/* DatabaseMetaData.java -- Information about the database itself.
   Copyright (C) 1999, 2000, 2001, 2002, 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
 
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package java.sql;

public interface DatabaseMetaData 
{
  /**
   * It is unknown whether or not the procedure returns a result.
   */
  int procedureResultUnknown = 0;

  /**
   * The procedure does not return a result.
   */
  int procedureNoResult = 1;

  /**
   * The procedure returns a result.
   */
  int procedureReturnsResult = 2;

  /**
   * The column type is unknown.
   */
  int procedureColumnUnknown = 0;

  /**
   * The column type is input.
   */
  int procedureColumnIn = 1;

  /**
   * The column type is input/output.
   */
  int procedureColumnInOut = 2;

  /**
   * The column type is output
   */
  int procedureColumnOut = 4;

  /**
   * The column is used for return values.
   */
  int procedureColumnReturn = 5;

  /**
   * The column is used for storing results
   */
  int procedureColumnResult = 3;

  /**
   * NULL values are not allowed.
   */
  int procedureNoNulls = 0;

  /**
   * NULL values are allowed.
   */
  int procedureNullable = 1;

  /**
   * It is unknown whether or not NULL values are allowed.
   */
  int procedureNullableUnknown = 2;

  /**
   * The column does not allow NULL
   */
  int columnNoNulls = 0;

  /**
   * The column does allow NULL
   */
  int columnNullable = 1;

  /**
   * It is unknown whether or not the column allows NULL
   */
  int columnNullableUnknown = 2;

  /**
   * The best row's scope is only guaranteed to be valid so long as the
   * row is actually being used.
   */
  int bestRowTemporary = 0;

  /**
   * The best row identifier is valid to the end of the transaction.
   */
  int bestRowTransaction = 1;

  /**
   * The best row identifier is valid to the end of the session.
   */
  int bestRowSession = 2;

  /**
   * The best row may or may not be a pseudo-column.
   */
  int bestRowUnknown = 0;

  /**
   * The best row identifier is not a pseudo-column.
   */
  int bestRowNotPseudo = 1;

  /**
   * The best row identifier is a pseudo-column.
   */
  int bestRowPseudo = 2;

  /**
   * It is unknown whether or not the version column is a pseudo-column.
   */
  int versionColumnUnknown = 0;

  /**
   * The version column is not a pseudo-column
   */
  int versionColumnNotPseudo = 1;

  /**
   * The version column is a pseudo-column
   */
  int versionColumnPseudo = 2;

  /**
   * Foreign key changes are cascaded in updates or deletes.
   */
  int importedKeyCascade = 0;

  /**
   * Column may not be updated or deleted in use as a foreign key.
   */
  int importedKeyRestrict = 1;

  /**
   * When primary key is updated or deleted, the foreign key is set to NULL.
   */
  int importedKeySetNull = 2;

  /**
   * If the primary key is a foreign key, it cannot be udpated or deleted.
   */
  int importedKeyNoAction = 3;

  /**
   * If the primary key is updated or deleted, the foreign key is set to
   * a default value.
   */
  int importedKeySetDefault = 4;

  /**
   * Wish I knew what this meant.
   */
  int importedKeyInitiallyDeferred = 5;

  /**
   * Wish I knew what this meant.
   */
  int importedKeyInitiallyImmediate = 6;

  /**
   * Wish I knew what this meant.
   */
  int importedKeyNotDeferrable = 7;

  /**
   * A NULL value is not allowed for this data type.
   */
  int typeNoNulls = 0;

  /**
   * A NULL value is allowed for this data type.
   */
  int typeNullable = 1;

  /**
   * It is unknown whether or not NULL values are allowed for this data type.
   */
  int typeNullableUnknown = 2;

  /**
   * Where clauses are not supported for this type.
   */
  int typePredNone = 0;

  /**
   * Only "WHERE..LIKE" style WHERE clauses are allowed on this data type.
   */
  int typePredChar = 1;

  /**
   * All WHERE clauses except "WHERE..LIKE" style are allowed on this data type.
   */
  int typePredBasic = 2;

  /**
   * Any type of WHERE clause is allowed for this data type.
   */
  int typeSearchable = 3;

  /**
   * This column contains table statistics.
   */
  short tableIndexStatistic = 0;

  /**
   * This table index is clustered.
   */
  short tableIndexClustered = 1;

  /**
   * This table index is hashed.
   */
  short tableIndexHashed = 2;

  /**
   * This table index is of another type.
   */
  short tableIndexOther = 3;

  /**
   * A NULL value is not allowed for this attribute.
   */
  short attributeNoNulls = 0;

  /**
   * A NULL value is allowed for this attribute.
   */
  short attributeNullable = 1;

  /**
   * It is unknown whether or not NULL values are allowed for this attribute.
   */
  short attributeNullableUnknown = 2;

  int sqlStateXOpen = 1;

  int sqlStateSQL99 = 2;

  /**
   * This method tests whether or not all the procedures returned by
   * the <code>getProcedures</code> method can be called by this user.
   *
   * @return <code>true</code> if all the procedures can be called,
   * <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean allProceduresAreCallable() throws SQLException;

  /**
   * This method tests whether or not all the table returned by the
   * <code>getTables</code> method can be selected by this user.
   *
   * @return <code>true</code> if all the procedures can be called,
   * <code>false</code> otherwise.
   *
   * @exception SQLException If an error occurs.
   */
  boolean allTablesAreSelectable() throws SQLException;

  /**
   * This method returns the URL for this database.
   *
   * @return The URL string for this database, or <code>null</code> if it
   *         is not known.
   * @exception SQLException If an error occurs.
   */
  String getURL() throws SQLException;

  /**
   * This method returns the database username for this connection.
   *
   * @return The database username.
   * @exception SQLException If an error occurs.
   */
  String getUserName() throws SQLException;

  /**
   * This method tests whether or not the database is in read only mode.
   *
   * @return <code>true</code> if the database is in read only mode,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean isReadOnly() throws SQLException;

  /**
   * This method tests whether or not NULL's sort as high values.
   *
   * @return <code>true</code> if NULL's sort as high values, <code>false</code>
   *         otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean nullsAreSortedHigh() throws SQLException;

  /**
   * This method tests whether or not NULL's sort as low values.
   *
   * @return <code>true</code> if NULL's sort as low values, <code>false</code>
   * otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean nullsAreSortedLow() throws SQLException;

  /**
   * This method tests whether or not NULL's sort as high values.
   *
   * @return <code>true</code> if NULL's sort as high values, <code>false</code>
   * otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean nullsAreSortedAtStart() throws SQLException;

  /**
   * This method test whether or not NULL's are sorted to the end
   * of the list regardless of ascending or descending sort order.
   *
   * @return <code>true</code> if NULL's always sort to the end,
   * <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean nullsAreSortedAtEnd() throws SQLException;

  /**
   * This method returns the name of the database product.
   *
   * @return The database product.
   * @exception SQLException If an error occurs.
   */
  String getDatabaseProductName() throws SQLException;

  /**
   * This method returns the version of the database product.
   *
   * @return The version of the database product.
   * @exception SQLException If an error occurs.
   */
  String getDatabaseProductVersion() throws SQLException;

  /**
   * This method returns the name of the JDBC driver.
   *
   * @return The name of the JDBC driver.
   * @exception SQLException If an error occurs.
   */
  String getDriverName() throws SQLException;

  /**
   * This method returns the version of the JDBC driver.
   *
   * @return The version of the JDBC driver.
   * @exception SQLException If an error occurs.
   */
  String getDriverVersion() throws SQLException;

  /**
   * This method returns the major version number of the JDBC driver.
   *
   * @return The major version number of the JDBC driver.
   */
  int getDriverMajorVersion();

  /**
   * This method returns the minor version number of the JDBC driver.
   *
   * @return The minor version number of the JDBC driver.
   */
  int getDriverMinorVersion();

  /**
   * This method tests whether or not the database uses local files to
   * store tables.
   *
   * @return <code>true</code> if the database uses local files, 
   * <code>false</code> otherwise.
   *
   * @exception SQLException If an error occurs.
   */
  boolean usesLocalFiles() throws SQLException;

  /**
   * This method tests whether or not the database uses a separate file for
   * each table.
   *
   * @return <code>true</code> if the database uses a separate file for each
   * table <code>false</code> otherwise.
   *
   * @exception SQLException If an error occurs.
   */
  boolean usesLocalFilePerTable() throws SQLException;

  /**
   * This method tests whether or not the database supports identifiers
   * with mixed case.
   *
   * @return <code>true</code> if the database supports mixed case identifiers,
   * <code>false</code> otherwise.
   *
   * @exception SQLException If an error occurs.
   */
  boolean supportsMixedCaseIdentifiers() throws SQLException;

  /**
   * This method tests whether or not the database treats mixed case
   * identifiers as all upper case.
   *
   * @return <code>true</code> if the database treats all identifiers as
   *         upper case, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean storesUpperCaseIdentifiers() throws SQLException;

  /**
   * This method tests whether or not the database treats mixed case
   * identifiers as all lower case.
   *
   * @return <code>true</code> if the database treats all identifiers as
   *         lower case, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean storesLowerCaseIdentifiers() throws SQLException;

  /**
   * This method tests whether or not the database stores mixed case 
   * identifers even if it treats them as case insensitive.
   *
   * @return <code>true</code> if the database stores mixed case identifiers,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean storesMixedCaseIdentifiers() throws SQLException;

  /**
   * This method tests whether or not the database supports quoted identifiers
   * with mixed case.
   *
   * @return <code>true</code> if the database supports mixed case quoted
   *         identifiers, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsMixedCaseQuotedIdentifiers() throws SQLException;

  /**
   * This method tests whether or not the database treats mixed case
   * quoted identifiers as all upper case.
   *
   * @return <code>true</code> if the database treats all quoted identifiers 
   *         as upper case, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean storesUpperCaseQuotedIdentifiers() throws SQLException;

  /**
   * This method tests whether or not the database treats mixed case
   * quoted identifiers as all lower case.
   *
   * @return <code>true</code> if the database treats all quoted identifiers 
   *         as lower case, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean storesLowerCaseQuotedIdentifiers() throws SQLException;

  /**
   * This method tests whether or not the database stores mixed case 
   * quoted identifers even if it treats them as case insensitive.
   *
   * @return <code>true</code> if the database stores mixed case quoted 
   *         identifiers, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean storesMixedCaseQuotedIdentifiers() throws SQLException;

  /**
   * This metohd returns the quote string for SQL identifiers.
   *
   * @return The quote string for SQL identifers, or a space if quoting
   *         is not supported.
   * @exception SQLException If an error occurs.
   */
  String getIdentifierQuoteString() throws SQLException;

  /**
   * This method returns a comma separated list of all the SQL keywords in
   * the database that are not in SQL92.
   *
   * @return The list of SQL keywords not in SQL92.
   * @exception SQLException If an error occurs.
   */
  String getSQLKeywords() throws SQLException;

  /**
   * This method returns a comma separated list of math functions.
   *
   * @return The list of math functions.
   * @exception SQLException If an error occurs.
   */
  String getNumericFunctions() throws SQLException;

  /**
   * This method returns a comma separated list of string functions.
   *
   * @return The list of string functions.
   * @exception SQLException If an error occurs.
   */
  String getStringFunctions() throws SQLException;

  /**
   * This method returns a comma separated list of of system functions.
   *
   * @return A comma separated list of system functions.
   * @exception SQLException If an error occurs.
   */
  String getSystemFunctions() throws SQLException;

  /**
   * This method returns comma separated list of time/date functions.
   * 
   * @return The list of time/date functions.
   * @exception SQLException If an error occurs.
   */
  String getTimeDateFunctions() throws SQLException;

  /**
   * This method returns the string used to escape wildcards in search strings.
   *
   * @return The string used to escape wildcards in search strings.
   * @exception SQLException If an error occurs.
   */
  String getSearchStringEscape() throws SQLException;

  /**
   * This methods returns non-standard characters that can appear in 
   * unquoted identifiers.
   *
   * @return Non-standard characters that can appear in unquoted identifiers.
   * @exception SQLException If an error occurs.
   */
  String getExtraNameCharacters() throws SQLException;

  /**
   * This method tests whether or not the database supports
   * "ALTER TABLE ADD COLUMN"
   *
   * @return <code>true</code> if column add supported, <code>false</code>
   *         otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsAlterTableWithAddColumn() throws SQLException;

  /**
   * This method tests whether or not the database supports
   * "ALTER TABLE DROP COLUMN"
   *
   * @return <code>true</code> if column drop supported, <code>false</code>
   *         otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsAlterTableWithDropColumn() throws SQLException;

  /**
   * This method tests whether or not column aliasing is supported.
   *
   * @return <code>true</code> if column aliasing is supported,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsColumnAliasing() throws SQLException;

  /**
   * This method tests whether the concatenation of a NULL and non-NULL
   * value results in a NULL.  This will always be true in fully JDBC compliant
   * drivers.
   *
   * @return <code>true</code> if concatenating NULL and a non-NULL value
   *         returns a NULL, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean nullPlusNonNullIsNull() throws SQLException;

  /**
   * Tests whether or not CONVERT is supported.
   *
   * @return <code>true</code> if CONVERT is supported, <code>false</code>
   *         otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsConvert() throws SQLException;

  /**
   * This method tests whether or not CONVERT can be performed between the
   * specified types.  The types are contants from <code>Types</code>.
   *
   * @param fromType The SQL type to convert from.
   * @param toType The SQL type to convert to.
   * @return <code>true</code> if the conversion can be performed,
   *         <code>false</code> otherwise.
   * @see Types
   */
  boolean supportsConvert(int fromType, int toType) throws
      SQLException;

  /**
   * This method tests whether or not table correlation names are 
   * supported.  This will be always be <code>true</code> in a fully JDBC
   * compliant driver.
   *
   * @return <code>true</code> if table correlation names are supported,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsTableCorrelationNames() throws SQLException;

  /**
   * This method tests whether correlation names must be different from the
   * name of the table.
   *
   * @return <code>true</code> if the correlation name must be different from
   *         the table name, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsDifferentTableCorrelationNames() throws SQLException;

  /**
   * This method tests whether or not expressions are allowed in an
   * ORDER BY lists.
   *
   * @return <code>true</code> if expressions are allowed in ORDER BY
   *         lists, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsExpressionsInOrderBy() throws SQLException;

  /**
   * This method tests whether or ORDER BY on a non-selected column is
   * allowed.
   *
   * @return <code>true</code> if a non-selected column can be used in an
   *         ORDER BY, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsOrderByUnrelated() throws SQLException;

  /**
   * This method tests whether or not GROUP BY is supported.
   *
   * @return <code>true</code> if GROUP BY is supported, <code>false</code>
   *         otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsGroupBy() throws SQLException;

  /**
   * This method tests whether GROUP BY on a non-selected column is
   * allowed.
   *
   * @return <code>true</code> if a non-selected column can be used in a
   *         GROUP BY, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsGroupByUnrelated() throws SQLException;

  /**
   * This method tests whether or not a GROUP BY can add columns not in the
   * select if it includes all the columns in the select.
   *
   * @return <code>true</code> if GROUP BY an add columns provided it includes
   *         all columns in the select, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsGroupByBeyondSelect() throws SQLException;

  /**
   * This method tests whether or not the escape character is supported in
   * LIKE expressions.  A fully JDBC compliant driver will always return
   * <code>true</code>.
   *
   * @return <code>true</code> if escapes are supported in LIKE expressions,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsLikeEscapeClause() throws SQLException;

  /**
   * This method tests whether multiple result sets for a single statement are
   * supported.
   *
   * @return <code>true</code> if multiple result sets are supported for a 
   *         single statement, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsMultipleResultSets() throws SQLException;

  /**
   * This method test whether or not multiple transactions may be open
   * at once, as long as they are on different connections.
   *
   * @return <code>true</code> if multiple transactions on different
   *         connections are supported, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsMultipleTransactions() throws SQLException;

  /**
   * This method tests whether or not columns can be defined as NOT NULL.  A
   * fully JDBC compliant driver always returns <code>true</code>.
   *
   * @return <code>true</code> if NOT NULL columns are supported,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsNonNullableColumns() throws SQLException;

  /**
   * This method tests whether or not the minimum grammer for ODBC is supported.
   * A fully JDBC compliant driver will always return <code>true</code>.
   *
   * @return <code>true</code> if the ODBC minimum grammar is supported,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsMinimumSQLGrammar() throws SQLException;

  /**
   * This method tests whether or not the core grammer for ODBC is supported.
   *
   * @return <code>true</code> if the ODBC core grammar is supported,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsCoreSQLGrammar() throws SQLException;

  /**
   * This method tests whether or not the extended grammer for ODBC is supported.
   *
   * @return <code>true</code> if the ODBC extended grammar is supported,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsExtendedSQLGrammar() throws SQLException;

  /**
   * This method tests whether or not the ANSI92 entry level SQL
   * grammar is supported.  A fully JDBC compliant drivers must return
   * <code>true</code>.
   *
   * @return <code>true</code> if the ANSI92 entry level SQL grammar is
   *         supported, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsANSI92EntryLevelSQL() throws SQLException;

  /**
   * This method tests whether or not the ANSI92 intermediate SQL
   * grammar is supported.  
   *
   * @return <code>true</code> if the ANSI92 intermediate SQL grammar is
   *         supported, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsANSI92IntermediateSQL() throws SQLException;

  /**
   * This method tests whether or not the ANSI92 full SQL
   * grammar is supported.  
   *
   * @return <code>true</code> if the ANSI92 full SQL grammar is
   *         supported, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsANSI92FullSQL() throws SQLException;

  /**
   * This method tests whether or not the SQL integrity enhancement
   * facility is supported.
   *
   * @return <code>true</code> if the integrity enhancement facility is
   *         supported, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsIntegrityEnhancementFacility() throws SQLException;

  /**
   * This method tests whether or not the database supports outer joins.
   *
   * @return <code>true</code> if outer joins are supported, <code>false</code>
   *         otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsOuterJoins() throws SQLException;

  /**
   * This method tests whether or not the database supports full outer joins.
   *
   * @return <code>true</code> if full outer joins are supported, 
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsFullOuterJoins() throws SQLException;

  /**
   * This method tests whether or not the database supports limited outer joins.
   *
   * @return <code>true</code> if limited outer joins are supported, 
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsLimitedOuterJoins() throws SQLException;

  /**
   * This method returns the vendor's term for "schema".
   *
   * @return The vendor's term for schema.
   * @exception SQLException if an error occurs.
   */
  String getSchemaTerm() throws SQLException;

  /**
   * This method returns the vendor's term for "procedure".
   *
   * @return The vendor's term for procedure.
   * @exception SQLException if an error occurs.
   */
  String getProcedureTerm() throws SQLException;

  /**
   * This method returns the vendor's term for "catalog".
   *
   * @return The vendor's term for catalog.
   * @exception SQLException if an error occurs.
   */
  String getCatalogTerm() throws SQLException;

  /**
   * This method tests whether a catalog name appears at the beginning of
   * a fully qualified table name.
   *
   * @return <code>true</code> if the catalog name appears at the beginning,
   *         <code>false</code> if it appears at the end.
   * @exception SQLException If an error occurs.
   */
  boolean isCatalogAtStart() throws SQLException;

  /**
   * This method returns the separator between the catalog name and the
   * table name.
   *
   * @return The separator between the catalog name and the table name.
   * @exception SQLException If an error occurs.
   */
  String getCatalogSeparator() throws SQLException;

  /**
   * This method tests whether a catalog name can appear in a data
   * manipulation statement.
   *
   * @return <code>true</code> if a catalog name can appear in a data
   *         manipulation statement, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsSchemasInDataManipulation() throws SQLException;

  /**
   * This method tests whether a catalog name can appear in a procedure
   * call
   *
   * @return <code>true</code> if a catalog name can appear in a procedure
   *         call, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsSchemasInProcedureCalls() throws SQLException;

  /**
   * This method tests whether a catalog name can appear in a table definition.
   *
   * @return <code>true</code> if a catalog name can appear in a table
   *         definition, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsSchemasInTableDefinitions() throws SQLException;

  /**
   * This method tests whether a catalog name can appear in an index definition.
   *
   * @return <code>true</code> if a catalog name can appear in an index
   *         definition, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsSchemasInIndexDefinitions() throws SQLException;

  /**
   * This method tests whether a catalog name can appear in privilege definitions.
   *
   * @return <code>true</code> if a catalog name can appear in privilege
   *         definition, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsSchemasInPrivilegeDefinitions() throws SQLException;

  /**
   * This method tests whether a catalog name can appear in a data
   * manipulation statement.
   *
   * @return <code>true</code> if a catalog name can appear in a data
   *         manipulation statement, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsCatalogsInDataManipulation() throws SQLException;

  /**
   * This method tests whether a catalog name can appear in a procedure
   * call
   *
   * @return <code>true</code> if a catalog name can appear in a procedure
   *         call, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsCatalogsInProcedureCalls() throws SQLException;

  /**
   * This method tests whether a catalog name can appear in a table definition.
   *
   * @return <code>true</code> if a catalog name can appear in a table
   *         definition, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsCatalogsInTableDefinitions() throws SQLException;

  /**
   * This method tests whether a catalog name can appear in an index definition.
   *
   * @return <code>true</code> if a catalog name can appear in an index
   *         definition, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsCatalogsInIndexDefinitions() throws SQLException;

  /**
   * This method tests whether a catalog name can appear in privilege definitions.
   *
   * @return <code>true</code> if a catalog name can appear in privilege
   *         definition, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException;

  /**
   * This method tests whether or not that database supports positioned
   * deletes.
   *
   * @return <code>true</code> if positioned deletes are supported,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsPositionedDelete() throws SQLException;

  /**
   * This method tests whether or not that database supports positioned
   * updates.
   *
   * @return <code>true</code> if positioned updates are supported,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsPositionedUpdate() throws SQLException;

  /**
   * This method tests whether or not SELECT FOR UPDATE is supported by the
   * database.
   *
   * @return <code>true</code> if SELECT FOR UPDATE is supported 
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsSelectForUpdate() throws SQLException;

  /**
   * This method tests whether or not stored procedures are supported on
   * this database.
   *
   * @return <code>true</code> if stored procedures are supported,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsStoredProcedures() throws SQLException;

  /**
   * This method tests whether or not subqueries are allowed in comparisons.
   * A fully JDBC compliant driver will always return <code>true</code>.
   *
   * @return <code>true</code> if subqueries are allowed in comparisons,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsSubqueriesInComparisons() throws SQLException;

  /**
   * This method tests whether or not subqueries are allowed in exists
   * expressions.  A fully JDBC compliant driver will always return
   * <code>true</code>.
   *
   * @return <code>true</code> if subqueries are allowed in exists 
   *         expressions, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsSubqueriesInExists() throws SQLException;

  /**
   * This method tests whether subqueries are allowed in IN statements.
   * A fully JDBC compliant driver will always return <code>true</code>.
   *
   * @return <code>true</code> if the driver supports subqueries in IN
   *         statements, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsSubqueriesInIns() throws SQLException;

  /**
   * This method tests whether or not subqueries are allowed in quantified
   * expressions.  A fully JDBC compliant driver will always return
   * <code>true</code>.
   *
   * @return <code>true</code> if subqueries are allowed in quantified 
   *         expressions, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsSubqueriesInQuantifieds() throws SQLException;

  /**
   * This method test whether or not correlated subqueries are allowed. A
   * fully JDBC compliant driver will always return <code>true</code>.
   *
   * @return <code>true</code> if correlated subqueries are allowed,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsCorrelatedSubqueries() throws SQLException;

  /**
   * This method tests whether or not the UNION statement is supported.
   *
   * @return <code>true</code> if UNION is supported, <code>false</code>
   *         otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsUnion() throws SQLException;

  /**
   * This method tests whether or not the UNION ALL statement is supported.
   *
   * @return <code>true</code> if UNION ALL is supported, <code>false</code>
   *         otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsUnionAll() throws SQLException;

  /**
   * This method tests whether or not the database supports cursors
   * remaining open across commits.
   *
   * @return <code>true</code> if cursors can remain open across commits,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsOpenCursorsAcrossCommit() throws SQLException;

  /**
   * This method tests whether or not the database supports cursors
   * remaining open across rollbacks.
   *
   * @return <code>true</code> if cursors can remain open across rollbacks,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsOpenCursorsAcrossRollback() throws SQLException;

  /**
   * This method tests whether or not the database supports statements
   * remaining open across commits.
   *
   * @return <code>true</code> if statements can remain open across commits,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsOpenStatementsAcrossCommit() throws SQLException;

  /**
   * This method tests whether or not the database supports statements
   * remaining open across rollbacks.
   *
   * @return <code>true</code> if statements can remain open across rollbacks,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsOpenStatementsAcrossRollback() throws SQLException;

  /**
   * This method returns the number of hex characters allowed in an inline
   * binary literal.
   *
   * @return The number of hex characters allowed in a binary literal, 0 meaning
   *         either an unknown or unlimited number.
   * @exception SQLException If an error occurs.
   */
  int getMaxBinaryLiteralLength() throws SQLException;

  /**
   * This method returns the maximum length of a character literal.
   * 
   * @return The maximum length of a character literal.
   * @exception SQLException If an error occurs.
   */
  int getMaxCharLiteralLength() throws SQLException;

  /**
   * This method returns the maximum length of a column name.
   *
   * @return The maximum length of a column name.
   * @exception SQLException If an error occurs.
   */
  int getMaxColumnNameLength() throws SQLException;

  /**
   * This method returns the maximum number of columns in a GROUP BY statement.
   *
   * @return The maximum number of columns in a GROUP BY statement.
   * @exception SQLException If an error occurs.
   */
  int getMaxColumnsInGroupBy() throws SQLException;

  /**
   * This method returns the maximum number of columns in an index.
   *
   * @return The maximum number of columns in an index.
   * @exception SQLException If an error occurs.
   */
  int getMaxColumnsInIndex() throws SQLException;

  /**
   * This method returns the maximum number of columns in an ORDER BY statement.
   *
   * @return The maximum number of columns in an ORDER BY statement.
   * @exception SQLException If an error occurs.
   */
  int getMaxColumnsInOrderBy() throws SQLException;

  /**
   * This method returns the maximum number of columns in a SELECT statement.
   *
   * @return The maximum number of columns in a SELECT statement.
   * @exception SQLException If an error occurs.
   */
  int getMaxColumnsInSelect() throws SQLException;

  /**
   * This method returns the maximum number of columns in a table.
   *
   * @return The maximum number of columns in a table.
   * @exception SQLException If an error occurs.
   */
  int getMaxColumnsInTable() throws SQLException;

  /**
   * This method returns the maximum number of connections this client
   * can have to the database.
   *
   * @return The maximum number of database connections.
   * @SQLException If an error occurs.
   */
  int getMaxConnections() throws SQLException;

  /**
   * This method returns the maximum length of a cursor name.
   *
   * @return The maximum length of a cursor name.
   * @exception SQLException If an error occurs.
   */
  int getMaxCursorNameLength() throws SQLException;

  /**
   * This method returns the maximum length of an index.
   *
   * @return The maximum length of an index.
   * @exception SQLException If an error occurs.
   */
  int getMaxIndexLength() throws SQLException;

  /**
   * This method returns the maximum length of a schema name.
   *
   * @return The maximum length of a schema name.
   * @exception SQLException If an error occurs.
   */
  int getMaxSchemaNameLength() throws SQLException;

  /**
   * This method returns the maximum length of a procedure name.
   *
   * @return The maximum length of a procedure name.
   * @exception SQLException If an error occurs.
   */
  int getMaxProcedureNameLength() throws SQLException;

  /**
   * This method returns the maximum length of a catalog name.
   *
   * @return The maximum length of a catalog name.
   * @exception SQLException If an error occurs.
   */
  int getMaxCatalogNameLength() throws SQLException;

  /**
   * This method returns the maximum size of a row in bytes.
   *
   * @return The maximum size of a row.
   * @exception SQLException If an error occurs.
   */
  int getMaxRowSize() throws SQLException;

  /**
   * This method tests whether or not the maximum row size includes BLOB's
   *
   * @return <code>true</code> if the maximum row size includes BLOB's,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean doesMaxRowSizeIncludeBlobs() throws SQLException;

  /**
   * This method includes the maximum length of a SQL statement.
   *
   * @return The maximum length of a SQL statement.
   * @exception SQLException If an error occurs.
   */
  int getMaxStatementLength() throws SQLException;

  /**
   * This method returns the maximum number of statements that can be
   * active at any time.
   *
   * @return The maximum number of statements that can be active at any time.
   * @exception SQLException If an error occurs.
   */
  int getMaxStatements() throws SQLException;

  /**
   * This method returns the maximum length of a table name.
   *
   * @return The maximum length of a table name.
   * @exception SQLException If an error occurs.
   */
  int getMaxTableNameLength() throws SQLException;

  /**
   * This method returns the maximum number of tables that may be referenced
   * in a SELECT statement.
   *
   * @return The maximum number of tables allowed in a SELECT statement.
   * @exception SQLException If an error occurs.
   */
  int getMaxTablesInSelect() throws SQLException;

  /**
   * This method returns the maximum length of a user name.
   *
   * @return The maximum length of a user name.
   * @exception SQLException If an error occurs.
   */
  int getMaxUserNameLength() throws SQLException;

  /**
   * This method returns the default transaction isolation level of the
   * database.
   *
   * @return The default transaction isolation level of the database.
   * @exception SQLException If an error occurs.
   * @see Connection
   */
  int getDefaultTransactionIsolation() throws SQLException;

  /**
   * This method tests whether or not the database supports transactions.
   *
   * @return <code>true</code> if the database supports transactions,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsTransactions() throws SQLException;

  /**
   * This method tests whether or not the database supports the specified
   * transaction isolation level.
   *
   * @param level The transaction isolation level.
   *
   * @return <code>true</code> if the specified transaction isolation level
   *         is supported, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsTransactionIsolationLevel(int level) throws
      SQLException;

  /**
   * This method tests whether or not DDL and DML statements allowed within 
   * the same transaction.
   *
   * @return <code>true</code> if DDL and DML statements are allowed in the
   *         same transaction, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsDataDefinitionAndDataManipulationTransactions()
      throws SQLException;

  /**
   * This method tests whether or not only DML statement are allowed
   * inside a transaction.
   *
   * @return <code>true</code> if only DML statements are allowed in
   *         transactions, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsDataManipulationTransactionsOnly() throws
      SQLException;

  /**
   * This method tests whether or not a DDL statement will cause the
   * current transaction to be automatically committed.
   *
   * @return <code>true</code> if DDL causes an immediate transaction commit,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean dataDefinitionCausesTransactionCommit() throws SQLException;

  /**
   * This method tests whether or not DDL statements are ignored in
   * transactions.
   *
   * @return <code>true</code> if DDL statements are ignored in transactions,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean dataDefinitionIgnoredInTransactions() throws SQLException;

  /**
   * This method returns a list of all the stored procedures matching the
   * specified pattern in the given schema and catalog.  This is returned
   * a <code>ResultSet</code> with the following columns:
   * <p>
   * <ol>
   * <li>PROCEDURE_CAT - The catalog the procedure is in, which may be 
   * <code>null</code>.</li>
   * <li>PROCEDURE_SCHEM - The schema the procedures is in, which may be
   * <code>null</code>.</li>
   * <li>PROCEDURE_NAME - The name of the procedure.</li>
   * <li>Unused</li>
   * <li>Unused</li>
   * <li>Unused</li>
   * <li>REMARKS - A description of the procedure</li>
   * <li>PROCEDURE_TYPE - Indicates the return type of the procedure, which 
   * is one of the contstants defined in this class 
   * (<code>procedureResultUnknown</code>, <code>procedureNoResult</code>, or
   * <code>procedureReturnsResult</code>).</li>
   * </ol>
   *
   * @param catalog The name of the catalog to return stored procedured from,
   *        or "" to return procedures from all catalogs.
   * @param schemaPattern A schema pattern for the schemas to return stored
   *        procedures from, or "" to return procedures from all schemas.
   * @param procedurePattern The pattern of procedure names to return.
   * @returns A <code>ResultSet</code> with all the requested procedures.
   * @exception SQLException If an error occurs.
   */
  ResultSet getProcedures(String catalog, String schemaPattern, String
      procedurePattern) throws SQLException;

  /**
   * This method returns a list of the parameter and result columns for
   * the requested stored procedures.  This is returned in the form of a
   * <code>ResultSet</code> with the following columns:
   * <p>
   * <ol>
   * <li>PROCEDURE_CAT - The catalog the procedure is in, which may be 
   * <code>null</code>.</li>
   * <li>PROCEDURE_SCHEM - The schema the procedures is in, which may be
   * <code>null</code>.</li>
   * <li>PROCEDURE_NAME - The name of the procedure.</li>
   * <li>COLUMN_NAME - The name of the column</li>
   * <li>COLUMN_TYPE - The type of the column, which will be one of the
   * contants defined in this class (<code>procedureColumnUnknown</code>,
   * <code>procedureColumnIn</code>, <code>procedureColumnInOut</code>,
   * <code>procedureColumnOut</code>, <code>procedureColumnReturn</code>,
   * or <code>procedureColumnResult</code>).</li>
   * <li>DATA_TYPE - The SQL type of the column. This is one of the constants
   * defined in <code>Types</code>.</li>
   * <li>TYPE_NAME - The string name of the data type for this column.</li>
   * <li>PRECISION - The precision of the column.</li>
   * <li>LENGTH - The length of the column in bytes</li>
   * <li>SCALE - The scale of the column.</li>
   * <li>RADIX - The radix of the column.</li>
   * <li>NULLABLE - Whether or not the column is NULLABLE.  This is one of
   * the constants defined in this class (<code>procedureNoNulls</code>,
   * <code>procedureNullable</code>, or <code>procedureNullableUnknown</code>)</li>
   * <li>REMARKS - A description of the column.</li>
   * </ol>
   *
   * @param catalog The name of the catalog to return stored procedured from,
   *        or "" to return procedures from all catalogs.
   * @param schemaPattern A schema pattern for the schemas to return stored
   *        procedures from, or "" to return procedures from all schemas.
   * @param procedurePattern The pattern of procedures names to return.
   * @param columnPattern The pattern of column names to return.
   * @returns A <code>ResultSet</code> with all the requested procedures.
   * @exception SQLException If an error occurs.
   */
  ResultSet getProcedureColumns(String catalog, String schemaPattern,
      String procedurePattern, String columnPattern) throws
      SQLException;

  /**
   * This method returns a list of the requested table as a   
   * <code>ResultSet</code> with the following columns:
   *
   * <ol>
   * <li>TABLE_CAT - The catalog the table is in, which may be <code>null</code>.</li>
   * <li>TABLE_SCHEM - The schema the table is in, which may be <code>null</code>.</li>
   * <li>TABLE_NAME - The name of the table.</li>
   * <li>TABLE_TYPE - A string describing the table type.  This will be one
   * of the values returned by the <code>getTableTypes()</code> method.</li>
   * <li>REMARKS - Comments about the table.</li>
   * </ol>
   * 
   * @param catalog The name of the catalog to return tables from,
   *        or "" to return tables from all catalogs.
   * @param schemaPattern A schema pattern for the schemas to return tables
   *        from, or "" to return tables from all schemas.
   * @param tablePattern The pattern of table names to return.
   * @param types The list of table types to include; null returns all types.
   * @returns A <code>ResultSet</code> with all the requested tables.
   * @exception SQLException If an error occurs.
   */
  ResultSet getTables(String catalog, String schemaPattern, String
      tablePattern, String[] types) throws SQLException;

  /**
   * This method returns the list of database schemas as a 
   * <code>ResultSet</code>, with one column - TABLE_SCHEM - that is the
   * name of the schema.
   *
   * @return A <code>ResultSet</code> with all the requested schemas.
   * @exception SQLException If an error occurs.
   */
  ResultSet getSchemas() throws SQLException;

  /**
   * This method returns the list of database catalogs as a
   * <code>ResultSet</code> with one column - TABLE_CAT - that is the
   * name of the catalog.
   *
   * @return A <code>ResultSet</code> with all the requested catalogs.
   * @exception SQLException If an error occurs.
   */
  ResultSet getCatalogs() throws SQLException;

  /**
   * This method returns the list of database table types as a
   * <code>ResultSet</code> with one column - TABLE_TYPE - that is the
   * name of the table type.
   *
   * @return A <code>ResultSet</code> with all the requested table types.
   * @exception SQLException If an error occurs.
   */
  ResultSet getTableTypes() throws SQLException;

  /**
   * This method returns a list of the tables columns for
   * the requested tables.  This is returned in the form of a
   * <code>ResultSet</code> with the following columns:
   * <p>
   * <ol>
   * <li>TABLE_CAT - The catalog the table is in, which may be 
   * <code>null</code>.</li>
   * <li>TABLE_SCHEM - The schema the tables is in, which may be
   * <code>null</code>.</li>
   * <li>TABLE_NAME - The name of the table.</li>
   * <li>COLUMN_NAME - The name of the column</li>
   * <li>DATA_TYPE - The SQL type of the column. This is one of the constants
   * defined in <code>Types</code>.</li>
   * <li>TYPE_NAME - The string name of the data type for this column.</li>
   * <li>COLUMN_SIZE - The size of the column.</li>
   * <li>Unused</li>
   * <li>NUM_PREC_RADIX - The radix of the column.</li>
   * <li>NULLABLE - Whether or not the column is NULLABLE.  This is one of
   * the constants defined in this class (<code>tableNoNulls</code>,
   * <code>tableNullable</code>, or <code>tableNullableUnknown</code>)</li>
   * <li>REMARKS - A description of the column.</li>
   * <li>COLUMN_DEF - The default value for the column, may be <code>null</code>.</li>
   * <li>SQL_DATA_TYPE - Unused</li>
   * <li>SQL_DATETIME_SUB - Unused</li>
   * <li>CHAR_OCTET_LENGTH - For character columns, the maximum number of bytes
   * in the column.</li>
   * <li>ORDINAL_POSITION - The index of the column in the table.</li>
   * <li>IS_NULLABLE - "NO" means no, "YES" means maybe, and an empty string
   * means unknown.</li>
   * </ol>
   *
   * @param catalog The name of the catalog to return table from,
   * or "" to return tables from all catalogs.
   * @param schemaPattern A schema pattern for the schemas to return 
   * tables from, or "" to return tables from all schemas.
   * @param tablePattern The pattern of table names to return.
   * @param columnPattern The pattern of column names to return.
   * @returns A <code>ResultSet</code> with all the requested tables.
   * @exception SQLException If an error occurs.
   */
  ResultSet getColumns(String catalog, String schemaPattern, String
      tablePattern, String columnPattern) throws SQLException;

  /**
   * This method returns the access rights that have been granted to the
   * requested columns.  This information is returned as a <code>ResultSet</code>
   * with the following columns:
   *
   * <ol>
   * <li>TABLE_CAT - The catalog the table is in, which may be 
   * <code>null</code>.</li>
   * <li>TABLE_SCHEM - The schema the tables is in, which may be
   * <code>null</code>.</li>
   * <li>TABLE_NAME - The name of the table.</li>
   * <li>COLUMN_NAME - The name of the column.</li>
   * <li>GRANTOR - The entity that granted the access.</li>
   * <li>GRANTEE - The entity granted the access.</li>
   * <li>PRIVILEGE - The name of the privilege granted.</li>
   * <li>IS_GRANTABLE - "YES" if the grantee can grant the privilege to
   * others, "NO" if not, and <code>null</code> if unknown.</li>
   * </ol>
   *
   * @param catalog The catalog to retrieve information from, or the empty string
   *        to return entities not associated with a catalog, or <code>null</code>
   *        to return information from all catalogs.
   * @param schema The schema to retrieve information from, or the empty string
   *        to return entities not associated with a schema.
   * @param tableName The table name to return information for.
   * @param columnPattern A pattern of column names to return information for.
   * @return A <code>ResultSet</code> with all the requested privileges.
   * @exception SQLException If an error occurs.
   */
  ResultSet getColumnPrivileges(String catalog, String schema, String
      tableName, String columnPattern) throws SQLException;

  /**
   * This method returns the access rights that have been granted to the
   * requested tables.  This information is returned as a <code>ResultSet</code>
   * with the following columns:
   *
   * <ol>
   * <li>TABLE_CAT - The catalog the table is in, which may be 
   * <code>null</code>.</li>
   * <li>TABLE_SCHEM - The schema the tables is in, which may be
   * <code>null</code>.</li>
   * <li>TABLE_NAME - The name of the table.</li>
   * <li>GRANTOR - The entity that granted the access.</li>
   * <li>GRANTEE - The entity granted the access.</li>
   * <li>PRIVILEGE - The name of the privilege granted.</li>
   * <li>IS_GRANTABLE - "YES" if the grantee can grant the privilege to
   * others, "NO" if not, and <code>null</code> if unknown.</li>
   * </ol>
   *
   * @param catalog The catalog to retrieve information from, or the empty string
   *        to return entities not associated with a catalog, or <code>null</code>
   *        to return information from all catalogs.
   * @param schemaPattern The schema to retrieve information from, or the empty string
   *        to return entities not associated with a schema.
   * @param tablePattern The table name pattern of tables to return 
   *        information for.
   * @return A <code>ResultSet</code> with all the requested privileges.
   * @exception SQLException If an error occurs.
   */
  ResultSet getTablePrivileges(String catalog, String schemaPattern,
      String tablePattern) throws SQLException;

  /**
   * This method returns the best set of columns for uniquely identifying
   * a row.  It returns this information as a <code>ResultSet</code> with
   * the following columns:
   *
   * <ol>
   * <li>SCOPE - The scope of the results returned.  This is one of the 
   * constants defined in this class (<code>bestRowTemporary</code>,
   * <code>bestRowTransaction</code>, or <code>bestRowSession</code>).</li>
   * <li>COLUMN_NAME - The name of the column.</li>
   * <li>DATA_TYPE - The SQL type of the column. This is one of the constants
   * defined in <code>Types</code>.</li>
   * <li>TYPE_NAME - The string name of the data type for this column.</li>
   * <li>COLUMN_SIZE - The precision of the columns</li>
   * <li>BUFFER_LENGTH - Unused</li>
   * <li>DECIMAL_DIGITS - The scale of the column.</li>
   * <li>PSEUDO_COLUMN - Whether or not the best row identifier is a
   * pseudo_column.  This is one of the constants defined in this class 
   * (<code>bestRowUnknown</code>, <code>bestRowNotPseudo</code>, or
   * <code>bestRowPseudo</code>).</li>
   * </ol>
   *
   * @param catalog The catalog to retrieve information from, or the empty string
   * to return entities not associated with a catalog, or <code>null</code>
   * to return information from all catalogs.
   * @param schema The schema to retrieve information from, or the empty string
   * to return entities not associated with a schema.
   * @param tableName The table name to return information for.
   * @param scope One of the best row id scope constants from this class.
   * @param nullable <code>true</code> to include columns that are nullable,
   * <code>false</code> otherwise.
   * @return A <code>ResultSet</code> with the best row identifier.
   * @exception SQLException If an error occurs.
   */
  ResultSet getBestRowIdentifier(String catalog, String schema,
    String tableName, int scope, boolean nullable) throws SQLException;

  /**
   * This method returns the set of columns that are automatically updated
   * when the row is update. It returns this information as a 
   * <code>ResultSet</code> with the following columns:
   *
   * <ol>
   * <li>SCOPE - Unused</li>
   * <li>COLUMN_NAME - The name of the column.</li>
   * <li>DATA_TYPE - The SQL type of the column. This is one of the constants
   * defined in <code>Types</code>.</li>
   * <li>TYPE_NAME - The string name of the data type for this column.</li>
   * <li>COLUMN_SIZE - The precision of the columns</li>
   * <li>BUFFER_LENGTH - Unused</li>
   * <li>DECIMAL_DIGITS - The scale of the column.</li>
   * <li>PSEUDO_COLUMN - Whether or not the best row identifier is a
   * pseudo_column.  This is one of the constants defined in this class 
   * (<code>versionRowUnknown</code>, <code>versionRowNotPseudo</code>, or
   * <code>versionRowPseudo</code>).</li>
   * </ol>
   *
   * @param catalog The catalog to retrieve information from, or the empty string
   *        to return entities not associated with a catalog, or <code>null</code>
   *        to return information from all catalogs.
   * @param schema The schema to retrieve information from, or the empty string
   *        to return entities not associated with a schema.
   * @param tableName The table name to return information for
   * @return A <code>ResultSet</code> with the version columns.
   * @exception SQLException If an error occurs.
   */
  ResultSet getVersionColumns(String catalog, String schema,
    String tableName) throws SQLException;

  /**
   * This method returns a list of a table's primary key columns.  These
   * are returned as a <code>ResultSet</code> with the following columns.
   *
   * <ol>
   * <li>TABLE_CAT - The catalog of the table, which may be <code>null</code>.</li>
   * <li>TABLE_SCHEM - The schema of the table, which may be <code>null</code>.</li>
   * <li>TABLE_NAME - The name of the table.</li>
   * <li>COLUMN_NAME - The name of the column.</li>
   * <li>KEY_SEQ - The sequence number of the column within the primary key.</li>
   * <li>PK_NAME - The name of the primary key, which may be <code>null</code>.</li>
   * </ol>
   *
   * @param catalog The catalog to retrieve information from, or the empty string
   *        to return entities not associated with a catalog, or <code>null</code>
   *        to return information from all catalogs.
   * @param schema The schema to retrieve information from, or the empty string
   *        to return entities not associated with a schema.
   * @param tableName The table name to return information for.
   * @return A <code>ResultSet</code> with the primary key columns.
   * @exception SQLException If an error occurs.
   */
  ResultSet getPrimaryKeys(String catalog, String schema, String tableName)
      throws SQLException;

  /**
   * This method returns a list of the table's foreign keys.  These are
   * returned as a <code>ResultSet</code> with the following columns:
   *
   * <ol>
   * <li>PKTABLE_CAT - The catalog of the table the key was imported from.</li>
   * <li>PKTABLE_SCHEM - The schema of the table the key was imported from.</li>
   * <li>PKTABLE_NAME - The name of the table the key was imported from.</li>
   * <li>PKCOLUMN_NAME - The name of the column that was imported.</li>
   * <li>FKTABLE_CAT - The foreign key catalog name.</li>
   * <li>FKTABLE_SCHEM - The foreign key schema name.</li>
   * <li>FKTABLE_NAME - The foreign key table name.</li>
   * <li>FKCOLUMN_NAME - The foreign key column name.</li>
   * <li>KEY_SEQ - The sequence number of the column within the foreign key.</li>
   * <li>UPDATE_RULE - How the foreign key behaves when the primary key is
   * updated.  This is one of the constants defined in this class 
   * (<code>importedNoAction</code>, <code>importedKeyCascade</code>,
   * <code>importedKeySetNull</code>, <code>importedKeySetDefault</code>, or
   * <code>importedKeyRestrict</code>).</li>
   * <li>DELETE_RULE - How the foreign key behaves when the primary key is
   * deleted.  This is one of the constants defined in this class 
   * (<code>importedNoAction</code>, <code>importedKeyCascade</code>,
   * <code>importedKeySetNull</code>, or <code>importedKeySetDefault</code>)</li>
   * <li>FK_NAME - The name of the foreign key.</li>
   * <li>PK_NAME - The name of the primary key.</li>
   * <li>DEFERRABILITY - The deferrability value.  This is one of the
   * constants defined in this table (<code>importedKeyInitiallyDeferred</code>,
   * <code>importedKeyInitiallyImmediate</code>, or
   * <code>importedKeyNotDeferrable</code>).</li>
   * </ol>
   *
   * @param catalog The catalog to retrieve information from, or the empty string
   *        to return entities not associated with a catalog, or <code>null</code>
   *        to return information from all catalogs.
   * @param schema The schema to retrieve information from, or the empty string
   *        to return entities not associated with a schema.
   * @param tableName The table name to return information for.
   * @return A <code>ResultSet</code> with the foreign key columns.
   * @exception SQLException If an error occurs.
   */
  ResultSet getImportedKeys(String catalog, String schema,
    String tableName) throws SQLException;

  /**
   * This method returns a list of the table's which use this table's
   * primary key as a foreign key.  The information is
   * returned as a <code>ResultSet</code> with the following columns:
   *
   * <ol>
   * <li>PKTABLE_CAT - The catalog of the table the key was imported from.</li>
   * <li>PKTABLE_SCHEM - The schema of the table the key was imported from.</li>
   * <li>PKTABLE_NAME - The name of the table the key was imported from.</li>
   * <li>PKCOLUMN_NAME - The name of the column that was imported.</li>
   * <li>FKTABLE_CAT - The foreign key catalog name.</li>
   * <li>FKTABLE_SCHEM - The foreign key schema name.</li>
   * <li>FKTABLE_NAME - The foreign key table name.</li>
   * <li>FKCOLUMN_NAME - The foreign key column name.</li>
   * <li>KEY_SEQ - The sequence number of the column within the foreign key.</li>
   * <li>UPDATE_RULE - How the foreign key behaves when the primary key is
   * updated.  This is one of the constants defined in this class 
   * (<code>importedNoAction</code>, <code>importedKeyCascade</code>,
   * <code>importedKeySetNull</code>, <code>importedKeySetDefault</code>, or
   * <code>importedKeyRestrict</code>).</li>
   * <li>DELETE_RULE - How the foreign key behaves when the primary key is
   * deleted.  This is one of the constants defined in this class 
   * (<code>importedNoAction</code>, <code>importedKeyCascade</code>,
   * <code>importedKeySetNull</code>, or <code>importedKeySetDefault</code>)</li>
   * <li>FK_NAME - The name of the foreign key.</li>
   * <li>PK_NAME - The name of the primary key.</li>
   * <li>DEFERRABILITY - The deferrability value.  This is one of the
   * constants defined in this table (<code>importedKeyInitiallyDeferred</code>,
   * <code>importedKeyInitiallyImmediate</code>, or
   * <code>importedKeyNotDeferrable</code>).</li>
   * </ol>
   *
   * @param catalog The catalog to retrieve information from, or the empty string
   *        to return entities not associated with a catalog, or <code>null</code>
   *        to return information from all catalogs.
   * @param schema The schema to retrieve information from, or the empty string
   *        to return entities not associated with a schema.
   * @param tableName The table name to return information for.
   * @return A <code>ResultSet</code> with the requested information
   * @exception SQLException If an error occurs.
   */
  ResultSet getExportedKeys(String catalog, String schema,
    String tableName) throws SQLException;

  /**
   * This method returns a description of how one table imports another
   * table's primary key as a foreign key.  The information is
   * returned as a <code>ResultSet</code> with the following columns:
   *
   * <ol>
   * <li>PKTABLE_CAT - The catalog of the table the key was imported from.</li>
   * <li>PKTABLE_SCHEM - The schema of the table the key was imported from.</li>
   * <li>PKTABLE_NAME - The name of the table the key was imported from.</li>
   * <li>PKCOLUMN_NAME - The name of the column that was imported.</li>
   * <li>FKTABLE_CAT - The foreign key catalog name.</li>
   * <li>FKTABLE_SCHEM - The foreign key schema name.</li>
   * <li>FKTABLE_NAME - The foreign key table name.</li>
   * <li>FKCOLUMN_NAME - The foreign key column name.</li>
   * <li>KEY_SEQ - The sequence number of the column within the foreign key.</li>
   * <li>UPDATE_RULE - How the foreign key behaves when the primary key is
   * updated.  This is one of the constants defined in this class 
   * (<code>importedNoAction</code>, <code>importedKeyCascade</code>,
   * <code>importedKeySetNull</code>, <code>importedKeySetDefault</code>, or
   * <code>importedKeyRestrict</code>).</li>
   * <li>DELETE_RULE - How the foreign key behaves when the primary key is
   * deleted.  This is one of the constants defined in this class 
   * (<code>importedNoAction</code>, <code>importedKeyCascade</code>,
   * <code>importedKeySetNull</code>, or <code>importedKeySetDefault</code>)</li>
   * <li>FK_NAME - The name of the foreign key.</li>
   * <li>PK_NAME - The name of the primary key.</li>
   * <li>DEFERRABILITY - The deferrability value.  This is one of the
   * constants defined in this table (<code>importedKeyInitiallyDeferred</code>,
   * <code>importedKeyInitiallyImmediate</code>, or
   * <code>importedKeyNotDeferrable</code>).</li>
   * </ol>
   *
   * @param primaryCatalog The catalog to retrieve information from, or the
   *        empty string to return entities not associated with a catalog, or
   *        <code>null</code> to return information from all catalogs, on the
   *         exporting side.
   * @param primarySchema The schema to retrieve information from, or the empty
   *        string to return entities not associated with a schema, on the
   *        exporting side.
   * @param primaryTableName The table name to return information for, on the
   *        exporting side.
   * @param foreignCatalog The catalog to retrieve information from, or the
   *        empty string to return entities not associated with a catalog,
   *        or <code>null</code> to return information from all catalogs, on
   *        the importing side.
   * @param foreignSchema The schema to retrieve information from, or the
   *        empty string to return entities not associated with a schema on
   *        the importing side.
   * @param foreignTableName The table name to return information for on the
   *        importing side.
   * @return A <code>ResultSet</code> with the requested information
   * @exception SQLException If an error occurs.
   */
  ResultSet getCrossReference(String primaryCatalog, String
    primarySchema, String primaryTableName, String foreignCatalog, String
    foreignSchema, String foreignTableName) throws SQLException;

  /**
   * This method returns a list of the SQL types supported by this
   * database.  The information is returned as a <code>ResultSet</code>
   * with the following columns:
   *
   * <ol>
   * <li>TYPE_NAME - The name of the data type.</li>
   * <li>DATA_TYPE - A data type constant from <code>Types</code> for this
   * type.</li>
   * <li>PRECISION - The maximum precision of this type.</li>
   * <li>LITERAL_PREFIX - Prefix value used to quote a literal, which may be
   * <code>null</code>.</li>
   * <li>LITERAL_SUFFIX - Suffix value used to quote a literal, which may be
   * <code>null</code>.</li>
   * <li>CREATE_PARAMS - The parameters used to create the type, which may be
   * <code>null</code>.</li>
   * <li>NULLABLE - Whether or not this type supports NULL values.  This will
   * be one of the constants defined in this interface 
   * (<code>typeNoNulls</code>, <code>typeNullable</code>, or
   * <code>typeNullableUnknown</code>).</li>
   * <li>CASE_SENSITIVE - Whether or not the value is case sensitive.</li>
   * <li>SEARCHABLE - Whether or not "LIKE" expressions are supported in
   * WHERE clauses for this type.  This will be one of the constants defined
   * in this interface (<code>typePredNone</code>, <code>typePredChar</code>,
   * <code>typePredBasic</code>, or <code>typeSearchable</code>).</li>
   * <li>UNSIGNED_ATTRIBUTE - Is the value of this type unsigned.</li>
   * <li>FIXED_PREC_SCALE - Whether or not this type can be used for money.</li>
   * <li>AUTO_INCREMENT - Whether or not this type supports auto-incrementing.</li>
   * <li>LOCAL_TYPE_NAME - A localized name for this data type.</li>
   * <li>MINIMUM_SCALE - The minimum scale supported by this type.</li>
   * <li>MAXIMUM_SCALE - The maximum scale supported by this type.</li>
   * <li>SQL_DATA_TYPE - Unused.</li>
   * <li>SQL_DATETIME_SUB - Unused.</li>
   * <li>NUM_PREC_RADIX - The radix of this data type.</li>
   * </ol>
   * 
   * @return A <code>ResultSet</code> with the list of available data types.
   * @exception SQLException If an error occurs.
   */
  ResultSet getTypeInfo() throws SQLException;

  /**
   * This method returns information about a tables indices and statistics.
   * It is returned as a <code>ResultSet</code> with the following columns:
   *
   * <ol>
   * <li>TABLE_CAT - The catalog of the table, which may be <code>null</code>.</li>
   * <li>TABLE_SCHEM - The schema of the table, which may be <code>null</code>.</li>
   * <li>TABLE_NAME - The name of the table.</li>
   * <li>NON_UNIQUE - Are index values non-unique?</li>
   * <li>INDEX_QUALIFIER The index catalog, which may be <code>null</code></li>
   * <li>INDEX_NAME - The name of the index.</li>
   * <li>TYPE - The type of index, which will be one of the constants defined
   * in this interface (<code>tableIndexStatistic</code>,
   * <code>tableIndexClustered</code>, <code>tableIndexHashed</code>, or
   * <code>tableIndexOther</code>).</li>
   * <li>ORDINAL_POSITION - The sequence number of this column in the index.
   * This will be 0 when the index type is <code>tableIndexStatistic</code>.</li>
   * <li>COLUMN_NAME - The name of this column in the index.</li>
   * <li>ASC_OR_DESC - "A" for an ascending sort sequence, "D" for a
   * descending sort sequence or <code>null</code> if a sort sequence is not
   * supported.</li>
   * <li>CARDINALITY - The number of unique rows in the index, or the number
   * of rows in the table if the index type is <code>tableIndexStatistic</code>.</li>
   * <li>PAGES - The number of pages used for the index, or the number of pages
   * in the table if the index type is <code>tableIndexStatistic</code>.</li>
   * <li>FILTER_CONDITION - The filter condition for this index, which may be
   * <code>null</code>.</li>
   * </ol>
   *
   * @param catalog The catalog to retrieve information from, or the empty string
   *        to return entities not associated with a catalog, or 
   *        <code>null</code> to return information from all catalogs.
   * @param schema The schema to retrieve information from, or the empty string
   *        to return entities not associated with a schema.
   * @param tableName The table name to return information for.
   * @param unique <code>true</code> to return only unique indexes, 
   *        <code>false</code> otherwise.
   * @param approximate <code>true</code> if data values can be approximations,
   *        <code>false</code> otherwise.
   * @return A <code>ResultSet</code> with the requested index information
   * @exception SQLException If an error occurs.
   */
  ResultSet getIndexInfo(String catalog, String schema, String tableName,
    boolean unique, boolean approximate) throws SQLException;

  /**
   * This method tests whether or not the datbase supports the specified
   * result type.
   *
   * @param type The desired result type, which is one of the constants
   * defined in <code>ResultSet</code>.
   *
   * @return <code>true</code> if the result set type is supported,
   * <code>false</code> otherwise.
   *
   * @exception SQLException If an error occurs.
   *
   * @see ResultSet
   */
  boolean supportsResultSetType(int type) throws SQLException;

  /**
   * This method tests whether the specified result set type and result set
   * concurrency type are supported by the database.
   *
   * @param type The desired result type, which is one of the constants
   *        defined in <code>ResultSet</code>.
   * @param concurrency The desired concurrency type, which is one of the
   *                    constants defined in <code>ResultSet</code>.
   * @return <code>true</code> if the result set type is supported,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   * @see ResultSet
   */
  boolean supportsResultSetConcurrency(int type, int concurrency)
      throws SQLException;

  /**
   * This method tests whether or not the specified result set type sees its
   * own updates.
   *
   * @param type The desired result type, which is one of the constants
   *        defined in <code>ResultSet</code>.
   * @return <code>true</code> if the result set type sees its own updates,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   * @see ResultSet
   */
  boolean ownUpdatesAreVisible(int type) throws SQLException;

 /**
   * This method tests whether or not the specified result set type sees its
   * own deletes.
   *
   * @param type The desired result type, which is one of the constants
   *        defined in <code>ResultSet</code>.
   * @return <code>true</code> if the result set type sees its own deletes,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   * @see ResultSet
   */
  boolean ownDeletesAreVisible(int type) throws SQLException;

  /**
   * This method tests whether or not the specified result set type sees its
   * own inserts.
   *
   * @param type The desired result type, which is one of the constants
   *        defined in <code>ResultSet</code>.
   * @return <code>true</code> if the result set type sees its own inserts,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   * @see ResultSet
   */
  boolean ownInsertsAreVisible(int type) throws SQLException;

  /**
   * This method tests whether or not the specified result set type sees 
   * updates committed by others.
   *
   * @param type The desired result type, which is one of the constants
   *        defined in <code>ResultSet</code>.
   * @return <code>true</code> if the result set type sees other updates,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   * @see ResultSet
   */
  boolean othersUpdatesAreVisible(int type) throws SQLException;

  /**
   * This method tests whether or not the specified result set type sees 
   * deletes committed by others.
   *
   * @param type The desired result type, which is one of the constants
   *        defined in <code>ResultSet</code>.
   * @return <code>true</code> if the result set type sees other deletes,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   * @see ResultSet
   */
  boolean othersDeletesAreVisible(int type) throws SQLException;

  /**
   * This method tests whether or not the specified result set type sees 
   * inserts committed by others.
   *
   * @param type The desired result type, which is one of the constants
   *        defined in <code>ResultSet</code>.
   * @return <code>true</code> if the result set type sees other inserts,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   * @see ResultSet
   */
  boolean othersInsertsAreVisible(int type) throws SQLException;

  /**
   * This method tests whether or not the specified result set type can detect
   * a visible update by calling the <code>rowUpdated</code> method.
   *
   * @param type The desired result type, which is one of the constants
   *        defined in <code>ResultSet</code>.
   * @return <code>true</code> if the result set type can detect visible updates
   *         using <code>rowUpdated</code>, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   * @see ResultSet
   */
  boolean updatesAreDetected(int type) throws SQLException;

  /**
   * This method tests whether or not the specified result set type can detect
   * a visible delete by calling the <code>rowUpdated</code> method.
   *
   * @param type The desired result type, which is one of the constants
   *        defined in <code>ResultSet</code>.
   * @return <code>true</code> if the result set type can detect visible deletes
   *         using <code>rowUpdated</code>, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   * @see ResultSet
   */
  boolean deletesAreDetected(int type) throws SQLException;
  
  /**
   * This method tests whether or not the specified result set type can detect
   * a visible insert by calling the <code>rowUpdated</code> method.
   *
   * @param type The desired result type, which is one of the constants
   *        defined in <code>ResultSet</code>.
   * @return <code>true</code> if the result set type can detect visible inserts
   *         using <code>rowUpdated</code>, <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   * @see ResultSet
   */
  boolean insertsAreDetected(int type) throws SQLException;

  /**
   * This method tests whether or not the database supports batch updates.
   *
   * @return <code>true</code> if batch updates are supported,
   *         <code>false</code> otherwise.
   * @exception SQLException If an error occurs.
   */
  boolean supportsBatchUpdates() throws SQLException;

  /**
   * This method returns the list of user defined data types in use.  These
   * are returned as a <code>ResultSet</code> with the following columns:
   *
   * <ol>
   * <li>TYPE_CAT - The catalog name, which may be <code>null</code>.</li>
   * <li>TYPE_SCEHM - The schema name, which may be <code>null</code>.</li>
   * <li>TYPE_NAME - The user defined data type name.</li>
   * <li>CLASS_NAME - The Java class name this type maps to.</li>
   * <li>DATA_TYPE - A type identifier from <code>Types</code> for this type.
   * This will be one of <code>JAVA_OBJECT</code>, <code>STRUCT</code>, or
   * <code>DISTINCT</code>.</li>
   * <li>REMARKS - Comments about this data type.</li>
   * </ol>
   *
   * @param catalog The catalog to retrieve information from, or the empty string
   *        to return entities not associated with a catalog, or <code>null</code>
   *        to return information from all catalogs.
   * @param schemaPattern The schema to retrieve information from, or the
   *        empty string to return entities not associated with a schema.
   * @param typePattern The type name pattern to match.
   * @param types The type identifier patterns (from <code>Types</code>) to
   *        match.
   * @return A <code>ResultSet</code> with the requested type information
   * @exception SQLException If an error occurs.
   */
  ResultSet getUDTs(String catalog, String schemaPattern, String
      typePattern, int[] types) throws SQLException;

  /**
   * This method returns the <code>Connection</code> object that was used
   * to generate the metadata in this object.
   *
   * @return The connection for this object.
   * @exception SQLException If an error occurs.
   */
  Connection getConnection() throws SQLException;

  /**
   * This method tests whether the databse supports savepoints.
   * 
   * @return <code>true</code> if the database supports savepoints,
   *         <code>false</code> if it does not.
   * @exception SQLException If an error occurs.
   * @see Savepoint
   * @since 1.4
   */
  boolean supportsSavepoints() throws SQLException;

  /**
   * This method tests whether the database supports named parameters.
   * 
   * @return <code>true</code> if the database supports named parameters,
   *         <code>false</code> if it does not.
   * @exception SQLException If an error occurs.
   * @since 1.4
   */
  boolean supportsNamedParameters() throws SQLException;

  /**
   * This method tests whether the database supports returning multiple
   * <code>ResultSet</code>S from a <code>CallableStatement</code> at once.
   * 
   * @return <code>true</code> if the database supports returnig multiple
   *         results at once, <code>false</code> if it does not.
   * @exception SQLException If an error occurs.
   * @since 1.4
   */
  boolean supportsMultipleOpenResults() throws SQLException;

  /**
   * @since 1.4
   */
  boolean supportsGetGeneratedKeys() throws SQLException;

  /**
   * @since 1.4
   */
  ResultSet getSuperTypes(String catalog, String schemaPattern,
    String typePattern) throws SQLException;

  /**
   * @since 1.4
   */
  ResultSet getSuperTables(String catalog, String schemaPattern,
    String tablePattern) throws SQLException;

  /**
   * @since 1.4
   */
  ResultSet getAttributes(String catalog, String schemaPattern, String
    typePattern, String attributePattern) throws SQLException;

  /**
   * This method tests if the database supports the specified holdability type.
   * Valid values for this parameter are specified in the
   * <code>ResultSet</code> class.
   * 
   * @param holdability The holdability type to test.
   * @return <code>true</code> if the database supports the holdability type,
   *         <code>false</code> if it does not.
   * @exception SQLException If an error occurs.
   * @see ResultSet
   * @since 1.4
   */
  boolean supportsResultSetHoldability(int holdability)
    throws SQLException;

  /**
   * This method returns the default holdability type of <code>ResultSet</code>S
   * retrieved from this database. The possible values are specified in the
   * <code>ResultSet</code> class.
   * 
   * @return The default holdability type.
   * @exception SQLException If an error occurs.
   * @since 1.4
   */
  int getResultSetHoldability() throws SQLException;

  /**
   * This method returns the major version number of the database.
   * 
   * @return The major version number of the database.
   * @exception SQLException If an error occurs.
   * @since 1.4
   */
  int getDatabaseMajorVersion() throws SQLException;

  /**
   * This method returns the minor version number of the database.
   * 
   * @return The minor version number of the database.
   * @exception SQLException If an error occurs.
   * @since 1.4
   */
  int getDatabaseMinorVersion() throws SQLException;

  /**
   * This method returns the major version number of the JDBC driver.
   * 
   * @return The major version number of the JDBC driver.
   * @exception  SQLException If an error occurs.
   * @since 1.4
   */
  int getJDBCMajorVersion() throws SQLException;

  /**
   * This method returns the minor version number of the JDBC driver.
   * 
   * @return The minor version number of the database.
   * @exception SQLException If an error occurs.
   * @since 1.4
   */
  int getJDBCMinorVersion() throws SQLException;

  /**
   * @since 1.4
   */
  int getSQLStateType() throws SQLException;

  /**
   * @since 1.4
   */
  boolean locatorsUpdateCopy() throws SQLException;

  /**
   * @since 1.4
   */
  boolean supportsStatementPooling() throws SQLException;
}
