MySQL Lists are EOL. Please join:

List:Internals« Previous MessageNext Message »
From:mark Date:April 13 2005 9:55pm
Subject:bk commit - mysqldoc tree (mmatthew:1.2858)
View as plain text  
Below is the list of changes that have just been committed into a local
mysqldoc repository of mmatthew. When mmatthew does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://www.mysql.com/doc/I/n/Installing_source_tree.html

ChangeSet
  1.2858 05/04/13 16:55:08 mmatthew@stripped +1 -0
  connector-j-en.xml:
    New structure, as well as changelog/properties for version 3.1.8.

  Docs/connector-j-en.xml
    1.33 05/04/13 16:54:45 mmatthew@stripped +2400 -2756
    New structure, as well as changelog/properties for version 3.1.8.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	mmatthew
# Host:	marks-box.i.thematthews.org
# Root:	/home/mmatthew/work/docs/mysqldoc

--- 1.32/Docs/connector-j-en.xml	2005-02-18 13:40:14 -06:00
+++ 1.33/Docs/connector-j-en.xml	2005-04-13 16:54:45 -05:00
@@ -40,624 +40,1046 @@
     </legalnotice>
   </bookinfo>
 
-  <chapter id="cj-intro">
-    <title>Introduction</title>
-
-    <para></para>
+  <chapter id="cj-developing-applications">
+    <title>Developing Applications with MySQL and Java using
+    Connector/J</title>
 
     <sect1 id="cj-what-is">
-      <title>What is MySQL Connector/J?</title>
+      <title>Introduction to JDBC Development</title>
 
-      <para>MySQL Connector/J is an implementation of Sun's JDBC 3.0 API for
-      the MySQL relational database server. It strives to conform as much as
-      possible to the JDBC API as specified by JavaSoft. It is known to work
-      with many third-party products, including:</para>
-
-      <itemizedlist>
-        <title>Application Servers</title>
-
-        <listitem>
-          <para><ulink url="http://jakarta.apache.org/">Apache
-          Tomcat</ulink></para>
-        </listitem>
-
-        <listitem>
-          <para><ulink url="http://www.jboss.org/">JBoss</ulink></para>
-        </listitem>
-
-        <listitem>
-          <para><ulink url="http://www.beasys.com/">Weblogic</ulink></para>
-        </listitem>
-
-        <listitem>
-          <para><ulink
-          url="http://www-3.ibm.com/software/info1/websphere/">IBM
-          WebSphere</ulink></para>
-        </listitem>
-      </itemizedlist>
-
-      <itemizedlist>
-        <title>Object Relational Mapping Tools</title>
-
-        <listitem>
-          <para><ulink
-          url="http://hibernate.sourceforge.net/">Hibernate</ulink></para>
-        </listitem>
-
-        <listitem>
-          <para><ulink url="http://db.apache.org/ojb/">Apache
-          ObjectRelationalBridge</ulink></para>
-        </listitem>
-
-        <listitem>
-          <para><ulink
-          url="http://www.thoughtinc.com/">CocoBase</ulink></para>
-        </listitem>
-
-        <listitem>
-          <para><ulink url="http://www.solarmetric.com/">Kodo</ulink></para>
-        </listitem>
-      </itemizedlist>
-
-      <itemizedlist>
-        <title>Development Environments</title>
-
-        <listitem>
-          <para><ulink url="http://www.eclipse.org/">Eclipse</ulink></para>
-        </listitem>
-
-        <listitem>
-          <para><ulink url="http://www.borland.com/jbuilder/">Borland
-          JBuilder</ulink></para>
-        </listitem>
-
-        <listitem>
-          <para><ulink
-          url="http://www-3.ibm.com/software/awdtools/studioappdev/">IBM
-          WebSphere Studio</ulink></para>
-        </listitem>
-      </itemizedlist>
-    </sect1>
+      <para>MySQL provides connectivity for client applications developed in
+      the Java programming language via a JDBC driver, which is called MySQL
+      Connector/J.</para>
+
+      <para>MySQL Connector/J is a JDBC-3.0 "Type 4" driver, which means that
+      is is pure Java, implements version 3.0 of the JDBC specification, and
+      communicates directly with the MySQL server using the MySQL
+      protocol.</para>
+
+      <para>This document is arranged for a beginning JDBC developer. If you
+      are already experienced with using JDBC, you might consider starting
+      with the section "<link linkend="cj-installing">Installing
+      Connector/J</link>".</para>
+
+      <para>While JDBC is useful by itself, we would hope that if you are not
+      familiar with JDBC that after reading the first few chapters of this
+      manual, that you would avoid using "naked" JDBC for all but the most
+      trivial problems and consider using one of the popular persistence
+      frameworks such as <ulink
+      url="http://www.hibernate.org/">Hibernate</ulink> , <ulink
+      url="http://www.springframework.org/">Spring's JDBC templates</ulink> or
+      <ulink url="http://www.ibatis.com/common/sqlmaps.html">Ibatis SQL
+      Maps</ulink> to do the majority of repetitive work and heavier lifting
+      that is sometimes required with JDBC.</para>
+
+      <para>This chapter is not designed to be a complete JDBC tutorial. If
+      you need more information about using JDBC you might be interested in
+      the following online tutorials that are more in-depth than the
+      information presented here:</para>
 
-    <sect1 id="cj-release-notes">
-      <title>Release Notes</title>
+      <para><itemizedlist>
+          <listitem>
+            <para><ulink
+            url="http://java.sun.com/docs/books/tutorial/jdbc/basics/index.html">JDBC
+            Basics </ulink>- A tutorial from Sun covering beginner topics in
+            JDBC</para>
+          </listitem>
 
-      <para></para>
+          <listitem>
+            <para><ulink
+            url="http://java.sun.com/developer/onlineTraining/Database/JDBCShortCourse/index.html">JDBC
+            Short Course</ulink> - A more in-depth tutorial from Sun and
+            JGuru</para>
+          </listitem>
+        </itemizedlist></para>
 
-      <sect2>
-        <title>Upgrading</title>
+      <sect2 id="cj-basic-jdbc">
+        <title>Basic JDBC concepts</title>
 
-        <para>MySQL AB tries to keep the upgrade process as easy as possible,
-        however as is the case with any software, sometimes changes need to be
-        made in new versions to support new features, improve existing
-        functionality, or comply with new standards.</para>
+        <para></para>
 
-        <para>This section has information about what users who are upgrading
-        from one version of Connector/J to another (or to a new version of the
-        MySQL server, with respect to JDBC functionality) should be aware
-        of.</para>
+        <sect3 id="cj-connect-with-drivermanager">
+          <title>Connecting to MySQL using the DriverManager Interface</title>
 
-        <sect3 id="cj-upgrading-3-0-to-3-1">
-          <title>Upgrading from MySQL Connector/J 3.0 to 3.1</title>
+          <para>When you are using JDBC outside of an application server, the
+          DriverManager class manages the establishment of Connections.</para>
 
-          <para>Connector/J 3.1 is designed to be backwards-compatible with
-          Connector/J 3.0 as much as possible. Major changes are isolated to
-          new functionality exposed in MySQL-4.1 and newer, which includes
-          Unicode character sets, server-side prepared statements, SQLState
-          codes returned in error messages by the server and various
-          performance enhancements that can be enabled or disabled via
-          configuration properties.</para>
+          <para>The DriverManager needs to be told which JDBC drivers it
+          should try to make Connections with. The easiest way to do this is
+          to use Class.forName() on the class that implements the
+          java.sql.Driver interface. With MySQL Connector/J, the name of this
+          class is com.mysql.jdbc.Driver. With this method, you could use an
+          external configuration file to supply the driver class name and
+          driver parameters to use when connecting to a database.</para>
 
-          <itemizedlist>
-            <listitem>
-              <para>Unicode Character Sets - See the next section, as well as
-              the "Character Sets" section in the server manual for
-              information on this new feature of MySQL. If you have something
-              misconfigured, it will usually show up as an error with a
-              message similar to 'Illegal mix of collations'.</para>
-            </listitem>
+          <para>The following section of Java code shows how you might
+          register MySQL Connector/J from the main() method of your
+          application:<programlisting>import java.sql.Connection; 
+import java.sql.DriverManager; 
+import java.sql.SQLException; 
 
-            <listitem>
-              <para>Server-side prepared statements - The driver tries to
-              maintain transparency between the two implementations (emulated
-              and server-side). The only large divergence is with the
-              re-execution of PreparedStatement with LOB parameters, when a
-              parameter that was previously bound as a LOB has been re-bound
-              as a non-LOB type. For server-side prepared statements, this
-              requires all parameters to be re-bound before execution of the
-              statement. See the next section for further details.</para>
-            </listitem>
+// Notice, do not import com.mysql.jdbc.* 
+// or you will have problems! 
 
-            <listitem>
-              <para>New SQLState Codes - Connector/J 3.1 uses SQL:1999
-              SQLState codes returned by the MySQL server (if supported),
-              which are different than the "legacy" X/Open state codes that
-              Connector/J 3.0 uses. If connected to a MySQL server older than
-              MySQL-4.1.0 (the oldest version to return SQLStates as part of
-              the error code), the driver will use a built-in mapping. You can
-              revert to the old mapping by using the following configuration
-              property:</para>
+public class LoadDriver { 
+    public static void main(String[] args) { 
+        try { 
+            // The newInstance() call is a work around for some 
+            // broken Java implementations
 
-              <para><computeroutput>useSqlStateCodes=false</computeroutput></para>
-            </listitem>
+            Class.forName("com.mysql.jdbc.Driver").newInstance(); 
+        } catch (Exception ex) { 
+            // handle the error 
+        }
+}</programlisting></para>
 
-            <listitem>
-              <para>Datetimes with all-zero components ('0000-00-00 ...') -
-              These values can not be represented reliably in Java.
-              Connector/J 3.0.x always converted them to NULL when being read
-              from a ResultSet.</para>
+          <para>After the driver has been registered with the DriverManager,
+          you can obtain a Connection instance that is connected to a
+          particular database by calling DriverManager.getConnection():</para>
+
+          <example>
+            <title>Obtaining a Connection From the DriverManager</title>
+
+            <para>This example shows how you can obtain a Connection instance
+            from the DriverManager. There are a few different signatures for
+            the getConnection() method. You should see the API documentation
+            that comes with your JDK for more specific information on how to
+            use them. <programlisting>
+import java.sql.Connection;
+import java.sql.DriverManager; 
+import java.sql.SQLException; 
 
-              <para>Connector/J 3.1 throws an exception by default when these
-              values are encountered as this is the most correct behavior
-              according to the JDBC and SQL standards. This behavior can be
-              modified using the '<property>zeroDateTimeBehavior</property>'
-              configuration property. The allowable values are: 'exception'
-              (the default), which throws a SQLException with a SQLState of
-              'S1009', 'convertToNull', which returns NULL instead of the
-              date, and 'round', which rounds the date to the nearest closest
-              value which is '0001-01-01'.</para>
+    ... try {
+            Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test?user=monty&amp;password=greatsqldb");
+          
+            // Do something with the Connection 
+          
+           .... 
+        } catch (SQLException ex) {
+            // handle any errors 
+            System.out.println("SQLException: " + ex.getMessage()); 
+            System.out.println("SQLState: " + ex.getSQLState()); 
+            System.out.println("VendorError: " + ex.getErrorCode()); 
+        }
+</programlisting></para>
 
-              <para>Starting with Connector/J 3.1.7, ResultSet.getString() can
-              be decoupled from this behavior via
-              '<property>noDatetimeStringSync=true</property>' (the default
-              value is 'false') so that you can get retrieve the unaltered
-              all-zero value as a String. It should be noted that this also
-              precludes using any timezone conversions, therefore the driver
-              will not allow you to enable
-              <property>noDatetimeStringSync</property> and
-              <property>useTimezone</property> at the same time.</para>
-            </listitem>
-          </itemizedlist>
+            <para>Once a Connection is established, it can be used to create
+            Statements and PreparedStatements, as well as retrieve metadata
+            about the database. This is explained in the following
+            sections.</para>
+          </example>
         </sect3>
 
-        <sect3 id="cj-jdbc-upgrading-issues">
-          <title>JDBC-Specific Issues When Upgrading to MySQL Server Version
-          4.1 or Newer</title>
+        <!--
+        <sect3 id="cj-connect-with-datasource">
+          <title>Connecting to MySQL using the DataSource Interface</title>
 
-          <para><itemizedlist>
-              <listitem>
-                <para><emphasis>Using the UTF-8 Character Encoding</emphasis>
-                - Prior to MySQL server version 4.1, the UTF-8 character
-                encoding was not supported by the server, however the JDBC
-                driver could use it, allowing storage of multiple character
-                sets in latin1 tables on the server.</para>
+          <para />
+        </sect3>
+-->
 
-                <para>Starting with MySQL-4.1, this functionality is
-                deprecated. If you have applications that rely on this
-                functionality, and can not upgrade them to use the official
-                Unicode character support in MySQL server version 4.1 or
-                newer, you should add the following property to your
-                connection URL:</para>
+        <!--
+        <sect3 id="cj-controlling-transactions">
+          <title>Controlling transactions</title>
 
-                <para><computeroutput>useOldUTF8Behavior=true</computeroutput></para>
-              </listitem>
+          <para />
+        </sect3>
+-->
 
-              <listitem>
-                <para><emphasis>Server-side Prepared Statements</emphasis> -
-                Connector/J 3.1 will automatically detect and use server-side
-                prepared statements when they are available (MySQL server
-                version 4.1.0 and newer).</para>
+        <sect3 id="cj-using-statements">
+          <title>Using Statements to Execute SQL</title>
 
-                <para>Starting with version 3.1.7, the driver scans SQL you
-                are preparing via all variants of
-                <methodname>Connection.prepareStatement()</methodname> to
-                determine if it is a supported type of statement to prepare on
-                the server side, and if it is not supported by the server, it
-                instead prepares it as a client-side emulated prepared
-                statement. You can disable this feature by passing
-                <property>'emulateUnsupportedPstmts=false'</property> in your
-                JDBC URL.</para>
-
-                <para>If your application encounters issues with server-side
-                prepared statements, you can revert to the older client-side
-                emulated prepared statement code that is still presently used
-                for MySQL servers older than 4.1.0 with the following
-                connection property:</para>
+          <para>Statements allow you to execute basic SQL queries and retrieve
+          the results through the ResultSet class which is described
+          later.</para>
+
+          <para>To create a Statement instance, you call the createStatement()
+          method on the Connection object you have retrieved via one of the
+          DriverManager.getConnection() or DataSource.getConnection() methods
+          described earlier.</para>
+
+          <para>Once you have a Statement instance, you can execute a SELECT
+          query by calling the executeQuery(String) method with the SQL you
+          want to use.</para>
+
+          <para>To update data in the database use the executeUpdate(String
+          SQL) method. This method returns the number of rows affected by the
+          update statement.</para>
+
+          <para>If you don't know ahead of time whether the SQL statement will
+          be a SELECT or an UPDATE/INSERT, then you can use the execute(String
+          SQL) method. This method will return true if the SQL query was a
+          SELECT, or false if an UPDATE/INSERT/DELETE query. If the query was
+          a SELECT query, you can retrieve the results by calling the
+          getResultSet() method. If the query was an UPDATE/INSERT/DELETE
+          query, you can retrieve the affected rows count by calling
+          getUpdateCount() on the Statement instance.</para>
 
-                <para><computeroutput>useServerPrepStmts=false</computeroutput></para>
-              </listitem>
-            </itemizedlist></para>
+          <example>
+            <title>Using java.sql.Statement to Execute a SELECT Query</title>
+
+            <programlisting>// assume conn is an already created JDBC connection
+Statement stmt = null; 
+ResultSet rs = null; 
+
+try {
+    stmt = conn.createStatement(); 
+    rs = stmt.executeQuery("SELECT foo FROM bar"); 
+
+    // or alternatively, if you don't know ahead of time that 
+    // the query will be a SELECT... 
+
+    if (stmt.execute("SELECT foo FROM bar")) { 
+        rs = stmt.getResultSet(); 
+    } 
+
+    // Now do something with the ResultSet .... 
+} finally { 
+    // it is a good idea to release
+    // resources in a finally{} block 
+    // in reverse-order of their creation 
+    // if they are no-longer needed 
+
+    if (rs != null) { 
+        try {
+            rs.close(); 
+        } catch (SQLException sqlEx) { // ignore } 
+
+        rs = null; 
+    }
+    
+    if (stmt != null) { 
+        try { 
+            stmt.close(); 
+        } catch (SQLException sqlEx) { // ignore } 
+
+        stmt = null; 
+    } 
+}</programlisting>
+          </example>
         </sect3>
-      </sect2>
 
-      <sect2 id="cj-known-issues">
-        <title>Known Issues</title>
+        <!--
+        <sect3 id="cj-using-prepared-statements">
+          <title>Using PreparedStatements to Execute SQL</title>
 
-        <para></para>
+          <para />
+        </sect3>
+-->
 
-        <sect3 id="cj-implementation-notes">
-          <title>Implementation Notes (By java.sql and javax.sql
-          Interface/Class)</title>
-
-          <para>MySQL Connector/J passes all of the tests in Sun's JDBC
-          compliance testsuite except for tests requiring stored procedures
-          (which MySQL does not have at this time). However, in many places
-          the JDBC specification is vague about how certain functionality
-          should be implemented, or the specification allows leeway in
-          implementation.</para>
-
-          <para>This section gives details on a interface-by-interface level
-          about how certain implementation decisions may affect how you use
-          MySQL Connector/J.</para>
+        <sect3 id="cj-using-callable-statements">
+          <title>Using CallableStatements to Execute Stored Procedures</title>
 
-          <itemizedlist>
-            <listitem>
-              <para>Blob</para>
+          <para>Starting with MySQL server version 5.0 when used with
+          Connector/J 3.1.1 or newer, the
+          <classname>java.sql.CallableStatement</classname> interface is fully
+          implemented with the exception of the
+          <function>getParameterMetaData()</function> method.</para>
+
+          <para>MySQL's stored procedure syntax is documented in the "<ulink
+          url="http://www.mysql.com/doc/en/Stored_Procedures.html">Stored
+          Procedures and Functions</ulink>" section of the MySQL Reference
+          Manual.</para>
+
+          <para>Connector/J exposes stored procedure functionality through
+          JDBC's <classname>CallableStatement</classname> interface.</para>
+
+          <para>The following example shows a stored procedure that returns
+          the value of <varname>inOutParam</varname> incremented by 1, and the
+          string passed in via <varname>inputParam</varname> as a
+          <classname>ResultSet</classname>:<example>
+              <title>Stored Procedure Example</title>
 
-              <para>The Blob implementation does not allow in-place
-              modification (they are 'copies', as reported by the
-              DatabaseMetaData.locatorsUpdateCopies() method). Because of
-              this, you should use the corresponding
-              PreparedStatement.setBlob() or ResultSet.updateBlob() (in the
-              case of updatable result sets) methods to save changes back to
-              the database.</para>
-
-              <para>Starting with Connector/J version 3.1.0, you can emulate
-              Blobs with locators by adding the property
-              'emulateLocators=true' to your JDBC URL. You must then use a
-              column alias with the value of the column set to the actual name
-              of the Blob column in the SELECT that you write to retrieve the
-              Blob. The SELECT must also reference only one table, the table
-              must have a primary key, and the SELECT must cover all columns
-              that make up the primary key. The driver will then delay loading
-              the actual Blob data until you retrieve the Blob and call
-              retrieval methods (getInputStream(), getBytes(), etc) on
-              it.</para>
-            </listitem>
+              <programlisting>CREATE PROCEDURE demoSp(IN inputParam VARCHAR(255), INOUT inOutParam INT)
+BEGIN
+    DECLARE z INT;
+    SET z = inOutParam + 1;
+    SET inOutParam = z;
 
-            <listitem>
-              <para>CallableStatement</para>
+    SELECT inputParam;
 
-              <para>Starting with Connector/J 3.1.1, stored procedures are
-              supported when connecting to MySQL version 5.0 or newer via the
-              <classname>CallableStatement</classname> interface. Currently,
-              the <function>getParameterMetaData()</function> method of
-              <classname>CallableStatement</classname> is not
-              supported.</para>
-            </listitem>
+    SELECT CONCAT('zyxw', inputParam);
+END</programlisting>
+            </example></para>
+
+          <para>To use the <function>demoSp</function> procedure with
+          Connector/J, follow these steps:</para>
 
+          <orderedlist>
             <listitem>
-              <para>Clob</para>
+              <para>Prepare the callable statement by using
+              <function>Connection.prepareCall()</function>.</para>
 
-              <para>The Clob implementation does not allow in-place
-              modification (they are 'copies', as reported by the
-              DatabaseMetaData.locatorsUpdateCopies() method). Because of
-              this, you should use the PreparedStatement.setClob() method to
-              save changes back to the database. The JDBC API does not have a
-              ResultSet.updateClob() method.</para>
-            </listitem>
+              <para>Notice that you have to use JDBC escape syntax, and that
+              the parentheses surrounding the parameter placeholders are not
+              optional:</para>
 
-            <listitem>
-              <para>Connection</para>
+              <example>
+                <title>Using Connection.prepareCall()</title>
 
-              <para>Unlike older versions of MM.MySQL the 'isClosed()' method
-              does not "ping" the server to determine if it is alive. In
-              accordance with the JDBC specification, it only returns true if
-              'closed()' has been called on the connection. If you need to
-              determine if the connection is still valid, you should issue a
-              simple query, such as "SELECT 1". The driver will throw an
-              exception if the connection is no longer valid.</para>
-            </listitem>
+                <programlisting>import java.sql.CallableStatement;
 
-            <listitem>
-              <para>DatabaseMetaData</para>
+...
 
-              <para>Foreign Key information (getImported/ExportedKeys() and
-              getCrossReference()) is only available from 'InnoDB'-type
-              tables. However, the driver uses 'SHOW CREATE TABLE' to retrieve
-              this information, so when other table types support foreign
-              keys, the driver will transparently support them as well.</para>
-            </listitem>
+    //
+    // Prepare a call to the stored procedure 'demoSp'
+    // with two parameters
+    //
+    // Notice the use of JDBC-escape syntax ({call ...})
+    //
 
-            <listitem>
-              <para>Driver</para>
-            </listitem>
+    CallableStatement cStmt = conn.prepareCall("{call demoSp(?, ?)}");
 
-            <listitem>
-              <para>PreparedStatement</para>
+    
+
+    cStmt.setString(1, "abcdefg");</programlisting>
+              </example>
 
-              <para>PreparedStatements are implemented by the driver, as MySQL
-              does not have a prepared statement feature. Because of this, the
-              driver does not implement getParameterMetaData() or
-              getMetaData() as it would require the driver to have a complete
-              SQL parser in the client.</para>
-
-              <para>Starting with version 3.1.0 MySQL Connector/J, server-side
-              prepared statements and 'binary-encoded' result sets are used
-              when the server supports them.</para>
-
-              <para>Take care when using a server-side prepared statement with
-              "large" parameters that are set via setBinaryStream(),
-              setAsciiStream(), setUnicodeStream(), setBlob(), or setClob().
-              If you want to re-execute the statement with any "large"
-              parameter changed to a non-"large" parameter, it is necessary to
-              call clearParameters() and set all parameters again. The reason
-              for this is as follows:</para>
-
-              <itemizedlist>
-                <listitem>
-                  <para>The driver streams the 'large' data 'out-of-band' to
-                  the prepared statement on the server side when the parameter
-                  is set (before execution of the prepared statement).</para>
-                </listitem>
-              </itemizedlist>
-
-              <itemizedlist>
-                <listitem>
-                  <para>Once that has been done, the stream used to read the
-                  data on the client side is closed (as per the JDBC spec),
-                  and can't be read from again.</para>
-                </listitem>
-              </itemizedlist>
-
-              <itemizedlist>
-                <listitem>
-                  <para>If a parameter changes from "large" to non-"large",
-                  the driver must reset the server-side state of the prepared
-                  statement to allow the parameter that is being changed to
-                  take the place of the prior "large" value. This removes all
-                  of the 'large' data that has already been sent to the
-                  server, thus requiring the data to be re-sent, via the
-                  setBinaryStream(), setAsciiStream(), setUnicodeStream(),
-                  setBlob() or setClob() methods.</para>
-                </listitem>
-              </itemizedlist>
-
-              <para>Consequently, if you want to change the "type" of a
-              parameter to a non-"large" one, you must call clearParameters()
-              and set all parameters of the prepared statement again before it
-              can be re-executed.</para>
+              <note>
+                <para><function>Connection.prepareCall()</function> is an
+                expensive method, due to the metadata retrieval that the
+                driver performs to support output parameters. For performance
+                reasons, you should try to minimize unnecessary calls to
+                <function>Connection.prepareCall()</function> by reusing
+                <classname>CallableStatement</classname> instances in your
+                code.</para>
+              </note>
             </listitem>
 
             <listitem>
-              <para>ResultSet</para>
+              <para>Register the output parameters (if any exist)</para>
 
-              <para>By default, ResultSets are completely retrieved and stored
-              in memory. In most cases this is the most efficient way to
-              operate, and due to the design of the MySQL network protocol is
-              easier to implement. If you are working with ResultSets that
-              have a large number of rows or large values, and can not
-              allocate heap space in your JVM for the memory required, you can
-              tell the driver to 'stream' the results back one row
-              at-a-time.</para>
+              <para>To retrieve the values of output parameters (parameters
+              specified as <literal>OUT</literal> or <literal>INOUT</literal>
+              when you created the stored procedure), JDBC requires that they
+              be specified before statement execution using the various
+              <function>registerOutputParameter()</function> methods in the
+              <classname>CallableStatement</classname> interface:<example>
+                  <title>Registering Output Parameters</title>
 
-              <para>To enable this functionality, you need to create a
-              Statement instance in the following manner: <programlisting>
-stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
-              java.sql.ResultSet.CONCUR_READ_ONLY);
-stmt.setFetchSize(Integer.MIN_VALUE);</programlisting>The combination of a
-              forward-only, read-only result set, with a fetch size of
-              Integer.MIN_VALUE serves as a signal to the driver to "stream"
-              result sets row-by-row. After this any result sets created with
-              the statement will be retrieved row-by-row.</para>
-
-              <para>There are some caveats with this approach. You will have
-              to read all of the rows in the result set (or close it) before
-              you can issue any other queries on the connection, or an
-              exception will be thrown. Also, any tables referenced by the
-              query that created the streaming result will be locked until all
-              of the results have been read or the connection closed.</para>
+                  <programlisting>import java.sql.Types;
+
+...
+    //
+    // Connector/J supports both named and indexed
+    // output parameters. You can register output
+    // parameters using either method, as well
+    // as retrieve output parameters using either
+    // method, regardless of what method was
+    // used to register them.
+    //
+    // The following examples show how to use
+    // the various methods of registering
+    // output parameters (you should of course
+    // use only one registration per parameter).
+    //
+
+    //
+    // Registers the second parameter as output
+    //
+
+    cStmt.registerOutParameter(2);
+
+    //
+    // Registers the second parameter as output, and 
+    // uses the type 'INTEGER' for values returned from 
+    // getObject()
+    //
+
+    cStmt.registerOutParameter(2, Types.INTEGER);
+
+    //
+    // Registers the named parameter 'inOutParam'
+    //
+
+    cStmt.registerOutParameter("inOutParam");
+
+    //
+    // Registers the named parameter 'inOutParam', and 
+    // uses the type 'INTEGER' for values returned from 
+    // getObject()
+    //
+
+    cStmt.registerOutParameter("inOutParam", Types.INTEGER);
+
+...</programlisting>
+                </example></para>
             </listitem>
 
             <listitem>
-              <para>ResultSetMetaData</para>
+              <para>Set the input parameters (if any exist)</para>
+
+              <para>Input and in/out parameters are set as for
+              <classname>PreparedStatement</classname> objects. However,
+              <classname>CallableStatement</classname> also supports setting
+              parameters by name:<example>
+                  <title>Setting CallableStatement Input Parameters</title>
+
+                  <programlisting>...
+
+    //
+    // Set a parameter by index
+    //
+
+    cStmt.setString(1, "abcdefg");
+    
+    //
+    // Alternatively, set a parameter using
+    // the parameter name
+    //
+
+    cStmt.setString("inputParameter", "abcdefg");
+
+    //
+    // Set the 'in/out' parameter using an index
+    //
+
+    cStmt.setInt(2, 1);
 
-              <para>The 'isAutoIncrement()' method only works when using MySQL
-              servers 4.0 and newer.</para>
+    //
+    // Alternatively, set the 'in/out' parameter
+    // by name
+    //
+
+    cStmt.setInt("inOutParam", 1);
+
+...</programlisting>
+                </example></para>
             </listitem>
 
             <listitem>
-              <para>Statement</para>
+              <para>Execute the <classname>CallableStatement</classname>, and
+              retrieve any result sets or output parameters.</para>
+
+              <para>While <classname>CallableStatement</classname> supports
+              calling any of the <classname>Statement</classname> execute
+              methods (<function>executeUpdate()</function>,
+              <function>executeQuery()</function> or
+              <function>execute()</function>), the most flexible method to
+              call is <function>execute()</function>, as you do not need to
+              know ahead of time if the stored procedure returns result
+              sets:<example>
+                  <title>Retrieving Results and Output Parameter
+                  Values</title>
+
+                  <programlisting>...
+
+    boolean hadResults = cStmt.execute();
+
+    // 
+    // Process all returned result sets
+    //
+
+    while (hadResults) {
+        ResultSet rs = cStmt.getResultSet();
+
+        // process result set
+        ...
+
+        hadResults = cStmt.getMoreResults();
+    }
+
+    // 
+    // Retrieve output parameters
+    //
+    // Connector/J supports both index-based and
+    // name-based retrieval
+    //
+
+    int outputValue = cStmt.getInt(1); // index-based
+
+    outputValue = cStmt.getInt("inOutParam"); // name-based
+
+...</programlisting>
+                </example></para>
             </listitem>
-          </itemizedlist>
+          </orderedlist>
         </sect3>
+      </sect2>
 
-        <sect3 id="cj-unimplemented-features">
-          <title>Un-implemented Functionality</title>
+      <sect2 id="cj-advanced-concepts">
+        <title>Advanced JDBC Concepts</title>
 
-          <para>The following methods in the JDBC API have not been
-          implemented yet. They rely on functionality that at this time is not
-          present in the MySQL server:</para>
+        <para></para>
 
-          <itemizedlist>
-            <listitem>
-              <para>Blob.truncate()</para>
-            </listitem>
-          </itemizedlist>
+        <sect3 id="cj-retrieve-autoinc">
+          <title>Retrieving AUTO_INCREMENT Column Values</title>
 
-          <itemizedlist>
-            <listitem>
-              <para>Connection.setSavePoint() is not supported in versions
-              earlier than 3.1.1</para>
-            </listitem>
+          <para>Before version 3.0 of the JDBC API, there was no standard way
+          of retrieving key values from databases that supported 'auto
+          increment' or identity columns. With older JDBC drivers for MySQL,
+          you could always use a MySQL- specific method on the Statement
+          interface, or issue the query 'SELECT LAST_INSERT_ID()' after
+          issuing an 'INSERT' to a table that had an AUTO_INCREMENT key. Using
+          the MySQL-specific method call isn't portable, and issuing a
+          'SELECT' to get the AUTO_INCREMENT key's value requires another
+          round- trip to the database, which isn't as efficient as possible.
+          The following code snippets demonstrate the three different ways to
+          retrieve AUTO_INCREMENT values. First, we demonstrate the use of the
+          new JDBC-3.0 method 'getGeneratedKeys()' which is now the preferred
+          method to use if you need to retrieve AUTO_INCREMENT keys and have
+          access to JDBC-3.0. The second example shows how you can retrieve
+          the same value using a standard 'SELECT LAST_INSERT_ID()' query. The
+          final example shows how updatable result sets can retrieve the
+          AUTO_INCREMENT value when using the method 'insertRow()'. <example>
+              <title>Retrieving AUTO_INCREMENT Column Values using
+              Statement.getGeneratedKeys()</title>
 
-            <listitem>
-              <para>Connection.prepareCall(String) is not supported in
-              versions earlier than 3.1.1</para>
-            </listitem>
+              <programlisting>   Statement stmt = null;
+   ResultSet rs = null;
 
-            <listitem>
-              <para>Connection.releaseSavepoint(Savepoint) is not supported in
-              versions earlier than 3.1.1</para>
-            </listitem>
+   try {
 
-            <listitem>
-              <para>Connection.rollback(Savepoint) is not supported in
-              versions earlier than 3.1.1</para>
-            </listitem>
-          </itemizedlist>
+    //
+    // Create a Statement instance that we can use for
+    // 'normal' result sets assuming you have a 
+    // Connection 'conn' to a MySQL database already 
+    // available
 
-          <itemizedlist>
-            <listitem>
-              <para>PreparedStatement.setArray(int, Array)</para>
-            </listitem>
+    stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
+                                java.sql.ResultSet.CONCUR_UPDATABLE);
 
-            <listitem>
-              <para>PreparedStatement.setRef()</para>
-            </listitem>
+    //
+    // Issue the DDL queries for the table for this example
+    //
 
-            <listitem>
-              <para>PreparedStatement.getParameterMetaData()</para>
-            </listitem>
-          </itemizedlist>
+    stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTutorial");
+    stmt.executeUpdate(
+            "CREATE TABLE autoIncTutorial ("
+            + "priKey INT NOT NULL AUTO_INCREMENT, "
+            + "dataField VARCHAR(64), PRIMARY KEY (priKey))");
+
+    //
+    // Insert one row that will generate an AUTO INCREMENT
+    // key in the 'priKey' field
+    //
+
+    stmt.executeUpdate(
+            "INSERT INTO autoIncTutorial (dataField) "
+            + "values ('Can I Get the Auto Increment Field?')",
+            Statement.RETURN_GENERATED_KEYS);
+
+    //
+    // Example of using Statement.getGeneratedKeys()
+    // to retrieve the value of an auto-increment
+    // value
+    //
+
+    int autoIncKeyFromApi = -1;
+
+    rs = stmt.getGeneratedKeys();
+
+    if (rs.next()) {
+        autoIncKeyFromApi = rs.getInt(1);
+    } else {
+
+        // throw an exception from here
+    }
+
+    rs.close();
+
+    rs = null;
+
+    System.out.println("Key returned from getGeneratedKeys():"
+        + autoIncKeyFromApi);
+} finally {
+
+    if (rs != null) {
+        try {
+            rs.close();
+        } catch (SQLException ex) {
+            // ignore
+        }
+    }
+
+    if (stmt != null) {
+        try {
+            stmt.close();
+        } catch (SQLException ex) {
+            // ignore
+        }
+    }
+}
+</programlisting>
+            </example><example>
+              <title>Retrieving AUTO_INCREMENT Column Values using 'SELECT
+              LAST_INSERT_ID()'</title>
+
+              <programlisting>   Statement stmt = null;
+   ResultSet rs = null;
+
+   try {
+
+    //
+    // Create a Statement instance that we can use for
+    // 'normal' result sets.
+
+    stmt = conn.createStatement();
+
+    //
+    // Issue the DDL queries for the table for this example
+    //
+
+    stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTutorial");
+    stmt.executeUpdate(
+            "CREATE TABLE autoIncTutorial ("
+            + "priKey INT NOT NULL AUTO_INCREMENT, "
+            + "dataField VARCHAR(64), PRIMARY KEY (priKey))");
+
+    //
+    // Insert one row that will generate an AUTO INCREMENT
+    // key in the 'priKey' field
+    //
+
+    stmt.executeUpdate(
+            "INSERT INTO autoIncTutorial (dataField) "
+            + "values ('Can I Get the Auto Increment Field?')");
+
+    //
+    // Use the MySQL LAST_INSERT_ID()
+    // function to do the same thing as getGeneratedKeys()
+    //
+
+    int autoIncKeyFromFunc = -1;
+    rs = stmt.executeQuery("SELECT LAST_INSERT_ID()");
+
+    if (rs.next()) {
+        autoIncKeyFromFunc = rs.getInt(1);
+    } else {
+        // throw an exception from here
+    }
+
+    rs.close();
+    
+    System.out.println("Key returned from " + "'SELECT LAST_INSERT_ID()': "
+        + autoIncKeyFromFunc);
+
+} finally {
+
+    if (rs != null) {
+        try {
+            rs.close();
+        } catch (SQLException ex) {
+            // ignore
+        }
+    }
+
+    if (stmt != null) {
+        try {
+            stmt.close();
+        } catch (SQLException ex) {
+            // ignore
+        }
+    }
+}
+   </programlisting>
+            </example><example>
+              <title>Retrieving AUTO_INCREMENT Column Values in Updatable
+              ResultSets</title>
+
+              <programlisting>   Statement stmt = null;
+   ResultSet rs = null;
+
+   try {
+
+    //
+    // Create a Statement instance that we can use for
+    // 'normal' result sets as well as an 'updatable'
+    // one, assuming you have a Connection 'conn' to
+    // a MySQL database already available
+    // 
+
+    stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
+                                java.sql.ResultSet.CONCUR_UPDATABLE);
+
+    //
+    // Issue the DDL queries for the table for this example
+    //
+
+    stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTutorial");
+    stmt.executeUpdate(
+            "CREATE TABLE autoIncTutorial ("
+            + "priKey INT NOT NULL AUTO_INCREMENT, "
+            + "dataField VARCHAR(64), PRIMARY KEY (priKey))");
+
+    //
+    // Example of retrieving an AUTO INCREMENT key
+    // from an updatable result set
+    //
+
+    rs = stmt.executeQuery("SELECT priKey, dataField "
+       + "FROM autoIncTutorial");
+
+    rs.moveToInsertRow();
+
+    rs.updateString("dataField", "AUTO INCREMENT here?");
+    rs.insertRow();
+
+    //
+    // the driver adds rows at the end
+    //
+
+    rs.last();
+
+    //
+    // We should now be on the row we just inserted
+    //
+
+    int autoIncKeyFromRS = rs.getInt("priKey");
+
+    rs.close();
+
+    rs = null;
+   
+    System.out.println("Key returned for inserted row: "
+        + autoIncKeyFromRS);
+
+} finally {
+
+    if (rs != null) {
+        try {
+            rs.close();
+        } catch (SQLException ex) {
+            // ignore
+        }
+    }
+
+    if (stmt != null) {
+        try {
+            stmt.close();
+        } catch (SQLException ex) {
+            // ignore
+        }
+    }
+}
+
+
+   </programlisting>
+            </example> When you run the example code above, you should get the
+          following output: Key returned from getGeneratedKeys(): 1 Key
+          returned from 'SELECT LAST_INSERT_ID()': 1 Key returned for inserted
+          row: 2 You should be aware, that at times, it can be tricky to use
+          the 'SELECT LAST_INSERT_ID()' query, as that function's value is
+          scoped to a connection. So, if some other query happens on the same
+          connection, the value will be overwritten. On the other hand, the
+          'getGeneratedKeys()' method is scoped by the Statement instance, so
+          it can be used even if other queries happen on the same connection,
+          but not on the same Statement instance.</para>
+        </sect3>
+
+        <!--
+        <sect3 id="cj-retrieve-multiresults">
+          <title>Retrieving Multiple ResultSets from a Statement or
+          CallableStatement</title>
+
+          <para />
+        </sect3>
+-->
+
+        <!--
+        <sect3 id="cj-using-result-set-metadata">
+          <title>Using ResultSetMetaData to Retrieve Information about a
+          ResultSet</title>
+
+          <para />
+        </sect3>
+-->
+
+        <!--
+        <sect3 id="cj-using-database-metadata">
+          <title>Using DatabaseMetaData to Retrieve Information about a
+          Database</title>
+
+          <para />
+        </sect3>
+-->
+
+        <!--
+        <sect3 id="cj-working-with-lobs">
+          <title>Working with BLOBs and CLOBs</title>
+
+          <para />
+        </sect3>
+-->
+      </sect2>
+    </sect1>
+
+    <sect1 id="cj-installing">
+      <title>Installing Connector/J</title>
+
+      <para></para>
+
+      <sect2 id="cj-system-requirements">
+        <title>Required Software Versions</title>
+
+        <para></para>
+
+        <sect3 id="cj-supported-java-versions">
+          <title>Java Versions Supported</title>
+
+          <para>MySQL Connector/J supports Java-2 JVMs, including JDK-1.2.x,
+          JDK-1.3.x, JDK-1.4.x and JDK-1.5.x, and requires JDK-1.4.x or newer
+          to compile (but not run). MySQL Connector/J does not support
+          JDK-1.1.x or JDK-1.0.x</para>
+
+          <para>Because of the implementation of java.sql.Savepoint,
+          Connector/J 3.1.0 and newer will not run on JDKs older than 1.4
+          unless the class verifier is turned off (-Xverify:none), as the
+          class verifier will try to load the class definition for
+          java.sql.Savepoint even though it is not accessed by the driver
+          unless you actually use savepoint functionality.</para>
+        </sect3>
+
+        <sect3 id="cj-supported-mysql-versions">
+          <title>MySQL Server Version Guidelines</title>
+
+          <para>MySQL Connector/J supports all known MySQL server versions.
+          Some features (foreign keys, updatable result sets) require more
+          recent versions of MySQL to operate.</para>
+
+          <para>When connecting to MySQL server version 4.1 or newer, it is
+          best to use MySQL Connector/J version 3.1, as it has full support
+          for features in the newer versions of the server, including Unicode
+          characters, views, stored procedures and server-side prepared
+          statements.</para>
+
+          <para>While Connector/J version 3.0 will connect to MySQL server,
+          version 4.1 or newer, and implements Unicode characters and the new
+          authorization mechanism, Connector/J 3.0 will not be updated to
+          support new features in current and future server versions.</para>
+        </sect3>
+
+        <sect3 id="cj-classpath">
+          <title>Installing the Driver and Configuring the CLASSPATH</title>
+
+          <para>MySQL Connector/J is distributed as a .zip or .tar.gz archive
+          containing the sources, the class files and a class-file only
+          "binary" .jar archive named
+          "mysql-connector-java-[version]-bin.jar". You will need to use the
+          appropriate gui or command-line utility to un-archive the
+          distribution (for example, WinZip for the .zip archive, and "tar"
+          for the .tar.gz archive).</para>
+
+          <para>Once you have un-archived the distribution archive, you can
+          install the driver in one of two ways: Either copy the "com" and
+          "org" subdirectories and all of their contents to anywhere you like,
+          and put the directory holding the "com" and "org" subdirectories in
+          your classpath, or put mysql-connector-java-[version]-bin.jar in
+          your classpath, either by adding the FULL path to it to your
+          CLASSPATH enviornment variable, or by copying the directly
+          specifying it with the commandline switch -cp when starting your JVM
+          </para>
+
+          <para>If you are going to use the driver with the JDBC
+          DriverManager, you would use "com.mysql.jdbc.Driver" as the class
+          that implements java.sql.Driver.</para>
+
+          <example>
+            <title>Setting the CLASSPATH Under UNIX</title>
+
+            <para>The following command works for 'csh' under UNIX:</para>
+
+            <screen>$ setenv CLASSPATH /path/to/mysql-connector-java-[version]-bin.jar:$CLASSPATH</screen>
+          </example>
+
+          <para>The above command can be added to the appropriate startup file
+          for the login shell to make MySQL Connector/J available to all Java
+          applications.</para>
+
+          <para>If you want to use MySQL Connector/J with a servlet engine or
+          application server such as Tomcat or JBoss, you will have to read
+          your vendor's documentation for more information on how to configure
+          third-party class libraries, as most application servers ignore the
+          CLASSPATH environment variable. This document does contain
+          configuration examples for some J2EE application servers in the
+          section named "<link linkend="cj-j2ee">Using Connector/J with J2EE
+          and Other Java Frameworks</link>".</para>
+
+          <para>If you are developing servlets and/or JSPs, and your
+          application server is J2EE-compliant, you can put the driver's .jar
+          file in the WEB-INF/lib subdirectory of your webapp, as this is a
+          standard location for third party class libraries in J2EE web
+          applications.</para>
+
+          <para>You can also use the MysqlDataSource or
+          MysqlConnectionPoolDataSource classes in the
+          com.mysql.jdbc.jdbc2.optional package, if your J2EE application
+          server supports or requires them. The various MysqlDataSource
+          classes support the following parameters (through standard "set"
+          mutators):</para>
 
           <itemizedlist>
             <listitem>
-              <para>ResultSet.getArray(int)</para>
+              <para>user</para>
             </listitem>
 
             <listitem>
-              <para>ResultSet.getArray(colName)</para>
+              <para>password</para>
             </listitem>
 
             <listitem>
-              <para>ResultSet.getRef(int)</para>
+              <para>serverName (see the previous section about fail-over
+              hosts)</para>
             </listitem>
 
             <listitem>
-              <para>ResultSet.getRef(String)</para>
+              <para>databaseName</para>
             </listitem>
 
             <listitem>
-              <para>ResultSet.rowDeleted()</para>
+              <para>port</para>
             </listitem>
+          </itemizedlist>
+        </sect3>
+      </sect2>
 
-            <listitem>
-              <para>ResultSet.rowInserted()</para>
-            </listitem>
+      <sect2 id="cj-upgrading">
+        <title>Upgrading from an Older Version</title>
 
-            <listitem>
-              <para>ResultSet.rowUpdated()</para>
-            </listitem>
+        <para>MySQL AB tries to keep the upgrade process as easy as possible,
+        however as is the case with any software, sometimes changes need to be
+        made in new versions to support new features, improve existing
+        functionality, or comply with new standards.</para>
 
+        <para>This section has information about what users who are upgrading
+        from one version of Connector/J to another (or to a new version of the
+        MySQL server, with respect to JDBC functionality) should be aware
+        of.</para>
+
+        <sect3 id="cj-upgrading-3-0-to-3-1">
+          <title>Upgrading from MySQL Connector/J 3.0 to 3.1</title>
+
+          <para>Connector/J 3.1 is designed to be backwards-compatible with
+          Connector/J 3.0 as much as possible. Major changes are isolated to
+          new functionality exposed in MySQL-4.1 and newer, which includes
+          Unicode character sets, server-side prepared statements, SQLState
+          codes returned in error messages by the server and various
+          performance enhancements that can be enabled or disabled via
+          configuration properties.</para>
+
+          <itemizedlist>
             <listitem>
-              <para>ResultSet.updateArray(int, Array)</para>
+              <para>Unicode Character Sets - See the next section, as well as
+              the "Character Sets" section in the server manual for
+              information on this new feature of MySQL. If you have something
+              misconfigured, it will usually show up as an error with a
+              message similar to 'Illegal mix of collations'.</para>
             </listitem>
 
             <listitem>
-              <para>ResultSet.updateArray(String, Array)</para>
+              <para><emphasis>Server-side Prepared Statements</emphasis> -
+              Connector/J 3.1 will automatically detect and use server-side
+              prepared statements when they are available (MySQL server
+              version 4.1.0 and newer).</para>
+
+              <para>Starting with version 3.1.7, the driver scans SQL you are
+              preparing via all variants of
+              <methodname>Connection.prepareStatement()</methodname> to
+              determine if it is a supported type of statement to prepare on
+              the server side, and if it is not supported by the server, it
+              instead prepares it as a client-side emulated prepared
+              statement. You can disable this feature by passing
+              <property>'emulateUnsupportedPstmts=false'</property> in your
+              JDBC URL.</para>
+
+              <para>If your application encounters issues with server-side
+              prepared statements, you can revert to the older client-side
+              emulated prepared statement code that is still presently used
+              for MySQL servers older than 4.1.0 with the following connection
+              property:</para>
+
+              <para><computeroutput>useServerPrepStmts=false</computeroutput></para>
             </listitem>
 
             <listitem>
-              <para>ResultSet.updateRef(int, Ref)</para>
+              <para>Datetimes with all-zero components ('0000-00-00 ...') -
+              These values can not be represented reliably in Java.
+              Connector/J 3.0.x always converted them to NULL when being read
+              from a ResultSet.</para>
+
+              <para>Connector/J 3.1 throws an exception by default when these
+              values are encountered as this is the most correct behavior
+              according to the JDBC and SQL standards. This behavior can be
+              modified using the '<property>zeroDateTimeBehavior</property>'
+              configuration property. The allowable values are: 'exception'
+              (the default), which throws a SQLException with a SQLState of
+              'S1009', 'convertToNull', which returns NULL instead of the
+              date, and 'round', which rounds the date to the nearest closest
+              value which is '0001-01-01'.</para>
+
+              <para>Starting with Connector/J 3.1.7, ResultSet.getString() can
+              be decoupled from this behavior via
+              '<property>noDatetimeStringSync=true</property>' (the default
+              value is 'false') so that you can get retrieve the unaltered
+              all-zero value as a String. It should be noted that this also
+              precludes using any timezone conversions, therefore the driver
+              will not allow you to enable
+              <property>noDatetimeStringSync</property> and
+              <property>useTimezone</property> at the same time.</para>
             </listitem>
 
             <listitem>
-              <para>ResultSet.updateRef(String, Ref)</para>
+              <para>New SQLState Codes - Connector/J 3.1 uses SQL:1999
+              SQLState codes returned by the MySQL server (if supported),
+              which are different than the "legacy" X/Open state codes that
+              Connector/J 3.0 uses. If connected to a MySQL server older than
+              MySQL-4.1.0 (the oldest version to return SQLStates as part of
+              the error code), the driver will use a built-in mapping. You can
+              revert to the old mapping by using the following configuration
+              property:</para>
+
+              <para><computeroutput>useSqlStateCodes=false</computeroutput></para>
             </listitem>
           </itemizedlist>
         </sect3>
-      </sect2>
-    </sect1>
-  </chapter>
 
-  <chapter id="cj-installation">
-    <title>Installation</title>
-
-    <para>This chapter contains instructions for installing the MySQL
-    Connector/J drivers on Microsoft Windows and UNIX platforms. If you are on
-    another platform that supports Java and the JDBC API then substitute
-    commands appropriate for your system.</para>
-
-    <sect1 id="cj-system-requirements">
-      <title>System Requirements</title>
-
-      <sect2 id="cj-supported-java-versions">
-        <title>Java Versions Supported</title>
-
-        <para>MySQL Connector/J supports Java-2 JVMs, including JDK-1.2.x,
-        JDK-1.3.x, JDK-1.4.x and JDK-1.5.x, and requires JDK-1.4.x or newer to
-        compile (but not run). MySQL Connector/J does not support JDK-1.1.x or
-        JDK-1.0.x</para>
-
-        <para>Because of the implementation of java.sql.Savepoint, Connector/J
-        3.1.0 and newer will not run on JDKs older than 1.4 unless the class
-        verifier is turned off (-Xverify:none), as the class verifier will try
-        to load the class definition for java.sql.Savepoint even though it is
-        not accessed by the driver unless you actually use savepoint
-        functionality.</para>
-      </sect2>
-
-      <sect2 id="cj-supported-mysql-versions">
-        <title>MySQL Server Versions Supported</title>
+        <sect3 id="cj-jdbc-upgrading-issues">
+          <title>JDBC-Specific Issues When Upgrading to MySQL Server Version
+          4.1 or Newer</title>
 
-        <para>MySQL Connector/J supports all known MySQL server versions. Some
-        features (foreign keys, updatable result sets) require more recent
-        versions of MySQL to operate.</para>
+          <para><itemizedlist>
+              <listitem>
+                <para><emphasis>Using the UTF-8 Character Encoding</emphasis>
+                - Prior to MySQL server version 4.1, the UTF-8 character
+                encoding was not supported by the server, however the JDBC
+                driver could use it, allowing storage of multiple character
+                sets in latin1 tables on the server.</para>
 
-        <para></para>
+                <para>Starting with MySQL-4.1, this functionality is
+                deprecated. If you have applications that rely on this
+                functionality, and can not upgrade them to use the official
+                Unicode character support in MySQL server version 4.1 or
+                newer, you should add the following property to your
+                connection URL:</para>
 
-        <sect3 id="cj-version-guidelines">
-          <title>Version Guidelines</title>
+                <para><computeroutput>useOldUTF8Behavior=true</computeroutput></para>
+              </listitem>
 
-          <para>When connecting to MySQL server version 4.1 or newer, it is
-          best to use MySQL Connector/J version 3.1, as it has full support
-          for features in the newer versions of the server, including Unicode
-          characters, views, stored procedures and server-side prepared
-          statements.</para>
+              <listitem>
+                <para><emphasis>Server-side Prepared Statements</emphasis> -
+                Connector/J 3.1 will automatically detect and use server-side
+                prepared statements when they are available (MySQL server
+                version 4.1.0 and newer). If your application encounters
+                issues with server-side prepared statements, you can revert to
+                the older client-side emulated prepared statement code that is
+                still presently used for MySQL servers older than 4.1.0 with
+                the following connection property:</para>
 
-          <para>While Connector/J version 3.0 will connect to MySQL server,
-          version 4.1 or newer, and implements Unicode characters and the new
-          authorization mechanism, Connector/J 3.0 will not be updated to
-          support new features in current and future server versions.</para>
+                <para><computeroutput>useServerPrepStmts=false</computeroutput></para>
+              </listitem>
+            </itemizedlist></para>
         </sect3>
       </sect2>
     </sect1>
 
-    <sect1 id="cj-installing">
-      <title>Installing MySQL Connector/J</title>
+    <sect1 id="cj-jdbc-reference">
+      <title>JDBC Reference</title>
 
-      <para>MySQL Connector/J is distributed as a .zip or .tar.gz archive
-      containing the sources, the class files and a class-file only "binary"
-      .jar archive named "mysql-connector-java-[version]-bin.jar". You will
-      need to use the appropriate gui or command-line utility to un-archive
-      the distribution (for example, WinZip for the .zip archive, and "tar"
-      for the .tar.gz archive).</para>
-
-      <sect2 id="cj-setting-classpath">
-        <title>Setting the CLASSPATH (For Standalone Use)</title>
-
-        <para>Once you have un-archived the distribution archive, you can
-        install the driver in one of two ways: Either copy the "com" and "org"
-        subdirectories and all of their contents to anywhere you like, and put
-        the directory holding the "com" and "org" subdirectories in your
-        classpath, or put mysql-connector-java-[version]-bin.jar in your
-        classpath, either by adding the FULL path to it to your CLASSPATH
-        enviornment variable, or by copying the .jar file to
-        $JAVA_HOME/jre/lib/ext. If you are going to use the driver with the
-        JDBC DriverManager, you would use "com.mysql.jdbc.Driver" as the class
-        that implements java.sql.Driver.</para>
-
-        <example>
-          <title>Setting the CLASSPATH Under UNIX</title>
-
-          <para>The following command works for 'csh' under UNIX:</para>
-
-          <screen>$ setenv CLASSPATH /path/to/mysql-connector-java-[version]-bin.jar:$CLASSPATH</screen>
-        </example>
-
-        <para>The above command can be added to the appropriate startup file
-        for the login shell to make MySQL Connector/J available to all Java
-        applications.</para>
-
-        <example>
-          <title>Setting the CLASSPATH Under Microsoft Windows 9X</title>
-
-          <para>The following is an example of setting the CLASSPATH under
-          Microsoft Windows 95, 98, ME:</para>
-
-          <screen>C:\&gt; set CLASSPATH=\path\to\mysql-connector-java-[version]-bin.jar;%CLASSPATH%</screen>
-        </example>
-
-        <para>This command can be added as the last line in AUTOEXEC.BAT. If
-        this is done the MySQL Connector/J driver will be made available to
-        all Java applications that run on the Windows 9x system. This setting
-        will require the computer to be rebooted before the changes will take
-        effect.</para>
-      </sect2>
+      <para></para>
 
-      <sect2 id="cj-driver-classname">
-        <title>Driver Class Name and JDBC URL Format</title>
+      <sect2 id="cj-configuration-properties">
+        <title>Driver/Datasource Class Names, URL Syntax and Configuration
+        Properties for Connector/J</title>
 
         <para>The name of the class that implements java.sql.Driver in MySQL
         Connector/J is 'com.mysql.jdbc.Driver'. The 'org.gjt.mm.mysql.Driver'
@@ -673,50 +1095,81 @@
         the port is not specified, it defaults to '3306', the default port
         number for MySQL servers.</para>
 
-        <para>Starting with version 3.0.12 and 3.1.2, Connector/J supports
-        multiple hosts with ports, separated by commas:</para>
-
         <screen>jdbc:mysql://[host:port],[host:port].../[database][?propertyName1][=propertyValue1][&amp;propertyName2][=propertyValue2]...</screen>
 
         <para>If the database is not specified, the connection will be made
         with no 'current' database. In this case, you will need to either call
-        the 'setCatalog()' method on the Connection instance, issue a 'USE
-        dbname' query or fully-specify table names using the database name
-        (i.e. 'SELECT dbname.tablename.colname FROM dbname.tablename...') in
-        your SQL. Not specifying the database to use upon connection is
-        generally only useful when building tools that work with multiple
-        databases, such as GUI database managers.</para>
+        the 'setCatalog()' method on the Connection instance or fully-specify
+        table names using the database name (i.e. 'SELECT
+        dbname.tablename.colname FROM dbname.tablename...') in your SQL. Not
+        specifying the database to use upon connection is generally only
+        useful when building tools that work with multiple databases, such as
+        GUI database managers.</para>
 
         <para>MySQL Connector/J has fail-over support. This allows the driver
         to fail-over to any number of "slave" hosts and still perform
         read-only queries. Fail-over only happens when the connection is in an
         autoCommit(true) state, because fail-over can not happen reliably when
-        a transaction is in progress. Most good application servers and
-        connection pools set autoCommit to 'true' at the end of every
-        transaction/connection use. The fail-over functionality has the
-        following behavior: If the URL property "autoReconnect" is false:
-        Failover only happens at connection initialization, and failback
-        occurs when the driver determines that the first host has become
-        available again If the URL property "autoReconnect" is true: Failover
-        happens when the driver determines that the connection has failed
-        (before <emphasis>every</emphasis> query), and falls back to the first
-        host when it determines that the host has become available again
-        (after queriesBeforeRetryMaster queries have been issued). In either
-        case, whenever you are connected to a "failed-over" server, the
-        connection will be set to read-only state, so queries that would
-        modify data will have exceptions thrown (the query will
+        a transaction is in progress. Most application servers and connection
+        pools set autoCommit to 'true' at the end of every
+        transaction/connection use.</para>
+
+        <para>The fail-over functionality has the following behavior:</para>
+
+        <para>If the URL property "autoReconnect" is false: Failover only
+        happens at connection initialization, and failback occurs when the
+        driver determines that the first host has become available
+        again.</para>
+
+        <para>If the URL property "autoReconnect" is true: Failover happens
+        when the driver determines that the connection has failed (before
+        <emphasis>every</emphasis> query), and falls back to the first host
+        when it determines that the host has become available again (after
+        queriesBeforeRetryMaster queries have been issued).</para>
+
+        <para>In either case, whenever you are connected to a "failed-over"
+        server, the connection will be set to read-only state, so queries that
+        would modify data will have exceptions thrown (the query will
         <emphasis>never</emphasis> be processed by the MySQL server).</para>
 
-        <para>You may specify additional properties to the JDBC driver, either
-        by placing them in a java.util.Properties instance and passing that
-        instance to the DriverManager when you connect, or by adding them to
-        the end of your JDBC URL as name-value pairs. The first property needs
-        to be preceeded with a '?' character, and additional name-value pair
-        properties are separated by an '&amp;' character. The properties,
-        their definitions and their default values are covered in the
-        following table:</para>
+        <para>Configuration properties define how Connector/J will make a
+        connection to a MySQL server. Unless otherwise noted, properties can
+        be set for a DataSource object or for a Connection object.</para>
 
-        <!-- The following table is auto-generated from the driver itself -->
+        <para>Configuration Properties can be set in one of the following
+        ways:<itemizedlist>
+            <listitem>
+              <para>Using the set*() methods on MySQL implementations of
+              java.sql.DataSource:<itemizedlist>
+                  <listitem>
+                    <para>com.mysql.jdbc.jdbc2.optional.MysqlDataSource</para>
+                  </listitem>
+
+                  <listitem>
+                    <para>com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource</para>
+                  </listitem>
+                </itemizedlist></para>
+            </listitem>
+
+            <listitem>
+              <para>As a key/value pair in the java.util.Properties instance
+              passed to DriverManager.getConnection() or
+              Driver.connect()</para>
+            </listitem>
+
+            <listitem>
+              <para>As a JDBC URL parameter in the URL given to
+              java.sql.DriverManager.getConnection(),
+              java.sql.Driver.connect() or the MySQL implementations of
+              javax.sql.DataSource's setURL() method.<note>
+                  <para>If the mechanism you use to configure a JDBC URL is
+                  XML-based, you will need to use the XML character literal
+                  &amp;amp; to separate configuration parameters, as the
+                  ampersand is a reserved character for XML.</para>
+                </note></para>
+            </listitem>
+          </itemizedlist>The properties are listed in the following
+        table:</para>
 
         <table>
           <title>Connection Properties</title>
@@ -984,6 +1437,21 @@
               </row>
 
               <row>
+                <entry>enableDeprecatedAutoreconnect</entry>
+
+                <entry>Auto-reconnect functionality is deprecated starting
+                with version 3.2, and will be removed in version 3.3. Set this
+                property to 'true' to disable the check for the feature being
+                configured.</entry>
+
+                <entry>No</entry>
+
+                <entry>false</entry>
+
+                <entry>3.2.1</entry>
+              </row>
+
+              <row>
                 <entry
                 spanname="cj_propstbl_span_all_cols"><emphasis>Security</emphasis></entry>
               </row>
@@ -1119,6 +1587,19 @@
               </row>
 
               <row>
+                <entry>blobSendChunkSize</entry>
+
+                <entry>Chunk to use when sending BLOB/CLOBs via
+                ServerPreparedStatements</entry>
+
+                <entry>No</entry>
+
+                <entry>1048576</entry>
+
+                <entry>3.2.1</entry>
+              </row>
+
+              <row>
                 <entry>cacheCallableStmts</entry>
 
                 <entry>Should the driver cache the parsing stage of
@@ -1232,6 +1713,20 @@
               </row>
 
               <row>
+                <entry>locatorFetchBufferSize</entry>
+
+                <entry>If 'emulateLocators' is configured to 'true', what size
+                buffer should be used when fetching BLOB data for
+                getBinaryInputStream?</entry>
+
+                <entry>No</entry>
+
+                <entry>1048576</entry>
+
+                <entry>3.2.1</entry>
+              </row>
+
+              <row>
                 <entry>useFastIntParsing</entry>
 
                 <entry>Use internal String-&gt;Integer conversion routines to
@@ -1516,6 +2011,20 @@
               </row>
 
               <row>
+                <entry>sessionVariables</entry>
+
+                <entry>A comma-separated list of name/value pairs to be sent
+                as SET SESSION ... to the server when the driver
+                connects.</entry>
+
+                <entry>No</entry>
+
+                <entry></entry>
+
+                <entry>3.1.8</entry>
+              </row>
+
+              <row>
                 <entry>allowNanAndInf</entry>
 
                 <entry>Should the driver allow NaN or +/- INF values in
@@ -1559,7 +2068,7 @@
                 <entry>clobberStreamingResults</entry>
 
                 <entry>This will cause a 'streaming' ResultSet to be
-                automatically closed, and any oustanding data still streaming
+                automatically closed, and any outstanding data still streaming
                 from the server to be discarded if another query is executed
                 before all the data has been read from the server.</entry>
 
@@ -1585,6 +2094,19 @@
               </row>
 
               <row>
+                <entry>emptyStringsConvertToZero</entry>
+
+                <entry>Should the driver allow conversions from empty string
+                fields to numeric values of '0'?</entry>
+
+                <entry>No</entry>
+
+                <entry>true</entry>
+
+                <entry>3.1.8</entry>
+              </row>
+
+              <row>
                 <entry>emulateLocators</entry>
 
                 <entry>N/A</entry>
@@ -1932,300 +2454,477 @@
         <classname>com.mysql.jdbc.StandardSocketFactory</classname>.</para>
       </sect2>
 
-      <sect2 id="cj-installing-for-servlet-use">
-        <title>Installing MySQL Connector/J for Use With
-        Servlets/JSP/EJB</title>
-
-        <para>If you want to use MySQL Connector/J with a servlet engine or
-        application server such as Tomcat or JBoss, you will have to read your
-        vendor's documentation for more information on how to configure
-        third-party class libraries, as most application servers ignore the
-        CLASSPATH environment variable.</para>
-
-        <para>If you are developing servlets and/or JSPs, and your application
-        server is J2EE-compliant, you should put the driver's .jar file in the
-        WEB-INF/lib subdirectory of your webapp, as this is the standard
-        location for third party class libraries in J2EE web
-        applications.</para>
-
-        <para>You can also use the MysqlDataSource or
-        MysqlConnectionPoolDataSource classes in the
-        com.mysql.jdbc.jdbc2.optional package, if your J2EE application server
-        supports or requires them. The various MysqlDataSource classes support
-        the following parameters (through standard "set" mutators):</para>
+      <sect2 id="cj-implementation-notes">
+        <title>JDBC API Implementation Notes</title>
+
+        <para>MySQL Connector/J passes all of the tests in the
+        publicly-available version of Sun's JDBC compliance testsuite.
+        However, in many places the JDBC specification is vague about how
+        certain functionality should be implemented, or the specification
+        allows leeway in implementation.</para>
+
+        <para>This section gives details on a interface-by-interface level
+        about how certain implementation decisions may affect how you use
+        MySQL Connector/J.</para>
 
         <itemizedlist>
           <listitem>
-            <para>user</para>
+            <para>Blob</para>
+
+            <para>The Blob implementation does not allow in-place modification
+            (they are 'copies', as reported by the
+            DatabaseMetaData.locatorsUpdateCopies() method). Because of this,
+            you should use the corresponding PreparedStatement.setBlob() or
+            ResultSet.updateBlob() (in the case of updatable result sets)
+            methods to save changes back to the database.</para>
+
+            <para>Starting with Connector/J version 3.1.0, you can emulate
+            Blobs with locators by adding the property 'emulateLocators=true'
+            to your JDBC URL. You must then use a column alias with the value
+            of the column set to the actual name of the Blob column in the
+            SELECT that you write to retrieve the Blob. The SELECT must also
+            reference only one table, the table must have a primary key, and
+            the SELECT must cover all columns that make up the primary key.
+            The driver will then delay loading the actual Blob data until you
+            retrieve the Blob and call retrieval methods (getInputStream(),
+            getBytes(), etc) on it.</para>
+          </listitem>
+
+          <listitem>
+            <para>CallableStatement</para>
+
+            <para>Starting with Connector/J 3.1.1, stored procedures are
+            supported when connecting to MySQL version 5.0 or newer via the
+            <classname>CallableStatement</classname> interface. Currently, the
+            <function>getParameterMetaData()</function> method of
+            <classname>CallableStatement</classname> is not supported.</para>
+          </listitem>
+
+          <listitem>
+            <para>Clob</para>
+
+            <para>The Clob implementation does not allow in-place modification
+            (they are 'copies', as reported by the
+            DatabaseMetaData.locatorsUpdateCopies() method). Because of this,
+            you should use the PreparedStatement.setClob() method to save
+            changes back to the database. The JDBC API does not have a
+            ResultSet.updateClob() method.</para>
+          </listitem>
+
+          <listitem>
+            <para>Connection</para>
+
+            <para>Unlike older versions of MM.MySQL the 'isClosed()' method
+            does not "ping" the server to determine if it is alive. In
+            accordance with the JDBC specification, it only returns true if
+            'closed()' has been called on the connection. If you need to
+            determine if the connection is still valid, you should issue a
+            simple query, such as "SELECT 1". The driver will throw an
+            exception if the connection is no longer valid.</para>
+          </listitem>
+
+          <listitem>
+            <para>DatabaseMetaData</para>
+
+            <para>Foreign Key information (getImported/ExportedKeys() and
+            getCrossReference()) is only available from 'InnoDB'-type tables.
+            However, the driver uses 'SHOW CREATE TABLE' to retrieve this
+            information, so when other table types support foreign keys, the
+            driver will transparently support them as well.</para>
+          </listitem>
+
+          <listitem>
+            <para>Driver</para>
           </listitem>
 
           <listitem>
-            <para>password</para>
+            <para>PreparedStatement</para>
+
+            <para>PreparedStatements are implemented by the driver, as MySQL
+            does not have a prepared statement feature. Because of this, the
+            driver does not implement getParameterMetaData() or getMetaData()
+            as it would require the driver to have a complete SQL parser in
+            the client.</para>
+
+            <para>Starting with version 3.1.0 MySQL Connector/J, server-side
+            prepared statements and 'binary-encoded' result sets are used when
+            the server supports them.</para>
+
+            <para>Take care when using a server-side prepared statement with
+            "large" parameters that are set via setBinaryStream(),
+            setAsciiStream(), setUnicodeStream(), setBlob(), or setClob(). If
+            you want to re-execute the statement with any "large" parameter
+            changed to a non-"large" parameter, it is necessary to call
+            clearParameters() and set all parameters again. The reason for
+            this is as follows:</para>
+
+            <itemizedlist>
+              <listitem>
+                <para>The driver streams the 'large' data 'out-of-band' to the
+                prepared statement on the server side when the parameter is
+                set (before execution of the prepared statement).</para>
+              </listitem>
+            </itemizedlist>
+
+            <itemizedlist>
+              <listitem>
+                <para>Once that has been done, the stream used to read the
+                data on the client side is closed (as per the JDBC spec), and
+                can't be read from again.</para>
+              </listitem>
+            </itemizedlist>
+
+            <itemizedlist>
+              <listitem>
+                <para>If a parameter changes from "large" to non-"large", the
+                driver must reset the server-side state of the prepared
+                statement to allow the parameter that is being changed to take
+                the place of the prior "large" value. This removes all of the
+                'large' data that has already been sent to the server, thus
+                requiring the data to be re-sent, via the setBinaryStream(),
+                setAsciiStream(), setUnicodeStream(), setBlob() or setClob()
+                methods.</para>
+              </listitem>
+            </itemizedlist>
+
+            <para>Consequently, if you want to change the "type" of a
+            parameter to a non-"large" one, you must call clearParameters()
+            and set all parameters of the prepared statement again before it
+            can be re-executed.</para>
           </listitem>
 
           <listitem>
-            <para>serverName (see the previous section about fail-over
-            hosts)</para>
+            <para>ResultSet</para>
+
+            <para>By default, ResultSets are completely retrieved and stored
+            in memory. In most cases this is the most efficient way to
+            operate, and due to the design of the MySQL network protocol is
+            easier to implement. If you are working with ResultSets that have
+            a large number of rows or large values, and can not allocate heap
+            space in your JVM for the memory required, you can tell the driver
+            to 'stream' the results back one row at-a-time.</para>
+
+            <para>To enable this functionality, you need to create a Statement
+            instance in the following manner: <programlisting>
+stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
+              java.sql.ResultSet.CONCUR_READ_ONLY);
+stmt.setFetchSize(Integer.MIN_VALUE);</programlisting>The combination of a
+            forward-only, read-only result set, with a fetch size of
+            Integer.MIN_VALUE serves as a signal to the driver to "stream"
+            result sets row-by-row. After this any result sets created with
+            the statement will be retrieved row-by-row.</para>
+
+            <para>There are some caveats with this approach. You will have to
+            read all of the rows in the result set (or close it) before you
+            can issue any other queries on the connection, or an exception
+            will be thrown. Also, any tables referenced by the query that
+            created the streaming result will be locked until all of the
+            results have been read or the connection closed.</para>
           </listitem>
 
           <listitem>
-            <para>databaseName</para>
+            <para>ResultSetMetaData</para>
+
+            <para>The "isAutoIncrement()" method only works when using MySQL
+            servers 4.0 and newer.</para>
           </listitem>
 
           <listitem>
-            <para>port</para>
+            <para>Statement</para>
+
+            <para>The "setFetchSize()" method has no effect, other than to
+            toggle result set streaming as described above.</para>
+
+            <para></para>
+
+            <para>MySQL does not support SQL cursors, and the JDBC driver
+            doesn't emulate them, so "setCursorName()" has no effect.</para>
           </listitem>
         </itemizedlist>
       </sect2>
-    </sect1>
 
-    <sect1 id="cj-whats-next">
-      <title>What's Next?</title>
+      <sect2 id="cj-type-conversions">
+        <title>Java, JDBC and MySQL Types</title>
 
-      <para>Once the driver has been installed into your CLASSPATH or
-      application server, the driver is ready for use! Taking a look at the
-      next chapter containing programming information might be a good idea,
-      however.</para>
-    </sect1>
+        <para>MySQL Connector/J is flexible in the way it handles conversions
+        between MySQL data types and Java data types.</para>
 
-    <!---->
-  </chapter>
+        <para>In general, any MySQL data type can be converted to a
+        java.lang.String, and any numerical type can be converted to any of
+        the Java numerical types, although round-off, overflow, or loss of
+        precision may occur.</para>
+
+        <para>Starting with Connector/J 3.1.0, the JDBC driver will issue
+        warnings or throw DataTruncation exceptions as is required by the JDBC
+        specification unless the connection was configured not to do so by
+        using the property "jdbcCompliantTruncation" and setting it to
+        "false".</para>
 
-  <chapter id="cj-app-development">
-    <title>Developing Applications with MySQL Connector/J</title>
+        <para>The conversions that are always guaranteed to work are listed in
+        the following table:</para>
 
-    <para>...</para>
+        <table>
+          <title>Conversion Table</title>
 
-    <sect1 id="cj-basic-functionality">
-      <title>Basic Functionality</title>
+          <tgroup cols="2">
+            <thead>
+              <row>
+                <entry>These MySQL Data Types</entry>
 
-      <para></para>
+                <entry>Can always be converted to these Java types</entry>
+              </row>
+            </thead>
 
-      <!--
-      <sect2 id="cj-importing-java-sql-interfaces>
-        <title>Importing Interfaces From the java.sql Package</title>
+            <tbody>
+              <row>
+                <entry><type>CHAR, VARCHAR, BLOB, TEXT, ENUM, and
+                SET</type></entry>
 
-        <para></para>
-      </sect2>
--->
+                <entry><classname>java.lang.String, java.io.InputStream,
+                java.io.Reader, java.sql.Blob,
+                java.sql.Clob</classname></entry>
+              </row>
 
-      <sect2 id="cj-registering-with-driver-manager">
-        <title>Registering MySQL Connector/J With the JDBC
-        DriverManager</title>
-
-        <para>When you are using JDBC outside of an application server, the
-        DriverManager class manages the establishment of Connections.</para>
-
-        <para>The DriverManager needs to be told which JDBC drivers it should
-        try to make Connections with. The easiest way to do this is to use
-        Class.forName() on the class that implements the java.sql.Driver
-        interface. With MySQL Connector/J, the name of this class is
-        com.mysql.jdbc.Driver. With this method, you could use an external
-        configuration file to supply the driver class name and driver
-        parameters to use when connecting to a database.</para>
+              <row>
+                <entry><type>FLOAT, REAL, DOUBLE PRECISION, NUMERIC, DECIMAL,
+                TINYINT, SMALLINT, MEDIUMINT, INTEGER, BIGINT</type></entry>
 
-        <example>
-          <title>Registering the Driver With the DriverManager</title>
+                <entry><classname>java.lang.String, java.lang.Short,
+                java.lang.Integer, java.lang.Long, java.lang.Double,
+                java.math.BigDecimal</classname> <note>
+                    <para>round-off, overflow or loss of precision may occur
+                    if you choose a Java numeric data type that has less
+                    precision or capacity than the MySQL data type you are
+                    converting to/from.</para>
+                  </note></entry>
+              </row>
 
-          <para>The following section of Java code shows how you might
-          register MySQL Connector/J from the main() method of your
-          application.<programlisting>import java.sql.Connection; 
-import java.sql.DriverManager; 
-import java.sql.SQLException; 
+              <row>
+                <entry><type>DATE, TIME, DATETIME, TIMESTAMP</type></entry>
 
-// Notice, do not import com.mysql.jdbc.* 
-// or you will have problems! 
+                <entry><classname>java.lang.String, java.sql.Date,
+                java.sql.Timestamp</classname></entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </table>
 
-public class LoadDriver { 
-    public static void main(String[] args) { 
-        try { 
-            // The newInstance() call is a work around for some 
-            // broken Java implementations
+        <para>The <classname>ResultSet.getObject()</classname> method uses the
+        following type conversions between MySQL and Java types, following the
+        JDBC specification where appropriate:</para>
 
-            Class.forName("com.mysql.jdbc.Driver").newInstance(); 
-        } catch (Exception ex) { 
-            // handle the error 
-        }
-}</programlisting></para>
-        </example>
-      </sect2>
+        <para><table>
+            <title>MySQL Types to Java Types for ResultSet.getObject()</title>
 
-      <sect2 id="cj-opening-connection">
-        <title>Opening a Connection to MySQL</title>
+            <tgroup cols="2">
+              <thead>
+                <row>
+                  <entry>MySQL Type Name</entry>
 
-        <para>After the driver has been registered with the DriverManager, you
-        can obtain a Connection instance that is connected to a particular
-        database by calling DriverManager.getConnection():</para>
-
-        <example>
-          <title>Obtaining a Connection From the DriverManager</title>
-
-          <para>This example shows how you can obtain a Connection instance
-          from the DriverManager. There are a few different signatures for the
-          getConnection() method. You should see the API documentation that
-          comes with your JDK for more specific information on how to use
-          them. <programlisting>
-import java.sql.Connection;
-import java.sql.DriverManager; 
-import java.sql.SQLException; 
+                  <entry>Returned as Java Class</entry>
+                </row>
+              </thead>
 
-    ... try {
-            Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test?user=monty&amp;password=greatsqldb");
-          
-            // Do something with the Connection 
-          
-           .... 
-        } catch (SQLException ex) {
-            // handle any errors 
-            System.out.println("SQLException: " + ex.getMessage()); 
-            System.out.println("SQLState: " + ex.getSQLState()); 
-            System.out.println("VendorError: " + ex.getErrorCode()); 
-        }
-</programlisting></para>
-        </example>
+              <tbody>
+                <row>
+                  <entry><type>BIT(1)</type> (new in MySQL-5.0)</entry>
 
-        <para>Once a Connection is established, it can be used to create
-        Statements and PreparedStatements, as well as retrieve metadata about
-        the database. This is explained in the following sections.</para>
-      </sect2>
+                  <entry><classname>java.lang.Boolean</classname></entry>
+                </row>
 
-      <!--
-      <sect2 id="cj-exception-handling">
-        <title>Exception Handling</title>
+                <row>
+                  <entry><type>BIT( &gt; 1)</type> (new in MySQL-5.0)</entry>
 
-        <para></para>
-      </sect2>
-      -->
+                  <entry><classname>byte[]</classname></entry>
+                </row>
 
-      <sect2 id="cj-creating-statement-instance">
-        <title>Creating a Statement Instance</title>
+                <row>
+                  <entry><type>TINYINT</type></entry>
 
-        <para>Statements allow you to execute basic SQL queries and retrieve
-        the results through the ResultSet class which is described later. To
-        get a Statement object, you call the createStatement() method on the
-        Connection object you have retrieved via the
-        DriverManager.getConnection() method. Once you have a Statement
-        object, you can execute a SELECT query by calling the
-        executeQuery(String SQL) method with the SQL you want to use. To
-        update data in the database use the executeUpdate(String SQL) method.
-        This method returns the number of rows affected by the update
-        statement. If you don't know ahead of time whether the SQL statement
-        will be a SELECT or an UPDATE/INSERT, then you can use the
-        execute(String SQL) method. This method will return true if the SQL
-        query was a SELECT, or false if an UPDATE/INSERT/DELETE query. If the
-        query was a SELECT query, you can retrieve the results by calling the
-        getResultSet() method. If the query was an UPDATE/INSERT/DELETE query,
-        you can retrieve the affected rows count by calling getUpdateCount()
-        on the Statement instance.</para>
-      </sect2>
+                  <entry><classname>java.lang.Boolean</classname> if the
+                  configuration property "tinyInt1isBit" is set to "true" (the
+                  default) and the storage size is "1", or
+                  <classname>java.lang.Integer</classname> if not.</entry>
+                </row>
 
-      <sect2 id="cj-executing-select">
-        <title>Executing a SELECT Query</title>
+                <row>
+                  <entry><type>BOOL , BOOLEAN</type></entry>
 
-        <para></para>
+                  <entry>See <type>TINYINT</type>, above as these are aliases
+                  for <type>TINYINT(1)</type>, currently.</entry>
+                </row>
 
-        <example>
-          <title>Using java.sql.Statement to Execute a SELECT Query</title>
+                <row>
+                  <entry><type>SMALLINT[(M)] [UNSIGNED]</type></entry>
 
-          <para></para>
+                  <entry><classname>java.lang.Integer</classname> (regardless
+                  if UNSIGNED or not)</entry>
+                </row>
 
-          <programlisting>// assume conn is an already created JDBC connection
-Statement stmt = null; 
-ResultSet rs = null; 
+                <row>
+                  <entry><type>MEDIUMINT[(M)] [UNSIGNED]</type></entry>
 
-try {
-    stmt = conn.createStatement(); 
-    rs = stmt.executeQuery("SELECT foo FROM bar"); 
+                  <entry><classname>java.lang.Integer</classname> (regardless
+                  if UNSIGNED or not)</entry>
+                </row>
 
-    // or alternatively, if you don't know ahead of time that 
-    // the query will be a SELECT... 
+                <row>
+                  <entry><type>INT,INTEGER[(M)] [UNSIGNED]</type></entry>
 
-    if (stmt.execute("SELECT foo FROM bar")) { 
-        rs = stmt.getResultSet(); 
-    } 
+                  <entry><classname>java.lang.Integer</classname>, if UNSIGNED
+                  <classname>java.lang.Long</classname></entry>
+                </row>
 
-    // Now do something with the ResultSet .... 
-} finally { 
-    // it is a good idea to release
-    // resources in a finally{} block 
-    // in reverse-order of their creation 
-    // if they are no-longer needed 
+                <row>
+                  <entry><type>BIGINT[(M)] [UNSIGNED]</type></entry>
 
-    if (rs != null) { 
-        try {
-            rs.close(); 
-        } catch (SQLException sqlEx) { // ignore } 
+                  <entry><classname>java.lang.Long</classname>, if UNSIGNED
+                  <classname>java.math.BigInteger</classname></entry>
+                </row>
 
-        rs = null; 
-    }
-    
-    if (stmt != null) { 
-        try { 
-            stmt.close(); 
-        } catch (SQLException sqlEx) { // ignore } 
+                <row>
+                  <entry><type>FLOAT[(M,D)]</type></entry>
 
-        stmt = null; 
-    } 
-}</programlisting>
-        </example>
-      </sect2>
+                  <entry><classname>java.lang.Float</classname></entry>
+                </row>
 
-      <!--
-      <sect2 id="cj-navigating-result-set">
-        <title>Navigating a ResultSet</title>
+                <row>
+                  <entry><type>DOUBLE[(M,B)]</type></entry>
 
-        <para></para>
-      </sect2>
--->
+                  <entry><classname>java.lang.Double</classname></entry>
+                </row>
 
-      <!--
-      <sect2 id="cj-making-database-changes">
-        <title>Making Changes to the Database</title>
+                <row>
+                  <entry><type>DECIMAL[(M[,D])]</type></entry>
 
-        <para></para>
-      </sect2>
--->
+                  <entry><classname>java.math.BigDecimal</classname></entry>
+                </row>
 
-      <!--
-      <sect2 id="cj-using-prepared-statements">
-        <title>Using PreparedStatements</title>
+                <row>
+                  <entry><type>DATE</type></entry>
 
-        <para></para>
-      </sect2>
--->
+                  <entry><classname>java.sql.Date</classname></entry>
+                </row>
 
-      <!--
-      <sect2 id="cj-closing-objects">
-        <title>Closing the ResultSet, Statement and Connection Instances</title>
+                <row>
+                  <entry><type>DATETIME</type></entry>
 
-        <para></para>
-      </sect2>
--->
-    </sect1>
+                  <entry><classname>java.sql.Timestamp</classname></entry>
+                </row>
 
-    <!--
-    <sect1 id="cj-jdbc-2-0-functionality">
-      <title>JDBC-2.0 Functionality</title>
+                <row>
+                  <entry><type>TIMESTAMP[(M)]</type></entry>
 
-      <para></para>
-    </sect1>
--->
+                  <entry><classname>java.sql.Timestamp</classname></entry>
+                </row>
 
-    <!--
-    <sect1 id="cj-jdbc-3-0-functionality">
-      <title>JDBC-3.0 Functionality</title>
+                <row>
+                  <entry><type>TIME</type></entry>
 
-      <para></para>
-    </sect1>
--->
+                  <entry><classname>java.sql.Time</classname></entry>
+                </row>
 
-    <sect1 id="cj-advanced-functionality">
-      <title>Advanced Functionality</title>
+                <row>
+                  <entry><type>YEAR[(2|4)]</type></entry>
 
-      <para></para>
+                  <entry><classname>java.sql.Date</classname> (with the date
+                  set two January 1st, at midnight)</entry>
+                </row>
+
+                <row>
+                  <entry><type>CHAR(M)</type></entry>
+
+                  <entry><classname>java.lang.String</classname> (unless the
+                  character set for the column is <type>BINARY</type>, then
+                  <classname>byte[]</classname> is returned.</entry>
+                </row>
+
+                <row>
+                  <entry><type>VARCHAR(M) [BINARY]</type></entry>
+
+                  <entry><classname>java.lang.String</classname> (unless the
+                  character set for the column is <type>BINARY</type>, then
+                  <classname>byte[]</classname> is returned.</entry>
+                </row>
+
+                <row>
+                  <entry><type>BINARY(M)</type></entry>
+
+                  <entry><classname>byte[]</classname></entry>
+                </row>
+
+                <row>
+                  <entry><type>VARBINARY(M)</type></entry>
+
+                  <entry><classname>byte[]</classname></entry>
+                </row>
+
+                <row>
+                  <entry><type>TINYBLOB</type></entry>
+
+                  <entry><classname>byte[]</classname></entry>
+                </row>
+
+                <row>
+                  <entry><type>TINYTEXT</type></entry>
+
+                  <entry><classname>java.lang.String</classname></entry>
+                </row>
+
+                <row>
+                  <entry><type>BLOB</type></entry>
+
+                  <entry><classname>byte[]</classname></entry>
+                </row>
+
+                <row>
+                  <entry><type>TEXT</type></entry>
+
+                  <entry><classname>java.lang.String</classname></entry>
+                </row>
+
+                <row>
+                  <entry><type>MEDIUMBLOB</type></entry>
+
+                  <entry><classname>byte[]</classname></entry>
+                </row>
+
+                <row>
+                  <entry><type>MEDIUMTEXT</type></entry>
+
+                  <entry><classname>java.lang.String</classname></entry>
+                </row>
+
+                <row>
+                  <entry><type>LONGBLOB</type></entry>
+
+                  <entry><classname>byte[]</classname></entry>
+                </row>
+
+                <row>
+                  <entry><type>LONGTEXT</type></entry>
+
+                  <entry><classname>java.lang.String</classname></entry>
+                </row>
+
+                <row>
+                  <entry><type>ENUM('value1','value2',...)</type></entry>
+
+                  <entry><classname>java.lang.String</classname></entry>
+                </row>
+
+                <row>
+                  <entry><type>SET('value1','value2',...)</type></entry>
+
+                  <entry><classname>java.lang.String</classname></entry>
+                </row>
+              </tbody>
+            </tgroup>
+          </table></para>
+      </sect2>
 
       <sect2 id="cj-character-sets">
-        <title>Character Sets and Unicode</title>
+        <title>Using Character Sets and Unicode</title>
 
         <para>All strings sent from the JDBC driver to the server are
         converted automatically from native Java Unicode form to the client
@@ -2514,242 +3213,16 @@
         property.</para>
       </sect2>
 
-      <sect2 id="cj-stored-procedures">
-        <title>Stored Procedures</title>
-
-        <para>Starting with MySQL 5.0 and Connector/J 3.1.1, the
-        <classname>java.sql.CallableStatement</classname> interface is fully
-        implemented with the exception of the
-        <function>getParameterMetaData()</function> method.</para>
-
-        <para>MySQL's stored procedure syntax is documented in the "<ulink
-        url="http://www.mysql.com/doc/en/Stored_Procedures.html">Stored
-        Procedures and Functions</ulink>" section of the MySQL Reference
-        Manual.</para>
-
-        <para>Connector/J exposes stored procedure functionality through
-        JDBC's <classname>CallableStatement</classname> interface.</para>
-
-        <para>The following example shows a stored procedure that returns the
-        value of <varname>inOutParam</varname> incremented by 1, and the
-        string passed in via <varname>inputParam</varname> as a
-        <classname>ResultSet</classname>:<example>
-            <title>Stored Procedure Example</title>
-
-            <programlisting>CREATE PROCEDURE demoSp(IN inputParam VARCHAR(255), INOUT inOutParam INT)
-BEGIN
-    DECLARE z INT;
-    SET z = inOutParam + 1;
-    SET inOutParam = z;
-
-    SELECT inputParam;
-
-    SELECT CONCAT('zyxw', inputParam);
-END</programlisting>
-          </example></para>
-
-        <para>To use the <function>demoSp</function> procedure with
-        Connector/J, follow these steps:</para>
-
-        <orderedlist>
-          <listitem>
-            <para>Prepare the callable statement by using
-            <function>Connection.prepareCall()</function>.</para>
-
-            <para>Notice that you have to use JDBC escape syntax, and that the
-            parentheses surrounding the parameter placeholders are not
-            optional:</para>
-
-            <example>
-              <title>Using Connection.prepareCall()</title>
-
-              <programlisting>import java.sql.CallableStatement;
-
-...
-
-    //
-    // Prepare a call to the stored procedure 'demoSp'
-    // with two parameters
-    //
-    // Notice the use of JDBC-escape syntax ({call ...})
-    //
-
-    CallableStatement cStmt = conn.prepareCall("{call demoSp(?, ?)}");
-
-    
-
-    cStmt.setString(1, "abcdefg");</programlisting>
-            </example>
-
-            <note>
-              <para><function>Connection.prepareCall()</function> is an
-              expensive method, due to the metadata retrieval that the driver
-              performs to support output parameters. For performance reasons,
-              you should try to minimize unnecessary calls to
-              <function>Connection.prepareCall()</function> by reusing
-              <classname>CallableStatement</classname> instances in your
-              code.</para>
-            </note>
-          </listitem>
-
-          <listitem>
-            <para>Register the output parameters (if any exist)</para>
-
-            <para>To retrieve the values of output parameters (parameters
-            specified as <literal>OUT</literal> or <literal>INOUT</literal>
-            when you created the stored procedure), JDBC requires that they be
-            specified before statement execution using the various
-            <function>registerOutputParameter()</function> methods in the
-            <classname>CallableStatement</classname> interface:<example>
-                <title>Registering Output Parameters</title>
-
-                <programlisting>import java.sql.Types;
-
-...
-    //
-    // Connector/J supports both named and indexed
-    // output parameters. You can register output
-    // parameters using either method, as well
-    // as retrieve output parameters using either
-    // method, regardless of what method was
-    // used to register them.
-    //
-    // The following examples show how to use
-    // the various methods of registering
-    // output parameters (you should of course
-    // use only one registration per parameter).
-    //
-
-    //
-    // Registers the second parameter as output
-    //
-
-    cStmt.registerOutParameter(2);
-
-    //
-    // Registers the second parameter as output, and 
-    // uses the type 'INTEGER' for values returned from 
-    // getObject()
-    //
-
-    cStmt.registerOutParameter(2, Types.INTEGER);
-
-    //
-    // Registers the named parameter 'inOutParam'
-    //
-
-    cStmt.registerOutParameter("inOutParam");
-
-    //
-    // Registers the named parameter 'inOutParam', and 
-    // uses the type 'INTEGER' for values returned from 
-    // getObject()
-    //
-
-    cStmt.registerOutParameter("inOutParam", Types.INTEGER);
-
-...</programlisting>
-              </example></para>
-          </listitem>
-
-          <listitem>
-            <para>Set the input parameters (if any exist)</para>
-
-            <para>Input and in/out parameters are set as for
-            <classname>PreparedStatement</classname> objects. However,
-            <classname>CallableStatement</classname> also supports setting
-            parameters by name:<example>
-                <title>Setting CallableStatement Input Parameters</title>
-
-                <programlisting>...
-
-    //
-    // Set a parameter by index
-    //
-
-    cStmt.setString(1, "abcdefg");
-    
-    //
-    // Alternatively, set a parameter using
-    // the parameter name
-    //
-
-    cStmt.setString("inputParameter", "abcdefg");
-
-    //
-    // Set the 'in/out' parameter using an index
-    //
-
-    cStmt.setInt(2, 1);
-
-    //
-    // Alternatively, set the 'in/out' parameter
-    // by name
-    //
-
-    cStmt.setInt("inOutParam", 1);
-
-...</programlisting>
-              </example></para>
-          </listitem>
-
-          <listitem>
-            <para>Execute the <classname>CallableStatement</classname>, and
-            retrieve any result sets or output parameters.</para>
-
-            <para>While <classname>CallableStatement</classname> supports
-            calling any of the <classname>Statement</classname> execute
-            methods (<function>executeUpdate()</function>,
-            <function>executeQuery()</function> or
-            <function>execute()</function>), the most flexible method to call
-            is <function>execute()</function>, as you do not need to know
-            ahead of time if the stored procedure returns result sets:<example>
-                <title>Retrieving Results and Output Parameter Values</title>
-
-                <programlisting>...
-
-    boolean hadResults = cStmt.execute();
-
-    // 
-    // Process all returned result sets
-    //
-
-    while (hadResults) {
-        ResultSet rs = cStmt.getResultSet();
-
-        // process result set
-        ...
-
-        hadResults = cStmt.getMoreResults();
-    }
-
-    // 
-    // Retrieve output parameters
-    //
-    // Connector/J supports both index-based and
-    // name-based retrieval
-    //
-
-    int outputValue = cStmt.getInt(1); // index-based
-
-    outputValue = cStmt.getInt("inOutParam"); // name-based
-
-...</programlisting>
-              </example></para>
-          </listitem>
-        </orderedlist>
-      </sect2>
-
-      <!--
-      <sect2 id="cj-connection-pooling">
-        <title>DataSources and Connection Pooling</title>
+<!--
+      <sect2 id="cj-usage-advisor">
+        <title>Using the Usage Advisor</title>
 
         <para></para>
       </sect2>
-      -->
+-->
 
-      <sect2 id="cj-ssl-connection">
-        <title>Connecting over SSL</title>
+      <sect2 id="cj-using-ssl">
+        <title>Connecting Securely Using SSL</title>
 
         <para>SSL in MySQL Connector/J encrypts all data (other than the
         initial handshake) between the JDBC driver and the server. The
@@ -2897,282 +3370,670 @@
         connection to happen.</para>
       </sect2>
     </sect1>
-  </chapter>
 
-  <chapter id="cj-reporting-bugs">
-    <title>How to Report Bugs or Problems</title>
+    <sect1 id="cj-j2ee">
+      <title>Using Connector/J with J2EE and Other Java Frameworks</title>
 
-    <para>The normal place to report bugs is <ulink
-    url="http://bugs.mysql.com/">http://bugs.mysql.com/</ulink>, which is the
-    address for our bugs database. This database is public, and can be browsed
-    and searched by anyone. If you log in to the system, you will also be able
-    to enter new reports.</para>
-
-    <para>If you have found a sensitive security bug in MySQL, you can send
-    email to <ulink url="mailto:security@stripped">security@stripped</ulink>
-    Writing a good bug report takes patience, but doing it right the first
-    time saves time both for us and for yourself. A good bug report,
-    containing a full test case for the bug, makes it very likely that we will
-    fix the bug in the next release. This section will help you write your
-    report correctly so that you don't waste your time doing things that may
-    not help us much or at all.</para>
-
-    <para>If you have a repeatable bug report, please report it to the bugs
-    database at <ulink url="???">http://bugs.mysql.com/</ulink>. Any bug that
-    we are able to repeat has a high chance of being fixed in the next MySQL
-    release. To report other problems, you can use one of the MySQL mailing
-    lists. Remember that it is possible for us to respond to a message
-    containing too much information, but not to one containing too little.
-    People often omit facts because they think they know the cause of a
-    problem and assume that some details don't matter. A good principle is
-    this: If you are in doubt about stating something, state it. It is faster
-    and less troublesome to write a couple more lines in your report than to
-    wait longer for the answer if we must ask you to provide information that
-    was missing from the initial report. The most common errors made in bug
-    reports are (a) not including the version number of Connector/J or MySQL
-    used, and (b) not fully describing the platform on which Connector/J is
-    installed (including the JVM version, and the platform type and version
-    number that MySQL itself is installed on). This is highly relevant
-    information, and in 99 cases out of 100, the bug report is useless without
-    it. Very often we get questions like, ``Why doesn't this work for me?''
-    Then we find that the feature requested wasn't implemented in that MySQL
-    version, or that a bug described in a report has already been fixed in
-    newer MySQL versions. Sometimes the error is platform-dependent; in such
-    cases, it is next to impossible for us to fix anything without knowing the
-    operating system and the version number of the platform.</para>
-
-    <para>If at all possible, you should create a repeatable, stanalone
-    testcase that doesn't involve any third-party classes.</para>
-
-    <para>To streamline this process, we ship a base class for testcases with
-    Connector/J, named
-    '<classname>com.mysql.jdbc.util.BaseBugReport</classname>'. To create a
-    testcase for Connector/J using this class, create your own class that
-    inherits from <classname>com.mysql.jdbc.util.BaseBugReport</classname> and
-    override the methods <methodname>setUp()</methodname>,
-    <methodname>tearDown()</methodname> and
-    <methodname>runTest</methodname>().</para>
-
-    <para>In the <methodname>setUp()</methodname> method, create code that
-    creates your tables, and populates them with any data needed to
-    demonstrate the bug.</para>
-
-    <para>In the <methodname>runTest</methodname>() method, create code that
-    demonstrates the bug using the tables and data you created in the 'setUp'
-    method.</para>
-
-    <para>In the <methodname>tearDown()</methodname> method, drop any tables
-    you created in the <methodname>setUp()</methodname> method.</para>
-
-    <para>In any of the above three methods, you should use one of the
-    variants of the <methodname>getConnection</methodname>() method to create
-    a JDBC connection to MySQL:</para>
-
-    <para><itemizedlist>
-        <listitem>
-          <para>getConnection() - Provides a connection to the JDBC URL
-          specified in getUrl(). If a connection already exists, that
-          connection is returned, otherwise a new connection is
-          created.</para>
-        </listitem>
-
-        <listitem>
-          <para>getNewConnection() - Use this if you need to get a new
-          connection for your bug report (i.e. there's more than one
-          connection involved).</para>
-        </listitem>
-
-        <listitem>
-          <para>getConnection(String url) - Returns a connection using the
-          given URL.</para>
-        </listitem>
-
-        <listitem>
-          <para>getConnection(String url, Properties props) - Returns a
-          connection using the given URL and properties.</para>
-        </listitem>
-      </itemizedlist>If you need to use a JDBC URL that is different than
-    'jdbc:mysql:///test', then override the method
-    <methodname>getUrl()</methodname> as well.</para>
-
-    <para>Use the <methodname>assertTrue(boolean expression)</methodname> and
-    <methodname>assertTrue(String failureMessage, boolean
-    expression)</methodname> methods to create conditions that must be met in
-    your testcase demonstrating the behavior you are expecting (vs. the
-    behavior you are observing, which is why you are most likely filing a bug
-    report).</para>
-
-    <para>Finally, create a <methodname>main</methodname>() method that
-    creates a new instance of your testcase, and calls the
-    <methodname>run</methodname> method: <programlisting>public static void main(String[] args) throws Exception {
-      new MyBugReport().run();
- }</programlisting> Once you have finished your testcase, and have verified
-    that it demonstrates the bug you are reporting, upload it with your bug
-    report to <ulink
-    url="http://bugs.mysql.com/">http://bugs.mysql.com/</ulink>.</para>
-  </chapter>
+      <para></para>
+
+      <sect2 id="cj-general-j2ee-concepts">
+        <title>General J2EE Concepts</title>
+
+        <para></para>
+
+        <sect3 id="cj-connection-pooling">
+          <title>Understanding Connection Pooling</title>
+
+          <para>Connection pooling is a technique of creating and managing a
+          pool of connections that are ready for use by any thread that needs
+          them.</para>
+
+          <para>This technique of "pooling" connections is based on the fact
+          that most applications only need a thread to have access to a JDBC
+          connection when they are actively processing a transaction, which
+          usually take only milliseconds to complete. When not processing a
+          transaction, the connection would otherwise sit idle. Instead,
+          connection pooling allows the idle connection to be used by some
+          other thread to do useful work.</para>
+
+          <para>In practice, when a thread needs to do work against a MySQL or
+          other database with JDBC, it requests a connection from the pool.
+          When the thread is finished using the connection, it returns it to
+          the pool, so that it may be used by any other threads that want to
+          use it.</para>
+
+          <para>When the connection is "loaned out" from the pool, it is used
+          exclusively by the thread that requested it. From a programming
+          point of view, it is the same as if your thread called
+          DriverManager.getConnection() every time it needed a JDBC
+          connection, however with connection pooling, your thread may end up
+          using either a new, or already-existing connection.</para>
+
+          <para>Connection pooling can greatly increase the performance of
+          your Java application, while reducing overall resource usage. The
+          main benefits to connection pooling are:</para>
 
-  <chapter id="cj-troubleshooting">
-    <title>Troubleshooting</title>
+          <itemizedlist>
+            <listitem>
+              <para>Reduced connection creation time</para>
+
+              <para>While this is not usually an issue with the quick
+              connection setup that MySQL offers compared to other databases,
+              creating new JDBC connections still incurs networking and JDBC
+              driver overhead that will be avoided if connections are
+              "recycled."</para>
+            </listitem>
+
+            <listitem>
+              <para>Simplified programming model</para>
+
+              <para>When using connection pooling, each individual thread can
+              act as though it has created its own JDBC connection, allowing
+              you to use straight-forward JDBC programming techniques.</para>
+            </listitem>
+
+            <listitem>
+              <para>Controlled resource usage</para>
 
-    <para>There are a few issues that seem to be commonly encountered often by
-    users of MySQL Connector/J. This section deals with their symptoms, and
-    their resolutions. If you have further issues, see the "SUPPORT"
-    section.</para>
-
-    <qandaset>
-      <qandaentry>
-        <question>
-          <para>When I try to connect to the database with MySQL Connector/J,
-          I get the following exception:</para>
+              <para>If you don't use connection pooling, and instead create a
+              new connection every time a thread needs one, your application's
+              resource usage can be quite wasteful and lead to unpredictable
+              behavior under load.</para>
+            </listitem>
+          </itemizedlist>
+
+          <para>Remember that each connection to MySQL has overhead (memory,
+          CPU, context switches, etc) on both the client and server side.
+          Every connection limits how many resources there are available to
+          your application as well as the MySQL server. Many of these
+          resources will be used whether or not the connection is actually
+          doing any useful work!</para>
+
+          <para>Connection pools can be tuned to maximize performance, while
+          keeping resource utilization below the point where your application
+          will start to fail rather than just run slower.</para>
+
+          <para>Luckily, Sun has standardized the concept of connection
+          pooling in JDBC through the JDBC-2.0 "Optional" interfaces, and all
+          major application servers have implementations of these APIs that
+          work fine with MySQL Connector/J.</para>
+
+          <para>Generally, you configure a connection pool in your application
+          server configuration files, and access it via the Java Naming and
+          Directory Interface (JNDI). The following code shows how you might
+          use a connection pool from an application deployed in a J2EE
+          application server:<example>
+              <title>Using a Connection Pool with a J2EE Application
+              Server</title>
+
+              <programlisting>import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import javax.naming.InitialContext;
+import javax.sql.DataSource;
+
+
+public class MyServletJspOrEjb {
+
+    public void doSomething() throws Exception {
+        /*
+         * Create a JNDI Initial context to be able to
+         *  lookup  the DataSource
+         *
+         * In production-level code, this should be cached as
+         * an instance or static variable, as it can
+         * be quite expensive to create a JNDI context.
+         *
+         * Note: This code only works when you are using servlets
+         * or EJBs in a J2EE application server. If you are
+         * using connection pooling in standalone Java code, you
+         * will have to create/configure datasources using whatever
+         * mechanisms your particular connection pooling library
+         * provides.
+         */
+
+        InitialContext ctx = new InitialContext();
+
+         /*
+          * Lookup the DataSource, which will be backed by a pool
+          * that the application server provides. DataSource instances
+          * are also a good candidate for caching as an instance
+          * variable, as JNDI lookups can be expensive as well.
+          */
+          
+        DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/MySQLDB");
 
-          <screen>SQLException: Server configuration denies access to data source 
+        /*
+         * The following code is what would actually be in your
+         * Servlet, JSP or EJB 'service' method...where you need
+         * to work with a JDBC connection.
+         */
+
+        Connection conn = null;
+        Statement stmt = null;
+
+        try {
+            conn = ds.getConnection();
+
+            /*
+             * Now, use normal JDBC programming to work with
+             * MySQL, making sure to close each resource when you're
+             * finished with it, which allows the connection pool
+             * resources to be recovered as quickly as possible
+             */
+
+            stmt = conn.createStatement();
+            stmt.execute("SOME SQL QUERY");
+
+            stmt.close();
+            stmt = null;
+
+            conn.close();
+            conn = null;
+        } finally {
+            /*
+             * close any jdbc instances here that weren't
+             * explicitly closed during normal code path, so
+             * that we don't 'leak' resources...
+             */
+
+            if (stmt != null) {
+                try {
+                    stmt.close();
+                } catch (sqlexception sqlex) {
+                    // ignore -- as we can't do anything about it here
+                }
+
+                stmt = null;
+            }
+
+            if (conn != null) {
+                try {
+                    conn.close();
+                } catch (sqlexception sqlex) {
+                    // ignore -- as we can't do anything about it here
+                }
+
+                conn = null;
+            }
+        }
+    }
+}</programlisting>
+            </example>As shown in the example above, after obtaining the JNDI
+          InitialContext, and looking up the DataSource, the rest of the code
+          should look familiar to anyone who has done JDBC programming in the
+          past.</para>
+
+          <para>The most important thing to remember when using connection
+          pooling is to make sure that no matter what happens in your code
+          (exceptions, flow-of-control, etc), connections, and anything
+          created by them (statements, result sets, etc) are closed, so that
+          they may be re-used, otherwise they will be "stranded," which in the
+          best case means that the MySQL server resources they represent
+          (buffers, locks, sockets, etc) may be tied up for some time, or
+          worst case, may be tied up forever.</para>
+
+          <para>What's the Best Size for my Connection Pool?</para>
+
+          <para>As with all other configuration rules-of-thumb, the answer is
+          "It depends." While the optimal size depends on anticipated load and
+          average database transaction time, the optimum connection pool size
+          is smaller than you might expect. If you take Sun's Java Petstore
+          blueprint application for example, a connection pool of 15-20
+          connections can serve a relatively moderate load (600 concurrent
+          users) using MySQL and Tomcat with response times that are
+          acceptable.</para>
+
+          <para>To correctly size a connection pool for your application, you
+          should create load test scripts with tools such as Apache JMeter or
+          The Grinder, and load test your application.</para>
+
+          <para>An easy way to determine a starting point is to configure your
+          connection pool's maximum number of connections to be "unbounded,"
+          run a load test, and measure the largest amount of concurrently used
+          connections. You can then work backwards from there to determine
+          what values of minimum and maximum pooled connections give the best
+          performance for your particular application.</para>
+        </sect3>
+
+        <!--
+        <sect3 id="cj-understanding-transactions">
+          <title>Understanding Transactions</title>
+
+          <para />
+        </sect3>
+-->
+      </sect2>
+
+      <sect2 id="cj-tomcat-config">
+        <title>Using Connector/J with Tomcat</title>
+
+        <para></para>
+
+        <para>The following instructions are based on the instructions for
+        Tomcat-5.x, available at <ulink
+        url="The following instructions are based on the instructions for Tomcat-5.x, available at http://jakarta.apache.org/tomcat/tomcat-5.0-doc/jndi-datasource-examples-howto.html which is current at the time this document was written.">http://jakarta.apache.org/tomcat/tomcat-5.0-doc/jndi-datasource-examples-howto.html</ulink>
+        which is current at the time this document was written.</para>
+
+        <para>First, install the .jar file that comes with Connector/J in
+        <filename>$CATALINA_HOME/common/lib</filename> so that it is available
+        to all applications installed in the container.</para>
+
+        <para>Next, Configure the JNDI DataSource by adding a declaration
+        resource to <filename>$CATALINA_HOME/conf/server.xml</filename> in the
+        context that defines your web application:</para>
+
+        <programlisting>&lt;Context ....&gt;
+
+  ...
+
+  &lt;Resource name="jdbc/MySQLDB"
+               auth="Container"
+               type="javax.sql.DataSource"/&gt;
+
+  &lt;!-- The name you used above, must match _exactly_ here! 
+
+       The connection pool will be bound into JNDI with the name
+       "java:/comp/env/jdbc/MySQLDB" 
+  --&gt;
+
+  &lt;ResourceParams name="jdbc/MySQLDB"&gt;
+    &lt;parameter&gt;
+      &lt;name&gt;factory&lt;/name&gt;
+      &lt;value&gt;org.apache.commons.dbcp.BasicDataSourceFactory&lt;/value&gt;
+    &lt;/parameter&gt;
+
+    &lt;!-- Don't set this any higher than max_connections on your
+         MySQL server, usually this should be a 10 or a few 10's 
+         of connections, not hundreds or thousands --&gt;
+
+    &lt;parameter&gt;
+      &lt;name&gt;maxActive&lt;/name&gt;
+      &lt;value&gt;10&lt;/value&gt;
+    &lt;/parameter&gt;
+
+    &lt;!-- You don't want to many idle connections hanging around
+         if you can avoid it, only enough to soak up a spike in
+         the load --&gt;
+
+    &lt;parameter&gt;
+      &lt;name&gt;maxIdle&lt;/name&gt;
+      &lt;value&gt;5&lt;/value&gt;
+    &lt;/parameter&gt;
+
+    &lt;!-- Don't use autoReconnect=true, it's going away eventually
+         and it's a crutch for older connection pools that couldn't
+         test connections. You need to decide if your application is
+         supposed to deal with SQLExceptions (hint, it should), and 
+         how much of a performance penalty you're willing to pay
+         to ensure 'freshness' of the connection --&gt;
+
+    &lt;parameter&gt;
+      &lt;name&gt;validationQuery&lt;/name&gt;
+      &lt;value&gt;SELECT 1&lt;/value&gt;
+    &lt;/parameter&gt;
+
+   &lt;!-- The most conservative approach is to test connections
+        before they're given to your application. For most applications 
+        this is okay, the query used above is very small and takes
+        no real server resources to process, other than the time used
+        to traverse the network.
+
+        If you have a high-load application you'll need to rely on 
+        something else. --&gt;
+
+    &lt;parameter&gt;
+      &lt;name&gt;testOnBorrow&lt;/name&gt;
+      &lt;value&gt;true&lt;/value&gt;
+    &lt;/parameter&gt;
+
+   &lt;!-- Otherwise, or in addition to testOnBorrow, you can test 
+        while connections are sitting idle --&gt;
+
+    &lt;parameter&gt;
+      &lt;name&gt;testWhileIdle&lt;/name&gt;
+      &lt;value&gt;true&lt;/value&gt;
+    &lt;/parameter&gt;
+
+    &lt;!-- You have to set this value, otherwise even though
+         you've asked connections to be tested while idle, 
+         the idle evicter thread will never run --&gt;
+
+    &lt;parameter&gt;
+      &lt;name&gt;timeBetweenEvictionRunsMillis&lt;/name&gt;
+      &lt;value&gt;10000&lt;/value&gt;
+    &lt;/parameter&gt;
+
+    &lt;!-- Don't allow connections to hang out idle too long, 
+         never longer than what wait_timeout is set to on the
+         server...A few minutes or even fraction of a minute
+         is sometimes okay here, it depends on your application
+         and how much spikey load it will see --&gt;
+
+    &lt;parameter&gt;
+      &lt;name&gt;minEvictableIdleTimeMillis&lt;/name&gt;
+      &lt;value&gt;60000&lt;/value&gt;
+    &lt;/parameter&gt;
+
+    &lt;!-- Username and password used when connecting to MySQL --&gt;
+
+    &lt;parameter&gt;
+     &lt;name&gt;username&lt;/name&gt;
+     &lt;value&gt;someuser&lt;/value&gt;
+    &lt;/parameter&gt;
+
+    &lt;parameter&gt;
+     &lt;name&gt;password&lt;/name&gt;
+     &lt;value&gt;somepass&lt;/value&gt;
+    &lt;/parameter&gt;
+    
+    &lt;!-- Class name for the Connector/J driver --&gt;
+
+    &lt;parameter&gt;
+       &lt;name&gt;driverClassName&lt;/name&gt;
+       &lt;value&gt;com.mysql.jdbc.Driver&lt;/value&gt;
+    &lt;/parameter&gt;
+    
+    &lt;!-- The JDBC connection url for connecting to MySQL, notice
+         that if you want to pass any other MySQL-specific parameters 
+         you should pass them here in the URL, setting them using the
+         parameter tags above will have no effect, you will also
+         need to use &amp;amp; to separate parameter values as the 
+         ampersand is a reserved character in XML --&gt;
+
+    &lt;parameter&gt;
+      &lt;name&gt;url&lt;/name&gt;
+      &lt;value&gt;jdbc:mysql://localhost:3306/test&lt;/value&gt;
+    &lt;/parameter&gt;
+
+  &lt;/ResourceParams&gt;
+&lt;/Context&gt;</programlisting>
+
+        <para>In general, you should follow the installation instructions that
+        come with your version of Tomcat, as the way you configure datasources
+        in Tomcat changes from time-to-time, and unfortunately if you use the
+        wrong syntax in your XML file, you will most likely end up with an
+        exception similar to the following:</para>
+
+        <programlisting>Error: java.sql.SQLException: Cannot load JDBC driver class 'null ' SQL
+state: null </programlisting>
+      </sect2>
+
+      <sect2 id="cj-jboss-config">
+        <title>Using Connector/J with JBoss</title>
+
+        <para></para>
+
+        <para>These instructions cover JBoss-4.x. To make the JDBC driver
+        classes available to the application server, copy the .jar file that
+        comes with Connector/J to the <filename>lib</filename> directory for
+        your server configuration (which is usually called
+        "<filename>default</filename>"). Then, in the same configuration
+        directory, in the subdirectory named "deploy", create a datasource
+        configuration file that ends with "-ds.xml", which tells JBoss to
+        deploy this file as a JDBC Datasource. The file should have the
+        following contents:</para>
+
+        <programlisting>&lt;datasources&gt; 
+    &lt;local-tx-datasource&gt; 
+        &lt;!-- This connection pool will be bound into JNDI with the name
+             "java:/MySQLDB" --&gt;
+
+        &lt;jndi-name&gt;MySQLDB&lt;/jndi-name&gt; 
+        &lt;connection-url&gt;jdbc:mysql://localhost:3306/dbname&lt;/connection-url&gt; 
+        &lt;driver-class&gt;com.mysql.jdbc.Driver&lt;/driver-class&gt; 
+        &lt;user-name&gt;user&lt;/user-name&gt; 
+        &lt;password&gt;pass&lt;/password&gt; 
+
+        &lt;min-pool-size&gt;5&lt;/min-pool-size&gt;
+
+        &lt;!-- Don't set this any higher than max_connections on your
+         MySQL server, usually this should be a 10 or a few 10's 
+         of connections, not hundreds or thousands --&gt;
+
+        &lt;max-pool-size&gt;20&lt;/max-pool-size&gt;
+
+        &lt;!-- Don't allow connections to hang out idle too long, 
+         never longer than what wait_timeout is set to on the
+         server...A few minutes is usually okay here, 
+         it depends on your application
+         and how much spikey load it will see --&gt;
+
+        &lt;idle-timeout-minutes&gt;5&lt;/idle-timeout-minutes&gt;
+
+        &lt;!-- If you're using Connector/J 3.1.8 or newer, you can use
+             our implementation of these to increase the robustness
+             of the connection pool. --&gt;
+
+        &lt;exception-sorter-class-name&gt;com.mysql.jdbc.integration.jboss.ExtendedMysqlExceptionSorter&lt;/exception-sorter-class-name&gt;
+        &lt;valid-connection-checker-class-name&gt;com.mysql.jdbc.integration.jboss.MysqlValidConnectionChecker&lt;/valid-connection-checker-class-name&gt;
+        
+    &lt;/local-tx-datasource&gt; 
+&lt;/datasources&gt; </programlisting>
+      </sect2>
+
+<!--
+      <sect2 id="cj-hibernate-config">
+        <title>Using Connector/J with Hibernate</title>
+
+        <para></para>
+      </sect2>
+-->
+
+      <!--
+      <sect2 id="cj-spring-config">
+        <title>Using Connector/J with Spring</title>
+
+        <para />
+      </sect2>
+-->
+
+      <!--
+      <sect2 id="cj-struts-config">
+        <title>Using Connector/J with Struts</title>
+
+        <para />
+      </sect2>
+
+-->
+
+      <!--
+      <sect2 id="cj-weblogic-config">
+        <title>Using Connector/J with BEA WebLogic</title>
+
+        <para />
+      </sect2>
+-->
+
+      <!--
+      <sect2 id="cj-websphere-config">
+        <title>Using Connector/J with IBM WebSphere</title>
+
+        <para />
+      </sect2>
+-->
+
+      <!--
+      <sect2 id="cj-ias-config">
+        <title>Using Connector/J with Oracle Application Server</title>
+
+        <para />
+      </sect2>
+-->
+    </sect1>
+
+    <sect1 id="cj-troubleshooting">
+      <title>Diagnosing Connector/J Problems</title>
+
+      <para></para>
+
+      <sect2 id="cj-faq">
+        <title>Common Problems and Solutions</title>
+
+        <para>There are a few issues that seem to be commonly encountered
+        often by users of MySQL Connector/J. This section deals with their
+        symptoms, and their resolutions. If you have further issues, see the
+        "SUPPORT" section.</para>
+
+        <qandaset>
+          <qandaentry>
+            <question>
+              <para>When I try to connect to the database with MySQL
+              Connector/J, I get the following exception:</para>
+
+              <screen>SQLException: Server configuration denies access to data source 
 SQLState: 08001 
 VendorError: 0</screen>
 
-          <para>What's going on? I can connect just fine with the MySQL
-          command-line client.</para>
-        </question>
-
-        <answer>
-          <para>MySQL Connector/J must use TCP/IP sockets to connect to MySQL,
-          as Java does not support Unix Domain Sockets. Therefore, when MySQL
-          Connector/J connects to MySQL, the security manager in MySQL server
-          will use its grant tables to determine whether or not the connection
-          should be allowed.</para>
-
-          <para>You must add grants to allow this to happen. The following is
-          an example of how to do this (but not the most secure).</para>
+              <para>What's going on? I can connect just fine with the MySQL
+              command-line client.</para>
+            </question>
+
+            <answer>
+              <para>MySQL Connector/J must use TCP/IP sockets to connect to
+              MySQL, as Java does not support Unix Domain Sockets. Therefore,
+              when MySQL Connector/J connects to MySQL, the security manager
+              in MySQL server will use its grant tables to determine whether
+              or not the connection should be allowed.</para>
+
+              <para>You must add grants to allow this to happen. The following
+              is an example of how to do this (but not the most
+              secure).</para>
 
-          <para>From the mysql command-line client, logged in as a user that
-          can grant privileges, issue the following command:</para>
+              <para>From the mysql command-line client, logged in as a user
+              that can grant privileges, issue the following command:</para>
 
-          <screen>GRANT ALL PRIVILEGES ON [dbname].* to
+              <screen>GRANT ALL PRIVILEGES ON [dbname].* to
                 '[user]'@'[hostname]' identified by
                 '[password]'</screen>
 
-          <para>replacing [dbname] with the name of your database, [user] with
-          the user name, [hostname] with the host that MySQL Connector/J will
-          be connecting from, and [password] with the password you want to
-          use. Be aware that RedHat Linux is broken with respect to the
-          hostname portion for the case when you are connecting from
-          localhost. You need to use "localhost.localdomain" for the
-          [hostname] value in this case. Follow this by issuing the "FLUSH
-          PRIVILEGES" command.</para>
-
-          <note>
-            <para>Testing your connectivity with the "mysql" command-line
-            client will not work unless you add the "--host" flag, and use
-            something other than "localhost" for the host. The "mysql"
-            command-line client will use Unix domain sockets if you use the
-            special hostname "localhost". If you are testing connectivity to
-            "localhost", use "127.0.0.1" as the hostname instead.</para>
-          </note>
-
-          <warning>
-            <para>If you don't understand what the 'GRANT' command does, or
-            how it works, you should read and understand the <ulink
-            url="http://www.mysql.com/doc/en/Privilege_system.html">'General
-            Security Issues and the MySQL Access Privilege System'</ulink>
-            section of the MySQL manual before attempting to change
-            privileges.</para>
-
-            <para>Changing privileges and permissions improperly in MySQL can
-            potentially cause your server installation to not have optimal
-            security properties.</para>
-          </warning>
-        </answer>
-      </qandaentry>
-
-      <qandaentry>
-        <question>
-          <para>My application throws a SQLException 'No Suitable Driver'. Why
-          is this happening?</para>
-        </question>
-
-        <answer>
-          <para>One of two things are happening. Either the driver is not in
-          your CLASSPATH (see the "INSTALLATION" section above), or your URL
-          format is incorrect (see "Developing Applications with MySQL
-          Connector/J").</para>
-        </answer>
-      </qandaentry>
-
-      <qandaentry>
-        <question>
-          <para>I'm trying to use MySQL Connector/J in an applet or
-          application and I get an exception similar to:</para>
+              <para>replacing [dbname] with the name of your database, [user]
+              with the user name, [hostname] with the host that MySQL
+              Connector/J will be connecting from, and [password] with the
+              password you want to use. Be aware that RedHat Linux is broken
+              with respect to the hostname portion for the case when you are
+              connecting from localhost. You need to use
+              "localhost.localdomain" for the [hostname] value in this case.
+              Follow this by issuing the "FLUSH PRIVILEGES" command.</para>
+
+              <note>
+                <para>Testing your connectivity with the "mysql" command-line
+                client will not work unless you add the "--host" flag, and use
+                something other than "localhost" for the host. The "mysql"
+                command-line client will use Unix domain sockets if you use
+                the special hostname "localhost". If you are testing
+                connectivity to "localhost", use "127.0.0.1" as the hostname
+                instead.</para>
+              </note>
+
+              <warning>
+                <para>If you don't understand what the 'GRANT' command does,
+                or how it works, you should read and understand the <ulink
+                url="http://www.mysql.com/doc/en/Privilege_system.html">'General
+                Security Issues and the MySQL Access Privilege System'</ulink>
+                section of the MySQL manual before attempting to change
+                privileges.</para>
+
+                <para>Changing privileges and permissions improperly in MySQL
+                can potentially cause your server installation to not have
+                optimal security properties.</para>
+              </warning>
+            </answer>
+          </qandaentry>
+
+          <qandaentry>
+            <question>
+              <para>My application throws a SQLException 'No Suitable Driver'.
+              Why is this happening?</para>
+            </question>
+
+            <answer>
+              <para>One of two things are happening. Either the driver is not
+              in your CLASSPATH (see the "INSTALLATION" section above), or
+              your URL format is incorrect (see "Developing Applications with
+              MySQL Connector/J").</para>
+            </answer>
+          </qandaentry>
+
+          <qandaentry>
+            <question>
+              <para>I'm trying to use MySQL Connector/J in an applet or
+              application and I get an exception similar to:</para>
 
-          <screen>SQLException: Cannot connect to MySQL server on host:3306. 
+              <screen>SQLException: Cannot connect to MySQL server on host:3306. 
 Is there a MySQL server running on the machine/port you 
 are trying to connect to?
 
 (java.security.AccessControlException) 
 SQLState: 08S01
 VendorError: 0 </screen>
-        </question>
+            </question>
 
-        <answer>
-          <para>Either you're running an Applet, your MySQL server has been
-          installed with the "--skip-networking" option set, or your MySQL
-          server has a firewall sitting in front of it.</para>
-
-          <para>Applets can only make network connections back to the machine
-          that runs the web server that served the .class files for the
-          applet. This means that MySQL must run on the same machine (or you
-          must have some sort of port re-direction) for this to work. This
-          also means that you will not be able to test applets from your local
-          file system, you must always deploy them to a web server.</para>
-
-          <para>MySQL Connector/J can only communicate with MySQL using
-          TCP/IP, as Java does not support Unix domain sockets. TCP/IP
-          communication with MySQL might be affected if MySQL was started with
-          the "--skip-networking" flag, or if it is firewalled.</para>
-
-          <para>If MySQL has been started with the "--skip-networking" option
-          set (the Debian Linux package of MySQL server does this for
-          example), you need to comment it out in the file /etc/mysql/my.cnf
-          or /etc/my.cnf. Of course your my.cnf file might also exist in the
-          "data" directory of your MySQL server, or anywhere else (depending
-          on how MySQL was compiled for your system). Binaries created by
-          MySQL AB always look in /etc/my.cnf and [datadir]/my.cnf. If your
-          MySQL server has been firewalled, you will need to have the firewall
-          configured to allow TCP/IP connections from the host where your Java
-          code is running to the MySQL server on the port that MySQL is
-          listening to (by default, 3306).</para>
-        </answer>
-      </qandaentry>
-
-      <qandaentry>
-        <question>
-          <para id="connector_j_wait_timeout_q_and_a">I have a
-          servlet/application that works fine for a day, and then stops
-          working overnight</para>
-        </question>
-
-        <answer>
-          <para>MySQL closes connections after 8 hours of inactivity. You
-          either need to use a connection pool that handles stale connections
-          or use the "autoReconnect" parameter (see "Developing Applications
-          with MySQL Connector/J").</para>
-
-          <para>Also, you should be catching SQLExceptions in your application
-          and dealing with them, rather than propagating them all the way
-          until your application exits, this is just good programming
-          practice. MySQL Connector/J will set the SQLState (see
-          java.sql.SQLException.getSQLState() in your APIDOCS) to "08S01" when
-          it encounters network-connectivity issues during the processing of a
-          query. Your application code should then attempt to re-connect to
-          MySQL at this point.</para>
-
-          <para>The following (simplistic) example shows what code that can
-          handle these exceptions might look like:</para>
-
-          <para><example>
-              <title id="connector_j_transaction_retry_example">Example of
-              transaction with retry logic</title>
+            <answer>
+              <para>Either you're running an Applet, your MySQL server has
+              been installed with the "--skip-networking" option set, or your
+              MySQL server has a firewall sitting in front of it.</para>
+
+              <para>Applets can only make network connections back to the
+              machine that runs the web server that served the .class files
+              for the applet. This means that MySQL must run on the same
+              machine (or you must have some sort of port re-direction) for
+              this to work. This also means that you will not be able to test
+              applets from your local file system, you must always deploy them
+              to a web server.</para>
+
+              <para>MySQL Connector/J can only communicate with MySQL using
+              TCP/IP, as Java does not support Unix domain sockets. TCP/IP
+              communication with MySQL might be affected if MySQL was started
+              with the "--skip-networking" flag, or if it is
+              firewalled.</para>
+
+              <para>If MySQL has been started with the "--skip-networking"
+              option set (the Debian Linux package of MySQL server does this
+              for example), you need to comment it out in the file
+              /etc/mysql/my.cnf or /etc/my.cnf. Of course your my.cnf file
+              might also exist in the "data" directory of your MySQL server,
+              or anywhere else (depending on how MySQL was compiled for your
+              system). Binaries created by MySQL AB always look in /etc/my.cnf
+              and [datadir]/my.cnf. If your MySQL server has been firewalled,
+              you will need to have the firewall configured to allow TCP/IP
+              connections from the host where your Java code is running to the
+              MySQL server on the port that MySQL is listening to (by default,
+              3306).</para>
+            </answer>
+          </qandaentry>
+
+          <qandaentry>
+            <question>
+              <para id="connector_j_wait_timeout_q_and_a">I have a
+              servlet/application that works fine for a day, and then stops
+              working overnight</para>
+            </question>
+
+            <answer>
+              <para>MySQL closes connections after 8 hours of inactivity. You
+              either need to use a connection pool that handles stale
+              connections or use the "autoReconnect" parameter (see
+              "Developing Applications with MySQL Connector/J").</para>
+
+              <para>Also, you should be catching SQLExceptions in your
+              application and dealing with them, rather than propagating them
+              all the way until your application exits, this is just good
+              programming practice. MySQL Connector/J will set the SQLState
+              (see java.sql.SQLException.getSQLState() in your APIDOCS) to
+              "08S01" when it encounters network-connectivity issues during
+              the processing of a query. Your application code should then
+              attempt to re-connect to MySQL at this point.</para>
+
+              <para>The following (simplistic) example shows what code that
+              can handle these exceptions might look like:</para>
+
+              <para><example>
+                  <title id="connector_j_transaction_retry_example">Example of
+                  transaction with retry logic</title>
 
-              <programlisting>public void doBusinessOp() throws SQLException {
+                  <programlisting>public void doBusinessOp() throws SQLException {
         Connection conn = null;
         Statement stmt = null;
         ResultSet rs = null;
@@ -3291,1528 +4152,291 @@
             }
         } while (!transactionCompleted &amp;&amp; (retryCount &gt; 0));
     }</programlisting>
-            </example></para>
-        </answer>
-      </qandaentry>
-
-      <qandaentry>
-        <question>
-          <para>I'm trying to use JDBC-2.0 updatable result sets, and I get an
-          exception saying my result set is not updatable.</para>
-        </question>
-
-        <answer>
-          <para>Because MySQL does not have row identifiers, MySQL Connector/J
-          can only update result sets that have come from queries on tables
-          that have at least one primary key, the query must select all of the
-          primary key(s) and the query can only span one table (i.e. no
-          joins). This is outlined in the JDBC specification.</para>
-        </answer>
-      </qandaentry>
-    </qandaset>
-  </chapter>
-
-  <appendix>
-    <title>Reference</title>
-
-    <para></para>
-
-    <sect1 id="connector-j-conversions">
-      <title id="connector-j-type-conversions">Type Conversions Supported by
-      MySQL Connector/J</title>
-
-      <para></para>
-
-      <para>MySQL Connector/J is flexible in the way it handles conversions
-      between MySQL data types and Java data types.</para>
-
-      <para>In general, any MySQL data type can be converted to a
-      java.lang.String, and any numerical type can be converted to any of the
-      Java numerical types, although round-off, overflow, or loss of precision
-      may occur.</para>
-
-      <para>The conversions that are always guaranteed to work are listed in
-      the following table:</para>
-
-      <table>
-        <title>Conversion Table</title>
-
-        <tgroup cols="2">
-          <thead>
-            <row>
-              <entry>These MySQL Data Types</entry>
-
-              <entry>Can always be converted to these Java types</entry>
-            </row>
-          </thead>
-
-          <tbody>
-            <row>
-              <entry><type>CHAR, VARCHAR, BLOB, TEXT, ENUM, and
-              SET</type></entry>
-
-              <entry><classname>java.lang.String, java.io.InputStream,
-              java.io.Reader, java.sql.Blob, java.sql.Clob</classname></entry>
-            </row>
-
-            <row>
-              <entry><type>FLOAT, REAL, DOUBLE PRECISION, NUMERIC, DECIMAL,
-              TINYINT, SMALLINT, MEDIUMINT, INTEGER, BIGINT</type></entry>
-
-              <entry><classname>java.lang.String, java.lang.Short,
-              java.lang.Integer, java.lang.Long, java.lang.Double,
-              java.math.BigDecimal</classname><note>
-                  <para>round-off, overflow or loss of precision may occur if
-                  you choose a Java numeric data type that has less precision
-                  or capacity than the MySQL data type you are converting
-                  to/from.</para>
-                </note></entry>
-            </row>
-
-            <row>
-              <entry><type>DATE, TIME, DATETIME, TIMESTAMP</type></entry>
-
-              <entry><classname>java.lang.String, java.sql.Date,
-              java.sql.Timestamp</classname></entry>
-            </row>
-          </tbody>
-        </tgroup>
-      </table>
-
-      <para>Columns with an unsigned numeric type in MySQL are treated as the
-      next 'larger' Java type that the signed variant of the MySQL type maps
-      to:<table>
-          <title>Unsigned Types Mapping</title>
-
-          <tgroup cols="2">
-            <thead>
-              <row>
-                <entry>MySQL Type</entry>
-
-                <entry>Corresponding Java Type</entry>
-              </row>
-            </thead>
-
-            <tbody>
-              <row>
-                <entry><type>TINYINT UNSIGNED</type></entry>
-
-                <entry><classname>java.lang.Integer</classname></entry>
-              </row>
+                </example></para>
+            </answer>
+          </qandaentry>
+
+          <qandaentry>
+            <question>
+              <para>I'm trying to use JDBC-2.0 updatable result sets, and I
+              get an exception saying my result set is not updatable.</para>
+            </question>
+
+            <answer>
+              <para>Because MySQL does not have row identifiers, MySQL
+              Connector/J can only update result sets that have come from
+              queries on tables that have at least one primary key, the query
+              must select all of the primary key(s) and the query can only
+              span one table (i.e. no joins). This is outlined in the JDBC
+              specification.</para>
+            </answer>
+          </qandaentry>
+        </qandaset>
+      </sect2>
 
-              <row>
-                <entry><type>SMALLINT UNSIGNED</type></entry>
+<!--
+      <sect2 id="cj-tracing">
+        <title>Enabling Tracing Options</title>
 
-                <entry><classname>java.lang.Integer</classname></entry>
-              </row>
+        <para></para>
+      </sect2>
+-->
 
-              <row>
-                <entry><type>MEDIUMINT UNSIGNED</type></entry>
+      <sect2 id="cj-reporting-bugs">
+        <title>How to Report Bugs or Problems</title>
 
-                <entry><classname>java.lang.Long</classname></entry>
-              </row>
+        <para>The normal place to report bugs is <ulink
+        url="http://bugs.mysql.com/">http://bugs.mysql.com/</ulink>, which is
+        the address for our bugs database. This database is public, and can be
+        browsed and searched by anyone. If you log in to the system, you will
+        also be able to enter new reports.</para>
+
+        <para>If you have found a sensitive security bug in MySQL, you can
+        send email to <ulink
+        url="mailto:security@stripped">security@stripped</ulink>.</para>
+
+        <para>Writing a good bug report takes patience, but doing it right the
+        first time saves time both for us and for yourself. A good bug report,
+        containing a full test case for the bug, makes it very likely that we
+        will fix the bug in the next release.</para>
+
+        <para>This section will help you write your report correctly so that
+        you don't waste your time doing things that may not help us much or at
+        all.</para>
+
+        <para>If you have a repeatable bug report, please report it to the
+        bugs database at <ulink
+        url="???">http://bugs.mysql.com/</ulink>.</para>
+
+        <para>Any bug that we are able to repeat has a high chance of being
+        fixed in the next MySQL release.</para>
+
+        <para>To report other problems, you can use one of the MySQL mailing
+        lists.</para>
+
+        <para>Remember that it is possible for us to respond to a message
+        containing too much information, but not to one containing too little.
+        People often omit facts because they think they know the cause of a
+        problem and assume that some details don't matter.</para>
+
+        <para>A good principle is this: If you are in doubt about stating
+        something, state it. It is faster and less troublesome to write a
+        couple more lines in your report than to wait longer for the answer if
+        we must ask you to provide information that was missing from the
+        initial report.</para>
+
+        <para>The most common errors made in bug reports are (a) not including
+        the version number of Connector/J or MySQL used, and (b) not fully
+        describing the platform on which Connector/J is installed (including
+        the JVM version, and the platform type and version number that MySQL
+        itself is installed on).</para>
+
+        <para>This is highly relevant information, and in 99 cases out of 100,
+        the bug report is useless without it. Very often we get questions
+        like, ``Why doesn't this work for me?'' Then we find that the feature
+        requested wasn't implemented in that MySQL version, or that a bug
+        described in a report has already been fixed in newer MySQL
+        versions.</para>
+
+        <para>Sometimes the error is platform-dependent; in such cases, it is
+        next to impossible for us to fix anything without knowing the
+        operating system and the version number of the platform.</para>
+
+        <para>If at all possible, you should create a repeatable, stanalone
+        testcase that doesn't involve any third-party classes.</para>
+
+        <para>To streamline this process, we ship a base class for testcases
+        with Connector/J, named
+        '<classname>com.mysql.jdbc.util.BaseBugReport</classname>'. To create
+        a testcase for Connector/J using this class, create your own class
+        that inherits from
+        <classname>com.mysql.jdbc.util.BaseBugReport</classname> and override
+        the methods <methodname>setUp()</methodname>,
+        <methodname>tearDown()</methodname> and
+        <methodname>runTest</methodname>().</para>
+
+        <para>In the <methodname>setUp()</methodname> method, create code that
+        creates your tables, and populates them with any data needed to
+        demonstrate the bug.</para>
+
+        <para>In the <methodname>runTest</methodname>() method, create code
+        that demonstrates the bug using the tables and data you created in the
+        'setUp' method.</para>
+
+        <para>In the <methodname>tearDown()</methodname> method, drop any
+        tables you created in the <methodname>setUp()</methodname>
+        method.</para>
+
+        <para>In any of the above three methods, you should use one of the
+        variants of the <methodname>getConnection</methodname>() method to
+        create a JDBC connection to MySQL:</para>
 
-              <row>
-                <entry><type>INT UNSIGNED</type></entry>
+        <para><itemizedlist>
+            <listitem>
+              <para>getConnection() - Provides a connection to the JDBC URL
+              specified in getUrl(). If a connection already exists, that
+              connection is returned, otherwise a new connection is
+              created.</para>
+            </listitem>
 
-                <entry><classname>java.lang.Long</classname></entry>
-              </row>
+            <listitem>
+              <para>getNewConnection() - Use this if you need to get a new
+              connection for your bug report (i.e. there's more than one
+              connection involved).</para>
+            </listitem>
 
-              <row>
-                <entry><type>BIGINT UNSIGNED</type></entry>
+            <listitem>
+              <para>getConnection(String url) - Returns a connection using the
+              given URL.</para>
+            </listitem>
 
-                <entry><classname>java.math.BigInteger</classname><note>
-                    <para>Before MySQL Connector/J 3.1.3, <type>BIGINT
-                    UNSIGNED</type> was mapped to
-                    <classname>java.math.BigDecimal</classname>.</para>
-                  </note></entry>
-              </row>
-            </tbody>
-          </tgroup>
-        </table></para>
+            <listitem>
+              <para>getConnection(String url, Properties props) - Returns a
+              connection using the given URL and properties.</para>
+            </listitem>
+          </itemizedlist>If you need to use a JDBC URL that is different than
+        'jdbc:mysql:///test', then override the method
+        <methodname>getUrl()</methodname> as well.</para>
+
+        <para>Use the <methodname>assertTrue(boolean expression)</methodname>
+        and <methodname>assertTrue(String failureMessage, boolean
+        expression)</methodname> methods to create conditions that must be met
+        in your testcase demonstrating the behavior you are expecting (vs. the
+        behavior you are observing, which is why you are most likely filing a
+        bug report).</para>
+
+        <para>Finally, create a <methodname>main</methodname>() method that
+        creates a new instance of your testcase, and calls the
+        <methodname>run</methodname> method: <programlisting>public static void main(String[] args) throws Exception {
+      new MyBugReport().run();
+ }</programlisting> Once you have finished your testcase, and have verified
+        that it demonstrates the bug you are reporting, upload it with your
+        bug report to <ulink
+        url="http://bugs.mysql.com/">http://bugs.mysql.com/</ulink>.</para>
+      </sect2>
     </sect1>
-  </appendix>
-
-  <appendix>
-    <title id="connector_j_sql_states_mapping">How Connector/J Maps MySQL
-    Errors to SQLStates</title>
-
-    <para>The JDBC API uses SQLStates as a standard way of identifying error
-    conditions in SQLExceptions. Prior to MySQL server version 4.1,
-    Connector/J performed this mapping itself, as the server did not use
-    SQLStates. MySQL server versions 4.1.0 send SQLState codes with error
-    messages which Connector/J uses in SQLExceptions.</para>
-
-    <para>Prior to Connector/J version 3.1.3, a combination of SQL Standard
-    and X/Open SQLStates were used for MySQL server versions older than
-    4.1.0.</para>
-
-    <para>Connector/J version 3.1.3 and newer use the SQL Standard SQLStates
-    returned from the server (if available), or a mapping to SQL Standard
-    SQLStates, unless the configuration property
-    '<parameter>useSqlStateCodes</parameter>' is set to 'false', which will
-    cause the driver to use the older, 'legacy' SQLState mappings that
-    Connector/J 3.0 used.</para>
-
-    <para>The following table shows the mapping of MySQL error numbers to
-    SQLStates that Connector/J uses:</para>
-
-    <table>
-      <title>Mapping of MySQL Error Numbers to SQLStates</title>
-
-      <tgroup cols="4">
-        <thead>
-          <row>
-            <entry>MySQL Error Number</entry>
-
-            <entry>MySQL Error Name</entry>
-
-            <entry>Legacy (X/Open) SQLState</entry>
-
-            <entry>SQL Standard SQLState</entry>
-          </row>
-        </thead>
-
-        <tbody>
-          <row>
-            <entry>1022</entry>
-
-            <entry>ER_DUP_KEY</entry>
-
-            <entry>S1000</entry>
-
-            <entry>23000</entry>
-          </row>
-
-          <row>
-            <entry>1037</entry>
-
-            <entry>ER_OUTOFMEMORY</entry>
-
-            <entry>S1001</entry>
-
-            <entry>HY001</entry>
-          </row>
-
-          <row>
-            <entry>1038</entry>
-
-            <entry>ER_OUT_OF_SORTMEMORY</entry>
-
-            <entry>S1001</entry>
-
-            <entry>HY001</entry>
-          </row>
-
-          <row>
-            <entry>1040</entry>
-
-            <entry>ER_CON_COUNT_ERROR</entry>
-
-            <entry>08004</entry>
-
-            <entry>08004</entry>
-          </row>
-
-          <row>
-            <entry>1042</entry>
-
-            <entry>ER_BAD_HOST_ERROR</entry>
-
-            <entry>08004</entry>
-
-            <entry>08S01</entry>
-          </row>
-
-          <row>
-            <entry>1043</entry>
-
-            <entry>ER_HANDSHAKE_ERROR</entry>
-
-            <entry>08004</entry>
-
-            <entry>08S01</entry>
-          </row>
-
-          <row>
-            <entry>1044</entry>
-
-            <entry>ER_DBACCESS_DENIED_ERROR</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1045</entry>
-
-            <entry>ER_ACCESS_DENIED_ERROR</entry>
-
-            <entry>28000</entry>
-
-            <entry>28000</entry>
-          </row>
-
-          <row>
-            <entry>1047</entry>
-
-            <entry>ER_UNKNOWN_COM_ERROR</entry>
-
-            <entry>08S01</entry>
-
-            <entry>HY000</entry>
-          </row>
-
-          <row>
-            <entry>1050</entry>
-
-            <entry>ER_TABLE_EXISTS_ERROR</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42S01</entry>
-          </row>
-
-          <row>
-            <entry>1051</entry>
-
-            <entry>ER_BAD_TABLE_ERROR</entry>
-
-            <entry>42S02</entry>
-
-            <entry>42S02</entry>
-          </row>
-
-          <row>
-            <entry>1052</entry>
-
-            <entry>ER_NON_UNIQ_ERROR</entry>
-
-            <entry>S1000</entry>
-
-            <entry>23000</entry>
-          </row>
-
-          <row>
-            <entry>1053</entry>
-
-            <entry>ER_SERVER_SHUTDOWN</entry>
-
-            <entry>S1000</entry>
-
-            <entry>08S01</entry>
-          </row>
-
-          <row>
-            <entry>1054</entry>
-
-            <entry>ER_BAD_FIELD_ERROR</entry>
-
-            <entry>S0022</entry>
-
-            <entry>42S22</entry>
-          </row>
-
-          <row>
-            <entry>1055</entry>
-
-            <entry>ER_WRONG_FIELD_WITH_GROUP</entry>
-
-            <entry>S1009</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1056</entry>
-
-            <entry>ER_WRONG_GROUP_FIELD</entry>
-
-            <entry>S1009</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1057</entry>
-
-            <entry>ER_WRONG_SUM_SELECT</entry>
-
-            <entry>S1009</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1058</entry>
-
-            <entry>ER_WRONG_VALUE_COUNT</entry>
-
-            <entry>21S01</entry>
-
-            <entry>21S01</entry>
-          </row>
-
-          <row>
-            <entry>1059</entry>
-
-            <entry>ER_TOO_LONG_IDENT</entry>
-
-            <entry>S1009</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1060</entry>
-
-            <entry>ER_DUP_FIELDNAME</entry>
-
-            <entry>S1009</entry>
-
-            <entry>42S21</entry>
-          </row>
-
-          <row>
-            <entry>1061</entry>
-
-            <entry>ER_DUP_KEYNAME</entry>
-
-            <entry>S1009</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1062</entry>
-
-            <entry>ER_DUP_ENTRY</entry>
-
-            <entry>S1009</entry>
-
-            <entry>23000</entry>
-          </row>
-
-          <row>
-            <entry>1063</entry>
-
-            <entry>ER_WRONG_FIELD_SPEC</entry>
-
-            <entry>S1009</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1064</entry>
-
-            <entry>ER_PARSE_ERROR</entry>
-
-            <entry>42000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1065</entry>
-
-            <entry>ER_EMPTY_QUERY</entry>
-
-            <entry>42000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1066</entry>
-
-            <entry>ER_NONUNIQ_TABLE</entry>
-
-            <entry>S1009</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1067</entry>
-
-            <entry>ER_INVALID_DEFAULT</entry>
-
-            <entry>S1009</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1068</entry>
-
-            <entry>ER_MULTIPLE_PRI_KEY</entry>
-
-            <entry>S1009</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1069</entry>
-
-            <entry>ER_TOO_MANY_KEYS</entry>
-
-            <entry>S1009</entry>
 
-            <entry>42000</entry>
-          </row>
+    <sect1 id="cj-changelog">
+      <title>Changelog</title>
 
-          <row>
-            <entry>1070</entry>
+      <programlisting># Changelog
+# $Id: CHANGES,v 1.38.4.192 2005/04/11 22:23:47 mmatthews Exp $
 
-            <entry>ER_TOO_MANY_KEY_PARTS</entry>
+04-14-05 - Version 3.1.8-stable
 
-            <entry>S1009</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1071</entry>
-
-            <entry>ER_TOO_LONG_KEY</entry>
-
-            <entry>S1009</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1072</entry>
-
-            <entry>ER_KEY_COLUMN_DOES_NOT_EXITS</entry>
-
-            <entry>S1009</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1073</entry>
-
-            <entry>ER_BLOB_USED_AS_KEY</entry>
-
-            <entry>S1009</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1074</entry>
-
-            <entry>ER_TOO_BIG_FIELDLENGTH</entry>
-
-            <entry>S1009</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1075</entry>
-
-            <entry>ER_WRONG_AUTO_KEY</entry>
-
-            <entry>S1009</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1080</entry>
-
-            <entry>ER_FORCING_CLOSE</entry>
-
-            <entry>S1000</entry>
-
-            <entry>08S01</entry>
-          </row>
-
-          <row>
-            <entry>1081</entry>
-
-            <entry>ER_IPSOCK_ERROR</entry>
-
-            <entry>08S01</entry>
-
-            <entry>08S01</entry>
-          </row>
-
-          <row>
-            <entry>1082</entry>
-
-            <entry>ER_NO_SUCH_INDEX</entry>
-
-            <entry>S1009</entry>
-
-            <entry>42S12</entry>
-          </row>
-
-          <row>
-            <entry>1083</entry>
-
-            <entry>ER_WRONG_FIELD_TERMINATORS</entry>
-
-            <entry>S1009</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1084</entry>
-
-            <entry>ER_BLOBS_AND_NO_TERMINATED</entry>
-
-            <entry>S1009</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1090</entry>
-
-            <entry>ER_CANT_REMOVE_ALL_FIELDS</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1091</entry>
-
-            <entry>ER_CANT_DROP_FIELD_OR_KEY</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1101</entry>
-
-            <entry>ER_BLOB_CANT_HAVE_DEFAULT</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1102</entry>
-
-            <entry>ER_WRONG_DB_NAME</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1103</entry>
-
-            <entry>ER_WRONG_TABLE_NAME</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1104</entry>
-
-            <entry>ER_TOO_BIG_SELECT</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1106</entry>
-
-            <entry>ER_UNKNOWN_PROCEDURE</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1107</entry>
-
-            <entry>ER_WRONG_PARAMCOUNT_TO_PROCEDURE</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1109</entry>
-
-            <entry>ER_UNKNOWN_TABLE</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42S02</entry>
-          </row>
-
-          <row>
-            <entry>1110</entry>
-
-            <entry>ER_FIELD_SPECIFIED_TWICE</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1112</entry>
-
-            <entry>ER_UNSUPPORTED_EXTENSION</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1113</entry>
-
-            <entry>ER_TABLE_MUST_HAVE_COLUMNS</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1115</entry>
-
-            <entry>ER_UNKNOWN_CHARACTER_SET</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1118</entry>
-
-            <entry>ER_TOO_BIG_ROWSIZE</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1120</entry>
-
-            <entry>ER_WRONG_OUTER_JOIN</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1121</entry>
-
-            <entry>ER_NULL_COLUMN_IN_INDEX</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1129</entry>
-
-            <entry>ER_HOST_IS_BLOCKED</entry>
-
-            <entry>08004</entry>
-
-            <entry>HY000</entry>
-          </row>
-
-          <row>
-            <entry>1130</entry>
-
-            <entry>ER_HOST_NOT_PRIVILEGED</entry>
-
-            <entry>08004</entry>
-
-            <entry>HY000</entry>
-          </row>
-
-          <row>
-            <entry>1131</entry>
-
-            <entry>ER_PASSWORD_ANONYMOUS_USER</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1132</entry>
-
-            <entry>ER_PASSWORD_NOT_ALLOWED</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1133</entry>
-
-            <entry>ER_PASSWORD_NO_MATCH</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1136</entry>
-
-            <entry>ER_WRONG_VALUE_COUNT_ON_ROW</entry>
-
-            <entry>S1000</entry>
-
-            <entry>21S01</entry>
-          </row>
-
-          <row>
-            <entry>1138</entry>
-
-            <entry>ER_INVALID_USE_OF_NULL</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1139</entry>
-
-            <entry>ER_REGEXP_ERROR</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1140</entry>
-
-            <entry>ER_MIX_OF_GROUP_FUNC_AND_FIELDS</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1141</entry>
-
-            <entry>ER_NONEXISTING_GRANT</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1142</entry>
-
-            <entry>ER_TABLEACCESS_DENIED_ERROR</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1143</entry>
-
-            <entry>ER_COLUMNACCESS_DENIED_ERROR</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1144</entry>
-
-            <entry>ER_ILLEGAL_GRANT_FOR_TABLE</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1145</entry>
-
-            <entry>ER_GRANT_WRONG_HOST_OR_USER</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1146</entry>
-
-            <entry>ER_NO_SUCH_TABLE</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42S02</entry>
-          </row>
-
-          <row>
-            <entry>1147</entry>
-
-            <entry>ER_NONEXISTING_TABLE_GRANT</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1148</entry>
-
-            <entry>ER_NOT_ALLOWED_COMMAND</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1149</entry>
-
-            <entry>ER_SYNTAX_ERROR</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1152</entry>
-
-            <entry>ER_ABORTING_CONNECTION</entry>
-
-            <entry>S1000</entry>
-
-            <entry>08S01</entry>
-          </row>
-
-          <row>
-            <entry>1153</entry>
-
-            <entry>ER_NET_PACKET_TOO_LARGE</entry>
-
-            <entry>S1000</entry>
-
-            <entry>08S01</entry>
-          </row>
-
-          <row>
-            <entry>1154</entry>
-
-            <entry>ER_NET_READ_ERROR_FROM_PIPE</entry>
-
-            <entry>S1000</entry>
-
-            <entry>08S01</entry>
-          </row>
-
-          <row>
-            <entry>1155</entry>
-
-            <entry>ER_NET_FCNTL_ERROR</entry>
-
-            <entry>S1000</entry>
-
-            <entry>08S01</entry>
-          </row>
-
-          <row>
-            <entry>1156</entry>
-
-            <entry>ER_NET_PACKETS_OUT_OF_ORDER</entry>
-
-            <entry>S1000</entry>
-
-            <entry>08S01</entry>
-          </row>
-
-          <row>
-            <entry>1157</entry>
-
-            <entry>ER_NET_UNCOMPRESS_ERROR</entry>
-
-            <entry>S1000</entry>
-
-            <entry>08S01</entry>
-          </row>
-
-          <row>
-            <entry>1158</entry>
-
-            <entry>ER_NET_READ_ERROR</entry>
-
-            <entry>S1000</entry>
-
-            <entry>08S01</entry>
-          </row>
-
-          <row>
-            <entry>1159</entry>
-
-            <entry>ER_NET_READ_INTERRUPTED</entry>
-
-            <entry>S1000</entry>
-
-            <entry>08S01</entry>
-          </row>
-
-          <row>
-            <entry>1160</entry>
-
-            <entry>ER_NET_ERROR_ON_WRITE</entry>
-
-            <entry>S1000</entry>
-
-            <entry>08S01</entry>
-          </row>
-
-          <row>
-            <entry>1161</entry>
-
-            <entry>ER_NET_WRITE_INTERRUPTED</entry>
-
-            <entry>S1000</entry>
-
-            <entry>08S01</entry>
-          </row>
-
-          <row>
-            <entry>1162</entry>
-
-            <entry>ER_TOO_LONG_STRING</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1163</entry>
-
-            <entry>ER_TABLE_CANT_HANDLE_BLOB</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1164</entry>
-
-            <entry>ER_TABLE_CANT_HANDLE_AUTO_INCREMENT</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1166</entry>
-
-            <entry>ER_WRONG_COLUMN_NAME</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1167</entry>
-
-            <entry>ER_WRONG_KEY_COLUMN</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1169</entry>
-
-            <entry>ER_DUP_UNIQUE</entry>
-
-            <entry>S1000</entry>
-
-            <entry>23000</entry>
-          </row>
-
-          <row>
-            <entry>1170</entry>
-
-            <entry>ER_BLOB_KEY_WITHOUT_LENGTH</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1171</entry>
-
-            <entry>ER_PRIMARY_CANT_HAVE_NULL</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1172</entry>
-
-            <entry>ER_TOO_MANY_ROWS</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1173</entry>
-
-            <entry>ER_REQUIRES_PRIMARY_KEY</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1177</entry>
-
-            <entry>ER_CHECK_NO_SUCH_TABLE</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1178</entry>
-
-            <entry>ER_CHECK_NOT_IMPLEMENTED</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1179</entry>
-
-            <entry>ER_CANT_DO_THIS_DURING_AN_TRANSACTION</entry>
-
-            <entry>S1000</entry>
-
-            <entry>25000</entry>
-          </row>
-
-          <row>
-            <entry>1184</entry>
-
-            <entry>ER_NEW_ABORTING_CONNECTION</entry>
-
-            <entry>S1000</entry>
-
-            <entry>08S01</entry>
-          </row>
-
-          <row>
-            <entry>1189</entry>
-
-            <entry>ER_MASTER_NET_READ</entry>
-
-            <entry>S1000</entry>
-
-            <entry>08S01</entry>
-          </row>
-
-          <row>
-            <entry>1190</entry>
-
-            <entry>ER_MASTER_NET_WRITE</entry>
-
-            <entry>S1000</entry>
-
-            <entry>08S01</entry>
-          </row>
-
-          <row>
-            <entry>1203</entry>
-
-            <entry>ER_TOO_MANY_USER_CONNECTIONS</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1205</entry>
-
-            <entry>ER_LOCK_WAIT_TIMEOUT</entry>
-
-            <entry>41000</entry>
-
-            <entry>HY000</entry>
-          </row>
-
-          <row>
-            <entry>1207</entry>
-
-            <entry>ER_READ_ONLY_TRANSACTION</entry>
-
-            <entry>S1000</entry>
-
-            <entry>25000</entry>
-          </row>
-
-          <row>
-            <entry>1211</entry>
-
-            <entry>ER_NO_PERMISSION_TO_CREATE_USER</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1213</entry>
-
-            <entry>ER_LOCK_DEADLOCK</entry>
-
-            <entry>41000</entry>
-
-            <entry>40001</entry>
-          </row>
-
-          <row>
-            <entry>1216</entry>
-
-            <entry>ER_NO_REFERENCED_ROW</entry>
-
-            <entry>S1000</entry>
-
-            <entry>23000</entry>
-          </row>
-
-          <row>
-            <entry>1217</entry>
-
-            <entry>ER_ROW_IS_REFERENCED</entry>
-
-            <entry>S1000</entry>
-
-            <entry>23000</entry>
-          </row>
-
-          <row>
-            <entry>1218</entry>
-
-            <entry>ER_CONNECT_TO_MASTER</entry>
-
-            <entry>S1000</entry>
-
-            <entry>08S01</entry>
-          </row>
-
-          <row>
-            <entry>1222</entry>
-
-            <entry>ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT</entry>
-
-            <entry>S1000</entry>
-
-            <entry>21000</entry>
-          </row>
-
-          <row>
-            <entry>1226</entry>
-
-            <entry>ER_USER_LIMIT_REACHED</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1230</entry>
-
-            <entry>ER_NO_DEFAULT</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1231</entry>
-
-            <entry>ER_WRONG_VALUE_FOR_VAR</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1232</entry>
-
-            <entry>ER_WRONG_TYPE_FOR_VAR</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1234</entry>
-
-            <entry>ER_CANT_USE_OPTION_HERE</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1235</entry>
-
-            <entry>ER_NOT_SUPPORTED_YET</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1239</entry>
-
-            <entry>ER_WRONG_FK_DEF</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1241</entry>
-
-            <entry>ER_OPERAND_COLUMNS</entry>
-
-            <entry>S1000</entry>
-
-            <entry>21000</entry>
-          </row>
-
-          <row>
-            <entry>1242</entry>
-
-            <entry>ER_SUBQUERY_NO_1_ROW</entry>
-
-            <entry>S1000</entry>
-
-            <entry>21000</entry>
-          </row>
-
-          <row>
-            <entry>1247</entry>
-
-            <entry>ER_ILLEGAL_REFERENCE</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42S22</entry>
-          </row>
-
-          <row>
-            <entry>1248</entry>
-
-            <entry>ER_DERIVED_MUST_HAVE_ALIAS</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1249</entry>
-
-            <entry>ER_SELECT_REDUCED</entry>
-
-            <entry>S1000</entry>
-
-            <entry>01000</entry>
-          </row>
-
-          <row>
-            <entry>1250</entry>
-
-            <entry>ER_TABLENAME_NOT_ALLOWED_HERE</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1251</entry>
-
-            <entry>ER_NOT_SUPPORTED_AUTH_MODE</entry>
-
-            <entry>S1000</entry>
-
-            <entry>08004</entry>
-          </row>
-
-          <row>
-            <entry>1252</entry>
-
-            <entry>ER_SPATIAL_CANT_HAVE_NULL</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1253</entry>
-
-            <entry>ER_COLLATION_CHARSET_MISMATCH</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1261</entry>
-
-            <entry>ER_WARN_TOO_FEW_RECORDS</entry>
-
-            <entry>S1000</entry>
-
-            <entry>01000</entry>
-          </row>
-
-          <row>
-            <entry>1262</entry>
-
-            <entry>ER_WARN_TOO_MANY_RECORDS</entry>
-
-            <entry>S1000</entry>
-
-            <entry>01000</entry>
-          </row>
-
-          <row>
-            <entry>1263</entry>
-
-            <entry>ER_WARN_NULL_TO_NOTNULL</entry>
-
-            <entry>S1000</entry>
-
-            <entry>01000</entry>
-          </row>
-
-          <row>
-            <entry>1264</entry>
-
-            <entry>ER_WARN_DATA_OUT_OF_RANGE</entry>
-
-            <entry>S1000</entry>
-
-            <entry>01000</entry>
-          </row>
-
-          <row>
-            <entry>1265</entry>
-
-            <entry>ER_WARN_DATA_TRUNCATED</entry>
-
-            <entry>S1000</entry>
-
-            <entry>01000</entry>
-          </row>
-
-          <row>
-            <entry>1280</entry>
-
-            <entry>ER_WRONG_NAME_FOR_INDEX</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
-
-          <row>
-            <entry>1281</entry>
-
-            <entry>ER_WRONG_NAME_FOR_CATALOG</entry>
-
-            <entry>S1000</entry>
-
-            <entry>42000</entry>
-          </row>
+    - Fixed DatabaseMetaData.getTables() returning views when they were 
+      not asked for as one of the requested table types.
+  
+    - Added support for new precision-math DECIMAL type in MySQL &gt;= 5.0.3.
 
-          <row>
-            <entry>1286</entry>
+    - Fixed ResultSet.getTime() on a NULL value for server-side prepared
+      statements throws NPE.
+  
+    - Made Connection.ping() a public method.
 
-            <entry>ER_UNKNOWN_STORAGE_ENGINE</entry>
+    - Fixed Bug#8868, DATE_FORMAT() queries returned as BLOBs from getObject().
 
-            <entry>S1000</entry>
+    - ServerPreparedStatements now correctly 'stream' BLOB/CLOB data to the
+      server. You can configure the threshold chunk size using the
+      JDBC URL property 'blobSendChunkSize' (the default is one megabyte).
+ 
+    - BlobFromLocator now uses correct identifier quoting when generating
+      prepared statements.
+      
+    - Server-side session variables can be preset at connection time by
+      passing them as a comma-delimited list for the connection property 
+      'sessionVariables'.
 
-            <entry>42000</entry>
-          </row>
-        </tbody>
-      </tgroup>
-    </table>
-  </appendix>
+    - Fixed regression in ping() for users using autoReconnect=true.
 
-  <appendix>
-    <title id="connector_j_changelog">ChangeLog</title>
+    - Fixed BUG#9040 - PreparedStatement.addBatch() doesn't work with server-side 
+      prepared statements and streaming BINARY data.
+  
+    - Fixed BUG#8800 - DBMD.supportsMixedCase*Identifiers() returns wrong
+      value on servers running on case-sensitive filesystems.
 
-    <programlisting># Changelog
-# $Id: CHANGES,v 1.38.4.146 2004/12/21 21:49:27 mmatthew Exp $
+    - Fixed BUG#9206, can not use 'UTF-8' for characterSetResults
+      configuration property.
+      
+    - Fixed BUG#9236, a continuation of BUG#8868, where functions used in queries 
+      that should return non-string types when resolved by temporary tables suddenly 
+      become opaque binary strings (work-around for server limitation). Also fixed
+      fields with type of CHAR(n) CHARACTER SET BINARY to return correct/matching
+      classes for RSMD.getColumnClassName() and ResultSet.getObject().
+    
+    - Fixed BUG#8792 - DBMD.supportsResultSetConcurrency() not returning
+      true for forward-only/read-only result sets (we obviously support this).
+      
+    - Fixed BUG#8803, 'DATA_TYPE' column from DBMD.getBestRowIdentifier()
+      causes ArrayIndexOutOfBoundsException when accessed (and in fact, didn't
+      return any value).
+      
+    - Check for empty strings ('') when converting char/varchar column data to numbers,
+      throw exception if 'emptyStringsConvertToZero' configuration property is set
+      to 'false' (for backwards-compatibility with 3.0, it is now set to 'true' 
+      by default, but will most likely default to 'false' in 3.2).
+      
+    - Fixed BUG#9320 - PreparedStatement.getMetaData() inserts blank row in database 
+      under certain conditions when not using server-side prepared statements.
+      
+    - Connection.canHandleAsPreparedStatement() now makes 'best effort' to distinguish
+      LIMIT clauses with placeholders in them from ones without in order to have fewer
+      false positives when generating work-arounds for statements the server cannot 
+      currently handle as server-side prepared statements.
+      
+    - Fixed build.xml to not compile log4j logging if log4j not available.
+    
+    - Added support for the c3p0 connection pool's (http://c3p0.sf.net/) 
+      validation/connection checker interface which uses the lightweight 
+      'COM_PING' call to the server if available. To use it, configure your
+      c3p0 connection pool's 'connectionTesterClassName' property to use
+      'com.mysql.jdbc.integration.c3p0.MysqlConnectionTester'.
+      
+    - Better detection of LIMIT inside/outside of quoted strings so that
+      the driver can more correctly determine whether a prepared statement
+      can be prepared on the server or not.
+    
+    - Fixed BUG#9319 - Stored procedures with same name in 
+      different databases confuse the driver when it tries to determine
+      parameter counts/types.
+  
+    - Added finalizers to ResultSet and Statement implementations to be JDBC
+      spec-compliant, which requires that if not explicitly closed, these 
+      resources should be closed upon garbage collection.
+      
+    - Fixed BUG#9682 - Stored procedures with DECIMAL parameters with
+      storage specifications that contained "," in them would fail.
+      
+    - PreparedStatement.setObject(int, Object, int type, int scale) now 
+      uses scale value for BigDecimal instances.
+      
+    - Fixed BUG#9704 - Statement.getMoreResults() could throw NPE when
+      existing result set was .close()d.
+      
+    - The performance metrics feature now gathers information about
+      number of tables referenced in a SELECT.
+    
+    - The logging system is now automatically configured. If the value has 
+      been set by the user, via the URL property "logger" or the system 
+      property "com.mysql.jdbc.logger", then use that, otherwise, autodetect 
+      it using the following steps:
+      
+         Log4j, if it's available,
+         Then JDK1.4 logging,
+         Then fallback to our STDERR logging.
+         
+    - Fixed BUG#9778, DBMD.getTables() shouldn't return tables if views
+      are asked for, even if the database version doesn't support views.
+      
+    - Fixed driver not returning 'true' for '-1' when ResultSet.getBoolean()
+      was called on result sets returned from server-side prepared statements.
+      
+    - Added a Manifest.MF file with implementation information to the .jar
+      file.
+      
+    - More tests in Field.isOpaqueBinary() to distinguish opaque binary (i.e. 
+      fields with type CHAR(n) and CHARACTER SET BINARY) from output of 
+      various scalar and aggregate functions that return strings.
 
 02-18-05 - Version 3.1.7-stable
 
@@ -5401,6 +5025,23 @@
     - Fixed BUG#8064, which requires hex escaping of binary data when using
       multibyte charsets with prepared statements.
 
+    - Fixed BUG#8812, NON_UNIQUE column from DBMD.getIndexInfo() returned 
+      inverted value.
+      
+    - Workaround for server BUG#9098 - default values of CURRENT_* for 
+      DATE/TIME/TIMESTAMP/TIMESTAMP columns can't be distinguished from
+      'string' values, so UpdatableResultSet.moveToInsertRow() generates
+      bad SQL for inserting default values.
+      
+    - Fixed BUG#8629 - 'EUCKR' charset is sent as 'SET NAMES euc_kr' which
+      MySQL-4.1 and newer doesn't understand.
+      
+    - DatabaseMetaData.supportsSelectForUpdate() returns correct value based
+      on server version.
+      
+    - Use hex escapes for PreparedStatement.setBytes() for double-byte charsets
+      including 'aliases' Windows-31J, CP934, MS932.
+
 11-15-04 - Version 3.0.16-ga
 
     - Re-issue character set configuration commands when re-using pooled
@@ -6850,5 +6491,8 @@
         * getColumns
         * getCatalogs()
 </programlisting>
-  </appendix>
-</book>
\ No newline at end of file
+
+      <para></para>
+    </sect1>
+  </chapter>
+</book>
Thread
bk commit - mysqldoc tree (mmatthew:1.2858)mark13 Apr