EMMA Coverage Report (generated Wed Jun 28 22:15:27 PDT 2006)
[all classes][org.apache.derby.impl.jdbc]

COVERAGE SUMMARY FOR SOURCE FILE [EmbedDatabaseMetaData.java]

nameclass, %method, %block, %line, %
EmbedDatabaseMetaData.java100% (1/1)97%  (185/191)93%  (1329/1434)93%  (386/416)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class EmbedDatabaseMetaData100% (1/1)97%  (185/191)93%  (1329/1434)93%  (386/416)
EmbedDatabaseMetaData (EmbedConnection, String): void 100% (1/1)100% (7/7)100% (3/3)
PBloadQueryDescriptions (): Properties 100% (1/1)94%  (17/18)86%  (6/7)
allProceduresAreCallable (): boolean 100% (1/1)100% (2/2)100% (1/1)
allTablesAreSelectable (): boolean 100% (1/1)100% (2/2)100% (1/1)
dataDefinitionCausesTransactionCommit (): boolean 100% (1/1)100% (2/2)100% (1/1)
dataDefinitionIgnoredInTransactions (): boolean 100% (1/1)100% (2/2)100% (1/1)
deletesAreDetected (int): boolean 100% (1/1)100% (2/2)100% (1/1)
doGetBestRowId (String, String, String, int, boolean, String): ResultSet 100% (1/1)99%  (238/240)99%  (66/67)
doGetCols (String, String, String, String, String): ResultSet 100% (1/1)100% (27/27)100% (6/6)
doGetIndexInfo (String, String, String, boolean, boolean, String): ResultSet 100% (1/1)94%  (34/36)96%  (8.7/9)
doGetPrimaryKeys (String, String, String, String): ResultSet 100% (1/1)100% (22/22)100% (5/5)
doGetProcCols (String, String, String, String, String): ResultSet 100% (1/1)100% (22/22)100% (5/5)
doGetProcs (String, String, String, String): ResultSet 100% (1/1)100% (22/22)100% (5/5)
doGetVersionCols (String, String, String, String): ResultSet 100% (1/1)100% (22/22)100% (5/5)
doesMaxRowSizeIncludeBlobs (): boolean 100% (1/1)100% (2/2)100% (1/1)
getAttributes (String, String, String, String): ResultSet 100% (1/1)100% (2/2)100% (1/1)
getBestRowIdentifier (String, String, String, int, boolean): ResultSet 100% (1/1)100% (9/9)100% (1/1)
getBestRowIdentifierForODBC (String, String, String, int, boolean): ResultSet 100% (1/1)100% (9/9)100% (1/1)
getCatalogSeparator (): String 100% (1/1)100% (2/2)100% (1/1)
getCatalogTerm (): String 100% (1/1)100% (2/2)100% (1/1)
getCatalogs (): ResultSet 100% (1/1)100% (4/4)100% (1/1)
getColumnPrivileges (String, String, String, String): ResultSet 100% (1/1)100% (27/27)100% (6/6)
getColumns (String, String, String, String): ResultSet 100% (1/1)100% (8/8)100% (1/1)
getColumnsForODBC (String, String, String, String): ResultSet 100% (1/1)100% (8/8)100% (1/1)
getConnection (): Connection 100% (1/1)100% (4/4)100% (1/1)
getCrossReference (String, String, String, String, String, String): ResultSet 100% (1/1)100% (37/37)100% (8/8)
getDatabaseMajorVersion (): int 100% (1/1)80%  (8/10)75%  (3/4)
getDatabaseMinorVersion (): int 100% (1/1)80%  (8/10)75%  (3/4)
getDatabaseProductName (): String 100% (1/1)100% (4/4)100% (1/1)
getDatabaseProductVersion (): String 100% (1/1)100% (7/7)100% (2/2)
getDefaultTransactionIsolation (): int 100% (1/1)100% (2/2)100% (1/1)
getDriverMajorVersion (): int 100% (1/1)100% (5/5)100% (1/1)
getDriverMinorVersion (): int 100% (1/1)100% (5/5)100% (1/1)
getDriverName (): String 100% (1/1)100% (2/2)100% (1/1)
getDriverVersion (): String 100% (1/1)100% (3/3)100% (1/1)
getExportedKeys (String, String, String): ResultSet 100% (1/1)100% (37/37)100% (8/8)
getExtraNameCharacters (): String 100% (1/1)100% (2/2)100% (1/1)
getGenericConstantActionFactory (): GenericConstantActionFactory 0%   (0/1)0%   (0/16)0%   (0/4)
getIdentifierQuoteString (): String 100% (1/1)100% (2/2)100% (1/1)
getImportedKeys (String, String, String): ResultSet 100% (1/1)100% (22/22)100% (5/5)
getIndexInfo (String, String, String, boolean, boolean): ResultSet 100% (1/1)100% (9/9)100% (1/1)
getIndexInfoForODBC (String, String, String, boolean, boolean): ResultSet 100% (1/1)100% (9/9)100% (1/1)
getJDBCMajorVersion (): int 100% (1/1)100% (2/2)100% (1/1)
getJDBCMinorVersion (): int 100% (1/1)100% (2/2)100% (1/1)
getLanguageConnectionContext (): LanguageConnectionContext 100% (1/1)100% (4/4)100% (1/1)
getMaxBinaryLiteralLength (): int 100% (1/1)100% (2/2)100% (1/1)
getMaxCatalogNameLength (): int 100% (1/1)100% (2/2)100% (1/1)
getMaxCharLiteralLength (): int 100% (1/1)100% (2/2)100% (1/1)
getMaxColumnNameLength (): int 100% (1/1)100% (2/2)100% (1/1)
getMaxColumnsInGroupBy (): int 100% (1/1)100% (2/2)100% (1/1)
getMaxColumnsInIndex (): int 100% (1/1)100% (2/2)100% (1/1)
getMaxColumnsInOrderBy (): int 100% (1/1)100% (2/2)100% (1/1)
getMaxColumnsInSelect (): int 100% (1/1)100% (2/2)100% (1/1)
getMaxColumnsInTable (): int 100% (1/1)100% (2/2)100% (1/1)
getMaxConnections (): int 100% (1/1)100% (2/2)100% (1/1)
getMaxCursorNameLength (): int 100% (1/1)100% (2/2)100% (1/1)
getMaxIndexLength (): int 100% (1/1)100% (2/2)100% (1/1)
getMaxProcedureNameLength (): int 100% (1/1)100% (2/2)100% (1/1)
getMaxRowSize (): int 100% (1/1)100% (2/2)100% (1/1)
getMaxSchemaNameLength (): int 100% (1/1)100% (2/2)100% (1/1)
getMaxStatementLength (): int 100% (1/1)100% (2/2)100% (1/1)
getMaxStatements (): int 100% (1/1)100% (2/2)100% (1/1)
getMaxTableNameLength (): int 100% (1/1)100% (2/2)100% (1/1)
getMaxTablesInSelect (): int 100% (1/1)100% (2/2)100% (1/1)
getMaxUserNameLength (): int 100% (1/1)100% (2/2)100% (1/1)
getNumericFunctions (): String 100% (1/1)100% (2/2)100% (1/1)
getPreparedQuery (String): PreparedStatement 100% (1/1)72%  (33/46)74%  (9.6/13)
getPrimaryKeys (String, String, String): ResultSet 100% (1/1)100% (7/7)100% (1/1)
getPrimaryKeysForODBC (String, String, String): ResultSet 100% (1/1)100% (7/7)100% (1/1)
getProcedureColumns (String, String, String, String): ResultSet 100% (1/1)100% (8/8)100% (1/1)
getProcedureColumnsForODBC (String, String, String, String): ResultSet 100% (1/1)100% (8/8)100% (1/1)
getProcedureTerm (): String 100% (1/1)100% (2/2)100% (1/1)
getProcedures (String, String, String): ResultSet 100% (1/1)100% (7/7)100% (1/1)
getProceduresForODBC (String, String, String): ResultSet 100% (1/1)100% (7/7)100% (1/1)
getQueryDescriptions (): Properties 100% (1/1)100% (11/11)100% (4/4)
getResultSetHoldability (): int 100% (1/1)100% (2/2)100% (1/1)
getSQLKeywords (): String 100% (1/1)100% (2/2)100% (1/1)
getSQLStateType (): int 100% (1/1)100% (2/2)100% (1/1)
getSchemaTerm (): String 100% (1/1)100% (2/2)100% (1/1)
getSchemas (): ResultSet 100% (1/1)100% (4/4)100% (1/1)
getSearchStringEscape (): String 100% (1/1)100% (2/2)100% (1/1)
getSimpleQuery (String): ResultSet 100% (1/1)82%  (9/11)75%  (3/4)
getStringFunctions (): String 100% (1/1)100% (2/2)100% (1/1)
getSuperTables (String, String, String): ResultSet 100% (1/1)100% (2/2)100% (1/1)
getSuperTypes (String, String, String): ResultSet 100% (1/1)100% (2/2)100% (1/1)
getSystemFunctions (): String 100% (1/1)100% (2/2)100% (1/1)
getTablePrivileges (String, String, String): ResultSet 100% (1/1)100% (22/22)100% (5/5)
getTableTypes (): ResultSet 100% (1/1)100% (4/4)100% (1/1)
getTables (String, String, String, String []): ResultSet 100% (1/1)87%  (98/113)87%  (20.9/24)
getTimeDateFunctions (): String 100% (1/1)100% (2/2)100% (1/1)
getTypeInfo (): ResultSet 100% (1/1)100% (4/4)100% (1/1)
getTypeInfoForODBC (): ResultSet 100% (1/1)100% (4/4)100% (1/1)
getUDTs (String, String, String, int []): ResultSet 100% (1/1)88%  (76/86)95%  (19.9/21)
getURL (): String 100% (1/1)87%  (20/23)83%  (5/6)
getUserName (): String 100% (1/1)100% (5/5)100% (1/1)
getVersionColumns (String, String, String): ResultSet 100% (1/1)100% (7/7)100% (1/1)
getVersionColumnsForODBC (String, String, String): ResultSet 100% (1/1)100% (7/7)100% (1/1)
insertsAreDetected (int): boolean 0%   (0/1)0%   (0/2)0%   (0/1)
isCatalogAtStart (): boolean 100% (1/1)100% (2/2)100% (1/1)
isReadOnly (): boolean 100% (1/1)100% (5/5)100% (1/1)
loadQueryDescriptions (): Properties 100% (1/1)100% (4/4)100% (1/1)
locatorsUpdateCopy (): boolean 100% (1/1)100% (2/2)100% (1/1)
nullPlusNonNullIsNull (): boolean 100% (1/1)100% (2/2)100% (1/1)
nullsAreSortedAtEnd (): boolean 100% (1/1)100% (2/2)100% (1/1)
nullsAreSortedAtStart (): boolean 100% (1/1)100% (2/2)100% (1/1)
nullsAreSortedHigh (): boolean 100% (1/1)100% (2/2)100% (1/1)
nullsAreSortedLow (): boolean 100% (1/1)100% (2/2)100% (1/1)
othersDeletesAreVisible (int): boolean 100% (1/1)100% (7/7)100% (3/3)
othersInsertsAreVisible (int): boolean 100% (1/1)100% (7/7)100% (3/3)
othersUpdatesAreVisible (int): boolean 100% (1/1)100% (7/7)100% (3/3)
ownDeletesAreVisible (int): boolean 100% (1/1)100% (2/2)100% (1/1)
ownInsertsAreVisible (int): boolean 0%   (0/1)0%   (0/2)0%   (0/1)
ownUpdatesAreVisible (int): boolean 100% (1/1)100% (2/2)100% (1/1)
prepareSPS (String, String): PreparedStatement 100% (1/1)92%  (34/37)88%  (7/8)
run (): Object 100% (1/1)100% (3/3)100% (1/1)
storesLowerCaseIdentifiers (): boolean 100% (1/1)100% (2/2)100% (1/1)
storesLowerCaseQuotedIdentifiers (): boolean 100% (1/1)100% (2/2)100% (1/1)
storesMixedCaseIdentifiers (): boolean 100% (1/1)100% (2/2)100% (1/1)
storesMixedCaseQuotedIdentifiers (): boolean 100% (1/1)100% (2/2)100% (1/1)
storesUpperCaseIdentifiers (): boolean 100% (1/1)100% (2/2)100% (1/1)
storesUpperCaseQuotedIdentifiers (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsANSI92EntryLevelSQL (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsANSI92FullSQL (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsANSI92IntermediateSQL (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsAlterTableWithAddColumn (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsAlterTableWithDropColumn (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsBatchUpdates (): boolean 0%   (0/1)0%   (0/2)0%   (0/1)
supportsCatalogsInDataManipulation (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsCatalogsInIndexDefinitions (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsCatalogsInPrivilegeDefinitions (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsCatalogsInProcedureCalls (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsCatalogsInTableDefinitions (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsColumnAliasing (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsConvert (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsConvert (int, int): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsCoreSQLGrammar (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsCorrelatedSubqueries (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsDataDefinitionAndDataManipulationTransactions (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsDataManipulationTransactionsOnly (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsDifferentTableCorrelationNames (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsExpressionsInOrderBy (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsExtendedSQLGrammar (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsFullOuterJoins (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsGetGeneratedKeys (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsGroupBy (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsGroupByBeyondSelect (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsGroupByUnrelated (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsIntegrityEnhancementFacility (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsLikeEscapeClause (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsLimitedOuterJoins (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsMinimumSQLGrammar (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsMixedCaseIdentifiers (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsMixedCaseQuotedIdentifiers (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsMultipleOpenResults (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsMultipleResultSets (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsMultipleTransactions (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsNamedParameters (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsNonNullableColumns (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsOpenCursorsAcrossCommit (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsOpenCursorsAcrossRollback (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsOpenStatementsAcrossCommit (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsOpenStatementsAcrossRollback (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsOrderByUnrelated (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsOuterJoins (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsPositionedDelete (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsPositionedUpdate (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsResultSetConcurrency (int, int): boolean 0%   (0/1)0%   (0/18)0%   (0/5)
supportsResultSetHoldability (int): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsResultSetType (int): boolean 0%   (0/1)0%   (0/10)0%   (0/3)
supportsSavepoints (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsSchemasInDataManipulation (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsSchemasInIndexDefinitions (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsSchemasInPrivilegeDefinitions (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsSchemasInProcedureCalls (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsSchemasInTableDefinitions (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsSelectForUpdate (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsStatementPooling (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsStoredProcedures (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsSubqueriesInComparisons (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsSubqueriesInExists (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsSubqueriesInIns (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsSubqueriesInQuantifieds (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsTableCorrelationNames (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsTransactionIsolationLevel (int): boolean 100% (1/1)100% (16/16)100% (1/1)
supportsTransactions (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsUnion (): boolean 100% (1/1)100% (2/2)100% (1/1)
supportsUnionAll (): boolean 100% (1/1)100% (2/2)100% (1/1)
swapNull (String): String 100% (1/1)100% (6/6)100% (1/1)
updatesAreDetected (int): boolean 100% (1/1)100% (2/2)100% (1/1)
usesLocalFilePerTable (): boolean 100% (1/1)100% (2/2)100% (1/1)
usesLocalFiles (): boolean 100% (1/1)100% (2/2)100% (1/1)

1/*
2 
3   Derby - Class org.apache.derby.impl.jdbc.EmbedDatabaseMetaData
4 
5   Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable.
6 
7   Licensed under the Apache License, Version 2.0 (the "License");
8   you may not use this file except in compliance with the License.
9   You may obtain a copy of the License at
10 
11      http://www.apache.org/licenses/LICENSE-2.0
12 
13   Unless required by applicable law or agreed to in writing, software
14   distributed under the License is distributed on an "AS IS" BASIS,
15   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   See the License for the specific language governing permissions and
17   limitations under the License.
18 
19 */
20 
21package org.apache.derby.impl.jdbc;
22 
23import org.apache.derby.iapi.services.info.ProductVersionHolder;
24 
25import org.apache.derby.iapi.services.monitor.Monitor;
26 
27import org.apache.derby.iapi.services.sanity.SanityManager;
28 
29import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
30 
31import org.apache.derby.iapi.sql.dictionary.DataDictionary;
32import org.apache.derby.iapi.sql.dictionary.SPSDescriptor;
33 
34import org.apache.derby.iapi.error.StandardException;
35 
36import org.apache.derby.impl.sql.execute.GenericConstantActionFactory;
37import org.apache.derby.impl.sql.execute.GenericExecutionFactory;
38 
39import org.apache.derby.iapi.reference.Limits;
40import org.apache.derby.iapi.reference.JDBC20Translation;
41import org.apache.derby.iapi.reference.JDBC30Translation;
42 
43import java.util.Properties;
44 
45import java.sql.DatabaseMetaData;
46import java.sql.Connection;
47import java.sql.PreparedStatement;
48import java.sql.SQLException;
49import java.sql.ResultSet;
50import java.sql.Types;
51 
52import java.io.IOException;
53import java.io.InputStream;
54 
55/**
56 * This class provides information about the database as a whole.
57 *
58 * <P>Many of the methods here return lists of information in ResultSets.
59 * You can use the normal ResultSet methods such as getString and getInt
60 * to retrieve the data from these ResultSets.  If a given form of
61 * metadata is not available, these methods should throw a SQLException.
62 *
63 * <P>Some of these methods take arguments that are String patterns.  These
64 * arguments all have names such as fooPattern.  Within a pattern String, "%"
65 * means match any substring of 0 or more characters, and "_" means match
66 * any one character. Only metadata entries matching the search pattern
67 * are returned. If a search pattern argument is set to a null ref, it means
68 * that argument's criteria should be dropped from the search.
69 *
70 * <P>A SQLException will be thrown if a driver does not support a meta
71 * data method.  In the case of methods that return a ResultSet,
72 * either a ResultSet (which may be empty) is returned or a
73 * SQLException is thrown.
74 * <p>
75 * This implementation gets instructions from the Database for how to satisfy
76 * most requests for information.  Each instruction is either a simple string
77 * containing the desired information, or the text of a query that may be
78 * executed on the database connection to gather the information.  We get the
79 * instructions via an "InstructionReader," which requires the database
80 * Connection for initialization.
81 * <p>
82 * Those few pieces of metadata that are related to the driver, rather than the
83 * database, come from a separate InstructionReader.  Note that in that case it
84 * probably doesn't make sense to allow an instruction to specify a query.
85 *
86 * @author ames
87 */
88public class EmbedDatabaseMetaData extends ConnectionChild 
89        implements DatabaseMetaData, java.security.PrivilegedAction {
90 
91        /*
92        ** Property and values related to using
93        ** stored prepared statements for metatdata.
94        */
95 
96        private final String url;
97        
98        /*
99        ** Set to true if metadata is off
100        */
101 
102        private        GenericConstantActionFactory        constantActionFactory;
103    
104        //////////////////////////////////////////////////////////////
105        //
106        // CONSTRUCTORS
107        //
108        //////////////////////////////////////////////////////////////
109        /**
110            @exception SQLException on error
111         */
112        public EmbedDatabaseMetaData (EmbedConnection connection, String url) 
113                throws SQLException {
114 
115            super(connection);
116                this.url = url;
117 
118        }
119 
120    /** Cached query descriptions from metadata.properties. */
121    private static Properties queryDescriptions;
122    /** Cached query descriptions from metadata_net.properties. */
123    private static Properties queryDescriptions_net;
124    /**
125     * Return all queries found in either metadata.properties or
126     * metadata_net.properties.
127     *
128     * @param net if <code>true</code>, read metadata_net.properties;
129     * otherwise, read metadata.properties.
130     * @return a <code>Properties</code> value with the queries
131     */
132    private Properties getQueryDescriptions(boolean net) {
133        Properties p = net ? queryDescriptions_net : queryDescriptions;
134        if (p != null) {
135            return p;
136        }
137        loadQueryDescriptions();
138        return net ? queryDescriptions_net : queryDescriptions;
139    }
140 
141    /**
142     * Read the query descriptions from metadata.properties and
143     * metadata_net.properties. This method must be invoked from
144     * within a privileged block.
145     */
146    private void PBloadQueryDescriptions() {
147        String[] files = {
148            "metadata.properties",
149            "/org/apache/derby/impl/sql/catalog/metadata_net.properties"
150        };
151        Properties[] props = new Properties[files.length];
152        for (int i = 0; i < files.length; ++i) {
153            try {
154                props[i] = new Properties();
155                // SECURITY PERMISSION - IP3
156                InputStream is = getClass().getResourceAsStream(files[i]);
157                props[i].load(is);
158                is.close();
159            } catch (IOException ioe) {
160                if (SanityManager.DEBUG) {
161                    SanityManager.THROWASSERT("Error reading " + files[i], ioe);
162                }
163            }
164        }
165        queryDescriptions = props[0];
166        queryDescriptions_net = props[1];
167    }
168 
169        //////////////////////////////////////////////////////////////
170        //
171        // DatabaseMetaData interface
172        //
173        //////////////////////////////////////////////////////////////
174 
175    //----------------------------------------------------------------------
176        // First, a variety of minor information about the target database.
177 
178    /**
179     * Can all the procedures returned by getProcedures be called by the
180     * current user?
181     *
182     * @return true if so
183     */
184        public boolean allProceduresAreCallable() {
185                return true;
186        }
187 
188    /**
189     * Can all the tables returned by getTable be SELECTed by the
190     * current user?
191     *
192     * @return true if so
193     */
194        public boolean allTablesAreSelectable() {
195                return true;
196        }
197 
198    /**
199     * What's the url for this database?
200     *
201     * @return the url or null if it can't be generated
202     */
203        public final String getURL()  {
204 
205                if (url == null)
206                        return url;
207                int attributeStart = url.indexOf(';');
208                if (attributeStart == -1)
209                        return url;
210                else
211                        return url.substring(0,attributeStart);
212        }
213 
214    /**
215     * What's our user name as known to the database?
216     *
217     * @return our database user name
218     */
219        public String getUserName() {
220                return (getEmbedConnection().getTR().getUserName());
221        }
222 
223    /**
224     * Is the database in read-only mode?
225     *
226     * @return true if so
227     */
228        public boolean isReadOnly() {
229                return getLanguageConnectionContext().getDatabase().isReadOnly();
230        }
231 
232    /**
233     * Are NULL values sorted high?
234     *
235     * @return true if so
236     */
237        public boolean nullsAreSortedHigh() {
238                return true;
239        }
240 
241    /**
242     * Are NULL values sorted low?
243     *
244     * @return true if so
245     */
246        public boolean nullsAreSortedLow() {
247                return false;
248        }
249 
250    /**
251     * Are NULL values sorted at the start regardless of sort order?
252     *
253     * @return true if so
254     */
255        public boolean nullsAreSortedAtStart() {
256                return false;
257        }
258 
259    /**
260     * Are NULL values sorted at the end regardless of sort order?
261     *
262     * @return true if so
263     */
264        public boolean nullsAreSortedAtEnd() {
265                return false;
266        }
267 
268    /**
269     * What's the name of this database product?
270     *
271     * @return database product name
272     */
273        public String getDatabaseProductName() {
274                return Monitor.getMonitor().getEngineVersion().getProductName();
275        }
276 
277    /**
278     * What's the version of this database product?
279     *
280     * @return database version
281     */
282        public String getDatabaseProductVersion() {
283                ProductVersionHolder myPVH = Monitor.getMonitor().getEngineVersion();
284 
285                return myPVH.getVersionBuildString(false);
286        }
287 
288    /**
289     * What's the name of this JDBC driver?
290     *
291     * @return JDBC driver name
292     */
293        public String getDriverName() {
294                return "Apache Derby Embedded JDBC Driver";
295        }
296 
297    /**
298     * What's the version of this JDBC driver?
299     *
300     * @return JDBC driver version
301     */
302        public String getDriverVersion()  {
303                return getDatabaseProductVersion();
304        }
305 
306    /**
307     * What's this JDBC driver's major version number?
308     *
309     * @return JDBC driver major version
310     */
311        public int getDriverMajorVersion() {
312                return getEmbedConnection().getLocalDriver().getMajorVersion();
313        }
314 
315    /**
316     * What's this JDBC driver's minor version number?
317     *
318     * @return JDBC driver minor version number
319     */
320        public int getDriverMinorVersion() {
321                return getEmbedConnection().getLocalDriver().getMinorVersion();
322        }
323 
324    /**
325     * Does the database store tables in a local file?
326     *
327     * @return true if so
328     */
329        public boolean usesLocalFiles() {
330                return true;
331        }
332 
333    /**
334     * Does the database use a file for each table?
335     *
336     * @return true if the database uses a local file for each table
337     */
338        public boolean usesLocalFilePerTable() {
339                return true;
340        }
341 
342    /**
343     * Does the database treat mixed case unquoted SQL identifiers as
344     * case sensitive and as a result store them in mixed case?
345     *
346     * A JDBC-Compliant driver will always return false.
347     *
348     * @return true if so
349     */
350        public boolean supportsMixedCaseIdentifiers() {
351                return false;
352        }
353 
354    /**
355     * Does the database treat mixed case unquoted SQL identifiers as
356     * case insensitive and store them in upper case?
357     *
358     * @return true if so
359     */
360        public boolean storesUpperCaseIdentifiers() {
361                return true;
362        }
363 
364    /**
365     * Does the database treat mixed case unquoted SQL identifiers as
366     * case insensitive and store them in lower case?
367     *
368     * @return true if so
369     */
370        public boolean storesLowerCaseIdentifiers() {
371                return false;
372        }
373 
374    /**
375     * Does the database treat mixed case unquoted SQL identifiers as
376     * case insensitive and store them in mixed case?
377     *
378     * @return true if so
379     */
380        public boolean storesMixedCaseIdentifiers() {
381                return false;
382        }
383 
384    /**
385     * Does the database treat mixed case quoted SQL identifiers as
386     * case sensitive and as a result store them in mixed case?
387     *
388     * A JDBC-Compliant driver will always return true.
389     *
390     * @return true if so
391     */
392        public boolean supportsMixedCaseQuotedIdentifiers() {
393                return true;
394        }
395 
396    /**
397     * Does the database treat mixed case quoted SQL identifiers as
398     * case insensitive and store them in upper case?
399     *
400     * @return true if so
401     */
402        public boolean storesUpperCaseQuotedIdentifiers() {
403                return false;
404        }
405 
406    /**
407     * Does the database treat mixed case quoted SQL identifiers as
408     * case insensitive and store them in lower case?
409     *
410     * @return true if so
411     */
412        public boolean storesLowerCaseQuotedIdentifiers() {
413                return false;
414        }
415 
416    /**
417     * Does the database treat mixed case quoted SQL identifiers as
418     * case insensitive and store them in mixed case?
419     *
420     * @return true if so
421     */
422        public boolean storesMixedCaseQuotedIdentifiers() {
423                return true;
424        }
425 
426    /**
427     * What's the string used to quote SQL identifiers?
428     * This returns a space " " if identifier quoting isn't supported.
429     *
430     * A JDBC-Compliant driver always uses a double quote character.
431     *
432     * @return the quoting string
433     */
434        public String getIdentifierQuoteString() {
435                return "\"";
436        }
437 
438    /**
439     * Get a comma separated list of all a database's SQL keywords
440     * that are NOT also SQL92 keywords.
441        includes reserved and non-reserved keywords.
442 
443     * @return the list
444     */
445        public String getSQLKeywords() {
446                return "ALIAS,BIGINT,BOOLEAN,CALL,CLASS,COPY,DB2J_DEBUG,EXECUTE,EXPLAIN,FILE,FILTER,"
447                        +  "GETCURRENTCONNECTION,INDEX,INSTANCEOF,METHOD,NEW,OFF,PROPERTIES,PUBLICATION,RECOMPILE,"
448                        +  "REFRESH,RENAME,RUNTIMESTATISTICS,STATEMENT,STATISTICS,TIMING,WAIT";
449        }
450 
451    /**
452     * Get a comma separated list of JDBC escaped numeric functions.
453     * Must be a complete or sub set of functions in appendix C.1
454     * @return the list
455     */
456        public String getNumericFunctions() {
457                return "ABS,ACOS,ASIN,ATAN,CEILING,COS,DEGREES,EXP,FLOOR,LOG,LOG10,MOD,PI,RADIANS,SIN,SQRT,TAN";
458        }
459 
460    /**
461     * Get a comma separated list of JDBC escaped string functions.
462     * Must be a complete or sub set of functions in appendix C.2
463     * of JDBC 3.0 specification.
464     * @return the list
465     */
466        public String getStringFunctions() {
467                return "CONCAT,LENGTH,LCASE,LOCATE,LTRIM,RTRIM,SUBSTRING,UCASE";
468        }
469 
470    /**
471     * Get a comma separated list of JDBC escaped system functions.
472     * Must be a complete or sub set of functions in appendix C.4
473     * of JDBC 3.0 specification.
474     * @return the list
475     */
476        public String getSystemFunctions()  {
477                return "USER";
478        }
479 
480    /**
481     * Get a comma separated list of JDBC escaped time date functions.
482     * Must be a complete or sub set of functions in appendix C.3
483     * of JDBC 3.0 specification.
484      * @return the list
485     */
486        public String getTimeDateFunctions() {
487                return "CURDATE,CURTIME,HOUR,MINUTE,MONTH,SECOND,TIMESTAMPADD,TIMESTAMPDIFF,YEAR";
488        }
489 
490    /**
491     * This is the string that can be used to escape '_' or '%' in
492     * the string pattern style catalog search parameters.
493        we have no default escape value, so = is the end of the next line
494     * <P>The '_' character represents any single character.
495     * <P>The '%' character represents any sequence of zero or
496     * more characters.
497     * @return the string used to escape wildcard characters
498     */
499        public String getSearchStringEscape()  {
500                return "";
501        }
502 
503    /**
504     * Get all the "extra" characters that can be used in unquoted
505     * identifier names (those beyond a-z, A-Z, 0-9 and _).
506     *
507     * @return the string containing the extra characters
508     */
509        public String getExtraNameCharacters()  {
510                return "";
511        }
512 
513    //--------------------------------------------------------------------
514    // Functions describing which features are supported.
515 
516    /**
517     * Is "ALTER TABLE" with add column supported?
518     *
519     * @return true if so
520     */
521        public boolean supportsAlterTableWithAddColumn() {
522                return true;
523        }
524 
525    /**
526     * Is "ALTER TABLE" with drop column supported?
527     *
528     * @return true if so
529     */
530        public boolean supportsAlterTableWithDropColumn() {
531                return true;
532        }
533 
534    /**
535     * Is column aliasing supported?
536     *
537     * <P>If so, the SQL AS clause can be used to provide names for
538     * computed columns or to provide alias names for columns as
539     * required.
540     *
541     * A JDBC-Compliant driver always returns true.
542     *
543     * @return true if so
544     */
545        public boolean supportsColumnAliasing() {
546                return true;
547        }
548 
549    /**
550     * Are concatenations between NULL and non-NULL values NULL?
551     *
552     * A JDBC-Compliant driver always returns true.
553     *
554     * @return true if so
555     */
556        public boolean nullPlusNonNullIsNull()  {
557                return true;
558        }
559 
560    /**
561     * Is the CONVERT function between SQL types supported?
562     *
563     * @return true if so
564     */
565        public boolean supportsConvert() {
566                return true;
567        }
568 
569    /**
570     * Is CONVERT between the given SQL types supported?
571     *
572     * @param fromType the type to convert from
573     * @param toType the type to convert to
574     * @return true if so
575     * @see Types
576     */
577        public boolean supportsConvert(int fromType, int toType) {
578                /*
579                 * at the moment we don't support CONVERT at all, so we take the easy
580                 * way out.  Eventually we need to figure out how to handle this
581                 * cleanly.
582                 */
583                return false;
584        }
585 
586    /**
587     * Are table correlation names supported?
588     *
589     * A JDBC-Compliant driver always returns true.
590     *
591     * @return true if so
592     */
593        public boolean supportsTableCorrelationNames()  {
594                return true;
595        }
596 
597    /**
598     * If table correlation names are supported, are they restricted
599     * to be different from the names of the tables?
600     *
601     * @return true if so
602     */
603        public boolean supportsDifferentTableCorrelationNames() {
604                return true;
605        }
606 
607    /**
608     * Are expressions in "ORDER BY" lists supported?
609     *
610     * @return true if so
611     */
612        public boolean supportsExpressionsInOrderBy() {
613                return false;
614        }
615 
616    /**
617     * Can an "ORDER BY" clause use columns not in the SELECT?
618     *
619     * @return true if so
620     */
621        public boolean supportsOrderByUnrelated() {
622                return false;
623        }
624 
625    /**
626     * Is some form of "GROUP BY" clause supported?
627     *
628     * @return true if so
629     */
630        public boolean supportsGroupBy() {
631                return true;
632        }
633 
634    /**
635     * Can a "GROUP BY" clause use columns not in the SELECT?
636     *
637     * @return true if so
638     */
639        public boolean supportsGroupByUnrelated()  {
640                return true;
641        }
642 
643    /**
644     * Can a "GROUP BY" clause add columns not in the SELECT
645     * provided it specifies all the columns in the SELECT?
646     *
647     * @return true if so
648     */
649        public boolean supportsGroupByBeyondSelect() {
650                return true;
651        }
652 
653    /**
654     * Is the escape character in "LIKE" clauses supported?
655     *
656     * A JDBC-Compliant driver always returns true.
657     *
658     * @return true if so
659     */
660        public boolean supportsLikeEscapeClause() {
661                return true;
662        }
663 
664    /**
665     * Are multiple ResultSets from a single execute supported?
666     *
667     * @return true if so
668     */
669        public boolean supportsMultipleResultSets()  {
670                return true;
671        }
672 
673    /**
674     * Can we have multiple transactions open at once (on different
675     * connections)?
676     *
677     * @return true if so
678     */
679        public boolean supportsMultipleTransactions() {
680                return true;
681        }
682 
683    /**
684     * Can columns be defined as non-nullable?
685     *
686     * A JDBC-Compliant driver always returns true.
687     *
688     * @return true if so
689     */
690        public boolean supportsNonNullableColumns()  {
691                return true;
692        }
693 
694    /**
695     * Is the ODBC Minimum SQL grammar supported?
696     *
697     * All JDBC-Compliant drivers must return true.
698     *
699     * @return true if so
700     */
701        public boolean supportsMinimumSQLGrammar() {
702                return true;
703        }
704 
705    /**
706     * Is the ODBC Core SQL grammar supported?
707     *
708     * @return true if so
709     */
710        public boolean supportsCoreSQLGrammar() {
711                return false;
712        }
713 
714    /**
715     * Is the ODBC Extended SQL grammar supported?
716     *
717     * @return true if so
718     */
719        public boolean supportsExtendedSQLGrammar() {
720                return false;
721        }
722 
723    /**
724     * Is the ANSI92 entry level SQL grammar supported?
725     *
726     * All JDBC-Compliant drivers must return true.
727     *
728     * @return true if so
729     */
730        public boolean supportsANSI92EntryLevelSQL() {
731                return false;
732        }
733 
734    /**
735     * Is the ANSI92 intermediate SQL grammar supported?
736     *
737     * @return true if so
738         * 
739     */
740        public boolean supportsANSI92IntermediateSQL() {
741                return false;
742        }
743 
744    /**
745     * Is the ANSI92 full SQL grammar supported?
746     *
747     * @return true if so
748         * 
749     */
750        public boolean supportsANSI92FullSQL() {
751                return false;
752        }
753 
754    /**
755     * Is the SQL Integrity Enhancement Facility supported?
756     *
757     * @return true if so
758         * 
759     */
760        public boolean supportsIntegrityEnhancementFacility() {
761                return false;
762        }
763 
764    /**
765     * Is some form of outer join supported?
766     *
767     * @return true if so
768         * 
769     */
770        public boolean supportsOuterJoins() {
771                return true;
772        }
773 
774    /**
775     * Are full nested outer joins supported?
776     *
777     * @return true if so
778         * 
779     */
780        public boolean supportsFullOuterJoins()  {
781                return false;
782        }
783 
784    /**
785     * Is there limited support for outer joins?  (This will be true
786     * if supportFullOuterJoins is true.)
787     *
788     * @return true if so
789         * 
790     */
791        public boolean supportsLimitedOuterJoins() {
792                return true;
793        }
794 
795    /**
796     * What's the database vendor's preferred term for "schema"?
797     *
798     * @return the vendor term
799         * 
800     */
801        public String getSchemaTerm() {
802                return "SCHEMA";
803        }
804 
805    /**
806     * What's the database vendor's preferred term for "procedure"?
807     *
808     * @return the vendor term
809         * 
810     */
811        public String getProcedureTerm() {
812                return "PROCEDURE";
813        }
814 
815    /**
816     * What's the database vendor's preferred term for "catalog"?
817     *
818     * @return the vendor term
819         * 
820     */
821        public String getCatalogTerm() {
822                return "CATALOG";
823        }
824 
825    /**
826     * Does a catalog appear at the start of a qualified table name?
827     * (Otherwise it appears at the end)
828     *
829     * @return true if it appears at the start
830         * 
831     */
832        public boolean isCatalogAtStart() {
833                return false;
834        }
835 
836    /**
837     * What's the separator between catalog and table name?
838     *
839     * @return the separator string
840         * 
841     */
842        public String getCatalogSeparator() {
843                return "";
844        }
845 
846    /**
847     * Can a schema name be used in a data manipulation statement?
848     *
849     * @return true if so
850         * 
851     */
852        public boolean supportsSchemasInDataManipulation() {
853                return true;
854        }
855 
856    /**
857     * Can a schema name be used in a procedure call statement?
858     *
859     * @return true if so
860         * 
861     */
862        public boolean supportsSchemasInProcedureCalls() {
863                return true;
864        }
865 
866    /**
867     * Can a schema name be used in a table definition statement?
868     *
869     * @return true if so
870         * 
871     */
872        public boolean supportsSchemasInTableDefinitions() {
873                return true;
874        }
875 
876    /**
877     * Can a schema name be used in an index definition statement?
878     *
879     * @return true if so
880     */
881        public boolean supportsSchemasInIndexDefinitions() {
882                return true;
883        }
884 
885    /**
886     * Can a schema name be used in a privilege definition statement?
887     *
888     * @return true if so
889         * 
890     */
891        public boolean supportsSchemasInPrivilegeDefinitions() {
892                return true;
893        }
894 
895    /**
896     * Can a catalog name be used in a data manipulation statement?
897     *
898     * @return true if so
899         * 
900     */
901        public boolean supportsCatalogsInDataManipulation() {
902                return false;
903        }
904 
905    /**
906     * Can a catalog name be used in a procedure call statement?
907     *
908     * @return true if so
909         * 
910     */
911        public boolean supportsCatalogsInProcedureCalls() {
912                return false;
913        }
914 
915    /**
916     * Can a catalog name be used in a table definition statement?
917     *
918     * @return true if so
919         * 
920     */
921        public boolean supportsCatalogsInTableDefinitions() {
922                return false;
923        }
924 
925    /**
926     * Can a catalog name be used in an index definition statement?
927     *
928     * @return true if so
929     */
930        public boolean supportsCatalogsInIndexDefinitions() {
931                return false;
932        }
933 
934    /**
935     * Can a catalog name be used in a privilege definition statement?
936     *
937     * @return true if so
938     */
939        public boolean supportsCatalogsInPrivilegeDefinitions() {
940                return false;
941        }
942 
943 
944    /**
945     * Is positioned DELETE supported?
946     *
947     * @return true if so
948     */
949        public boolean supportsPositionedDelete() {
950                return true;
951        }
952 
953    /**
954     * Is positioned UPDATE supported?
955     *
956     * @return true if so
957     */
958        public boolean supportsPositionedUpdate() {
959                return true;
960        }
961 
962    /**
963     * Is SELECT for UPDATE supported?
964     *
965     * @return true if so
966     */
967        public boolean supportsSelectForUpdate() {
968                return true;
969        }
970 
971    /**
972     * Are stored procedure calls using the stored procedure escape
973     * syntax supported?
974     *
975     * @return true if so
976     */
977        public boolean supportsStoredProcedures() {
978                return true;
979        }
980 
981    /**
982     * Are subqueries in comparison expressions supported?
983     *
984     * A JDBC-Compliant driver always returns true.
985     *
986     * @return true if so
987     */
988        public boolean supportsSubqueriesInComparisons() {
989                return true;
990        }
991 
992    /**
993     * Are subqueries in 'exists' expressions supported?
994     *
995     * A JDBC-Compliant driver always returns true.
996     *
997     * @return true if so
998     */
999        public boolean supportsSubqueriesInExists() {
1000                return true;
1001        }
1002 
1003    /**
1004     * Are subqueries in 'in' statements supported?
1005     *
1006     * A JDBC-Compliant driver always returns true.
1007     *
1008     * @return true if so
1009     */
1010        public boolean supportsSubqueriesInIns() {
1011                return true;
1012        }
1013 
1014    /**
1015     * Are subqueries in quantified expressions supported?
1016     *
1017     * A JDBC-Compliant driver always returns true.
1018     *
1019     * @return true if so
1020     */
1021        public boolean supportsSubqueriesInQuantifieds() {
1022                return true;
1023        }
1024 
1025    /**
1026     * Are correlated subqueries supported?
1027     *
1028     * A JDBC-Compliant driver always returns true.
1029     *
1030     * @return true if so
1031     */
1032        public boolean supportsCorrelatedSubqueries() {
1033                return true;
1034        }
1035 
1036    /**
1037     * Is SQL UNION supported?
1038     *
1039     * @return true if so
1040     */
1041        public boolean supportsUnion() {
1042                return true;
1043        }
1044 
1045    /**
1046     * Is SQL UNION ALL supported?
1047     *
1048     * @return true if so
1049     */
1050        public boolean supportsUnionAll() {
1051                return true;
1052        }
1053 
1054    /**
1055     * Can cursors remain open across commits?
1056     *
1057     * @return true if cursors always remain open; false if they might not remain open
1058     */
1059        //returns false because Derby does not support cursors that are open across commits for XA transactions.
1060        public boolean supportsOpenCursorsAcrossCommit() {
1061                return false;
1062        }
1063 
1064    /**
1065     * Can cursors remain open across rollbacks?
1066     *
1067     * @return true if cursors always remain open; false if they might not remain open
1068     */
1069        public boolean supportsOpenCursorsAcrossRollback() {
1070                return false;
1071        }
1072 
1073    /**
1074     * Can statements remain open across commits?
1075     *
1076     * @return true if statements always remain open; false if they might not remain open
1077     */
1078        public boolean supportsOpenStatementsAcrossCommit() {
1079                return true;
1080        }
1081 
1082    /**
1083     * Can statements remain open across rollbacks?
1084     *
1085     * @return true if statements always remain open; false if they might not remain open
1086     */
1087        public boolean supportsOpenStatementsAcrossRollback() {
1088                return false;
1089        }
1090 
1091 
1092 
1093    //----------------------------------------------------------------------
1094    // The following group of methods exposes various limitations
1095    // based on the target database with the current driver.
1096    // Unless otherwise specified, a result of zero means there is no
1097    // limit, or the limit is not known.
1098 
1099    /**
1100     * How many hex characters can you have in an inline binary literal?
1101     *
1102     * @return max literal length
1103     */
1104        public int getMaxBinaryLiteralLength() {
1105                return 0;
1106        }
1107 
1108    /**
1109     * What's the max length for a character literal?
1110     *
1111     * @return max literal length
1112     */
1113        public int getMaxCharLiteralLength() {
1114                return 0;
1115        }
1116 
1117    /**
1118     * What's the limit on column name length?
1119     *
1120     * @return max literal length
1121     */
1122        public int getMaxColumnNameLength() {
1123                return Limits.MAX_IDENTIFIER_LENGTH;
1124        }
1125 
1126    /**
1127     * What's the maximum number of columns in a "GROUP BY" clause?
1128     *
1129     * @return max number of columns
1130     */
1131        public int getMaxColumnsInGroupBy() {
1132                return 0;
1133        }
1134 
1135    /**
1136     * What's the maximum number of columns allowed in an index?
1137     *
1138     * @return max columns
1139     */
1140        public int getMaxColumnsInIndex() {
1141                return 0;
1142        }
1143 
1144    /**
1145     * What's the maximum number of columns in an "ORDER BY" clause?
1146     *
1147     * @return max columns
1148     */
1149        public int getMaxColumnsInOrderBy() {
1150                return 0;
1151        }
1152 
1153    /**
1154     * What's the maximum number of columns in a "SELECT" list?
1155     *
1156     * we don't have a limit...
1157     *
1158     * @return max columns
1159     */
1160        public int getMaxColumnsInSelect() {
1161                return 0;
1162        }
1163 
1164    /**
1165     * What's the maximum number of columns in a table?
1166     *
1167     * @return max columns
1168     */
1169        public int getMaxColumnsInTable()  {
1170                return 0;
1171        }
1172 
1173    /**
1174     * How many active connections can we have at a time to this database?
1175     *
1176     * @return max connections
1177     */
1178        public int getMaxConnections() {
1179                return 0;
1180        }
1181 
1182    /**
1183     * What's the maximum cursor name length?
1184     *
1185     * @return max cursor name length in bytes
1186     */
1187        public int getMaxCursorNameLength() {
1188                return Limits.MAX_IDENTIFIER_LENGTH;
1189        }
1190 
1191    /**
1192     * What's the maximum length of an index (in bytes)?
1193     *
1194     * @return max index length in bytes
1195     */
1196        public int getMaxIndexLength() {
1197                return 0;
1198        }
1199 
1200    /**
1201     * What's the maximum length allowed for a schema name?
1202     *
1203     * @return max name length in bytes
1204     */
1205        public int getMaxSchemaNameLength()  {
1206                return Limits.MAX_IDENTIFIER_LENGTH;
1207        }
1208 
1209    /**
1210     * What's the maximum length of a procedure name?
1211     *
1212     * @return max name length in bytes
1213     */
1214        public int getMaxProcedureNameLength() {
1215                return Limits.MAX_IDENTIFIER_LENGTH;
1216        }
1217 
1218    /**
1219     * What's the maximum length of a catalog name?
1220     *
1221     * @return max name length in bytes
1222     */
1223        public int getMaxCatalogNameLength()  {
1224                return 0;
1225        }
1226 
1227    /**
1228     * What's the maximum length of a single row?
1229     *
1230     * @return max row size in bytes
1231     */
1232        public int getMaxRowSize() {
1233                return 0;
1234        }
1235 
1236    /**
1237     * Did getMaxRowSize() include LONGVARCHAR and LONGVARBINARY
1238     * blobs?
1239     *
1240     * @return true if so
1241     */
1242        public boolean doesMaxRowSizeIncludeBlobs() {
1243                return true;
1244        }
1245 
1246    /**
1247     * What's the maximum length of a SQL statement?
1248     *
1249     * @return max length in bytes
1250     */
1251        public int getMaxStatementLength() {
1252                return 0;
1253        }
1254 
1255    /**
1256     * How many active statements can we have open at one time to this
1257     * database?
1258     *
1259     * @return the maximum
1260     */
1261        public int getMaxStatements() {
1262                return 0;
1263        }
1264 
1265    /**
1266     * What's the maximum length of a table name?
1267     *
1268     * @return max name length in bytes
1269     */
1270        public int getMaxTableNameLength() {
1271                return Limits.MAX_IDENTIFIER_LENGTH;
1272        }
1273 
1274    /**
1275     * What's the maximum number of tables in a SELECT?
1276     *
1277     * @return the maximum
1278     */
1279        public int getMaxTablesInSelect() {
1280                return 0;
1281        }
1282 
1283    /**
1284     * What's the maximum length of a user name?
1285     *
1286     * @return max name length  in bytes
1287     */
1288        public int getMaxUserNameLength() {
1289                return Limits.DB2_MAX_USERID_LENGTH;
1290        }
1291 
1292    //----------------------------------------------------------------------
1293 
1294    /**
1295     * What's the database's default transaction isolation level?  The
1296     * values are defined in java.sql.Connection.
1297     *
1298     * @return the default isolation level
1299     * @see Connection
1300     */
1301        public int getDefaultTransactionIsolation() {
1302                return java.sql.Connection.TRANSACTION_READ_COMMITTED;
1303        }
1304 
1305    /**
1306     * Are transactions supported? If not, commit is a noop and the
1307     * isolation level is TRANSACTION_NONE.
1308     *
1309     * @return true if transactions are supported
1310     */
1311        public boolean supportsTransactions()  {
1312                return true;
1313        }
1314 
1315    /**
1316     * Does the database support the given transaction isolation level?
1317         *
1318         * DatabaseMetaData.supportsTransactionIsolation() should return false for
1319         * isolation levels that are not supported even if a higher level can be
1320         * substituted.
1321     *
1322     * @param level the values are defined in java.sql.Connection
1323     * @return true if so
1324     * @see Connection
1325                */        
1326        public boolean supportsTransactionIsolationLevel(int level)
1327                                                         {
1328                // REMIND: This is hard-coded for the moment because it doesn't nicely
1329                // fit within the framework we've set up for the rest of these values.
1330                // Part of the reason is that it has a parameter, so it's not just a
1331                // simple value look-up.  Some ideas for the future on how to make this
1332                // not hard-coded:
1333                //          - code it as a query: "select true from <something> where ? in
1334                //      (a,b,c)" where a,b,c are the supported isolation levels.  The
1335                //      parameter would be set to "level".  This seems awfully awkward.
1336                //    - somehow what you'd really like is to enable the instructions
1337                //      file to contain the list, or set, of supported isolation
1338                //      levels.  Something like:
1339                //          supportsTr...ionLevel=SERIALIZABLE | REPEATABLE_READ | ...
1340                //      That would take some more code that doesn't seem worthwhile at
1341                //      the moment for this one case.
1342 
1343                /*
1344                        REMIND: this could be moved into a query that is e.g.
1345                        VALUES ( ? in (8,...) )
1346                        so that database could control the list of supported
1347                        isolations.  For now, it's hard coded, and just the one.
1348                 */
1349 
1350                return (level == Connection.TRANSACTION_SERIALIZABLE    ||
1351                        level == Connection.TRANSACTION_REPEATABLE_READ ||
1352                            level == Connection.TRANSACTION_READ_COMMITTED  ||
1353                            level == Connection.TRANSACTION_READ_UNCOMMITTED);
1354        }
1355 
1356    /**
1357     * Are both data definition and data manipulation statements
1358     * within a transaction supported?
1359     *
1360     * @return true if so
1361     */
1362        public boolean supportsDataDefinitionAndDataManipulationTransactions() {
1363                         return true;
1364        }
1365    /**
1366     * Are only data manipulation statements within a transaction
1367     * supported?
1368     *
1369     * @return true if so
1370     */
1371        public boolean supportsDataManipulationTransactionsOnly()
1372        {
1373                         return false;
1374        }
1375    /**
1376     * Does a data definition statement within a transaction force the
1377     * transaction to commit?
1378     *
1379     * @return true if so
1380         * 
1381     */
1382        public boolean dataDefinitionCausesTransactionCommit() {
1383                return false;
1384        }
1385    /**
1386     * Is a data definition statement within a transaction ignored?
1387     *
1388     * @return true if so
1389         * 
1390     */
1391        public boolean dataDefinitionIgnoredInTransactions(){
1392                return false;
1393        }
1394 
1395 
1396    /**
1397     * Get a description of stored procedures available in a
1398     * catalog.
1399     *
1400     * <P>Only procedure descriptions matching the schema and
1401     * procedure name criteria are returned.  They are ordered by
1402     * PROCEDURE_SCHEM, and PROCEDURE_NAME.
1403     *
1404     * <P>Each procedure description has the the following columns:
1405     *  <OL>
1406     *        <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)
1407     *        <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)
1408     *        <LI><B>PROCEDURE_NAME</B> String => procedure name
1409     *  <LI> reserved for future use
1410     *  <LI> reserved for future use
1411     *  <LI> reserved for future use
1412     *        <LI><B>REMARKS</B> String => explanatory comment on the procedure
1413     *        <LI><B>PROCEDURE_TYPE</B> short => kind of procedure:
1414     *      <UL>
1415     *      <LI> procedureResultUnknown - May return a result
1416     *      <LI> procedureNoResult - Does not return a result
1417     *      <LI> procedureReturnsResult - Returns a result
1418     *      </UL>
1419     *  <LI><B>SPECIFIC_NAME</B> String => The name which uniquely 
1420     *  identifies this procedure within its schema (since JDBC 4.0)
1421     *  </OL>
1422     *
1423     * @param catalog a catalog name; "" retrieves those without a
1424     * catalog; null means drop catalog name from the selection criteria
1425     * @param schemaPattern a schema name pattern; "" retrieves those
1426     * without a schema
1427     * @param procedureNamePattern a procedure name pattern
1428     * @return ResultSet - each row is a procedure description
1429     * @see #getSearchStringEscape
1430     * @exception SQLException thrown on failure.
1431     */
1432        public ResultSet getProcedures(String catalog, String schemaPattern,
1433                        String procedureNamePattern) throws SQLException {
1434 
1435        // Using the new JDBC 4.0 version of the query here. The query
1436        // was given a new name to allow the old query to
1437        // be used by ODBCMetaDataGenerator.
1438                return doGetProcs(catalog, schemaPattern,
1439                        procedureNamePattern, "getProcedures40");
1440        }
1441 
1442        /**
1443         * Get a description of stored procedures available in a
1444         * catalog.  Same as getProcedures() above, except that
1445         * the result set will conform to ODBC specifications.
1446         */
1447        public ResultSet getProceduresForODBC(String catalog, String schemaPattern,
1448                        String procedureNamePattern) throws SQLException {
1449 
1450        // For ODBC we still use the transformed version of the JDBC
1451        // 3.0 query, (may change in the future).
1452                return doGetProcs(catalog, schemaPattern,
1453                        procedureNamePattern, "odbc_getProcedures");
1454        }
1455    
1456    /**
1457     * Implements DatabaseMetaData.getFunctions() for an embedded
1458     * database. Queries the database to get information about
1459     * functions (procedures returning values). Executes the
1460     * 'getFunctions' query from metadata.properties to obtain the
1461     * ResultSet to return.<p> Compatibility: This is a new method in
1462     * the API which is only available with with Derby versions > 10.1 and
1463     * JDK versions >= 1.6 <p>Upgrade: Since this is a new query it
1464     * does not have an SPS, and will be available as soon as any
1465     * database, new or old, is booted with the new version of Derby,
1466     * (in <b>soft and hard</b> upgrade).
1467     * @param catalog limit the search to functions in this catalog 
1468     * (not used)
1469     * @param schemaPattern limit the search to functions in schemas 
1470     * matching this pattern
1471     * @param functionNamePattern limit the search to functions 
1472     * matching this pattern
1473     * @return a ResultSet with metadata information
1474     * @throws SQLException if any of the underlying jdbc methods fail
1475     */
1476    public ResultSet getFunctions(java.lang.String catalog,
1477                                  java.lang.String schemaPattern,
1478                                  java.lang.String functionNamePattern)
1479        throws SQLException
1480    {
1481        return doGetProcs(catalog, schemaPattern,
1482                   functionNamePattern, "getFunctions");
1483    }
1484 
1485        /**
1486         * Does the actual work for the getProcedures and getFunctions
1487         * metadata calls.  See getProcedures() method above for parameter
1488         * descriptions.
1489         * @param queryName Name of the query to execute; is used
1490         *        to determine whether the result set should conform to
1491         *        JDBC or ODBC specifications.
1492         */
1493        private ResultSet doGetProcs(String catalog, String schemaPattern,
1494                String procedureNamePattern, String queryName)
1495                throws SQLException {
1496 
1497                PreparedStatement s = getPreparedQuery(queryName);
1498                s.setString(1, swapNull(catalog));
1499                s.setString(2, swapNull(schemaPattern));
1500                s.setString(3, swapNull(procedureNamePattern));
1501                return s.executeQuery();
1502        }
1503 
1504    /**
1505     * Get a description of a catalog's stored procedure parameters
1506     * and result columns.
1507     *
1508     * <P>Only descriptions matching the schema, procedure and
1509     * parameter name criteria are returned.  They are ordered by
1510     * PROCEDURE_SCHEM and PROCEDURE_NAME. Within this, the return value,
1511     * if any, is first. Next are the parameter descriptions in call
1512     * order. The column descriptions follow in column number order.
1513     *
1514     * <P>Each row in the ResultSet is a parameter description or
1515     * column description with the following fields:
1516     *  <OL>
1517     *        <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)
1518     *        <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)
1519     *        <LI><B>PROCEDURE_NAME</B> String => procedure name
1520     *        <LI><B>COLUMN_NAME</B> String => column/parameter name
1521     *        <LI><B>COLUMN_TYPE</B> Short => kind of column/parameter:
1522     *      <UL>
1523     *      <LI> procedureColumnUnknown - nobody knows
1524     *      <LI> procedureColumnIn - IN parameter
1525     *      <LI> procedureColumnInOut - INOUT parameter
1526     *      <LI> procedureColumnOut - OUT parameter
1527     *      <LI> procedureColumnReturn - procedure return value
1528     *      <LI> procedureColumnResult - result column in ResultSet
1529     *      </UL>
1530     *  <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types
1531     *        <LI><B>TYPE_NAME</B> String => SQL type name
1532     *        <LI><B>PRECISION</B> int => precision
1533     *        <LI><B>LENGTH</B> int => length in bytes of data
1534     *        <LI><B>SCALE</B> short => scale
1535     *        <LI><B>RADIX</B> short => radix
1536     *        <LI><B>NULLABLE</B> short => can it contain NULL?
1537     *      <UL>
1538     *      <LI> procedureNoNulls - does not allow NULL values
1539     *      <LI> procedureNullable - allows NULL values
1540     *      <LI> procedureNullableUnknown - nullability unknown
1541     *      </UL>
1542     *        <LI><B>REMARKS</B> String => comment describing parameter/column
1543     *        <LI><B>COLUMN_DEF</B> String
1544     *        <LI><B>SQL_DATA_TYPE</B> int
1545     *        <LI><B>SQL_DATETIME_SUB</B> int
1546     *        <LI><B>CHAR_OCTET_LENGTH</B> int
1547     *        <LI><B>ORDINAL_POSITION</B> int
1548     *        <LI><B>IS_NULLABLE</B> String
1549     *        <LI><B>SPECIFIC_NAME</B> String
1550     *  </OL>
1551     *
1552     * <P><B>Note:</B> Some databases may not return the column
1553     * descriptions for a procedure. Additional columns beyond
1554     * SPECIFIC_NAME can be defined by the database.
1555     *
1556     * @param catalog a catalog name; "" retrieves those without a
1557     * catalog; null means drop catalog name from the selection criteria
1558     * @param schemaPattern a schema name pattern; "" retrieves those
1559     * without a schema
1560     * @param procedureNamePattern a procedure name pattern
1561     * @param columnNamePattern a column name pattern
1562     * @return ResultSet - each row is a stored procedure parameter or
1563     *      column description
1564     * @see #getSearchStringEscape
1565         * @exception SQLException thrown on failure.
1566     */
1567        public ResultSet getProcedureColumns(String catalog,
1568                        String schemaPattern,
1569                        String procedureNamePattern,
1570                        String columnNamePattern) throws SQLException {
1571 
1572                // Using the new JDBC 4.0 version of the query here. The query
1573                // was given a new name to allow the old query to
1574                // be used by ODBCMetaDataGenerator.
1575                return doGetProcCols(catalog, schemaPattern,
1576                        procedureNamePattern, columnNamePattern,
1577                        "getProcedureColumns40");
1578        }
1579 
1580        /**
1581         * Get a description of a catalog's stored procedure parameters
1582         * and result columns.  Same as getProcedureColumns() above,
1583         * except that the result set will conform to ODBC specifications.
1584         */
1585        public ResultSet getProcedureColumnsForODBC(String catalog,
1586                        String schemaPattern, String procedureNamePattern,
1587                        String columnNamePattern) throws SQLException {
1588 
1589                // For ODBC we still use the transformed version of the JDBC
1590                // 3.0 query, (may change in the future).
1591                return doGetProcCols(catalog, schemaPattern,
1592                        procedureNamePattern, columnNamePattern,
1593                        "odbc_getProcedureColumns");
1594        }
1595 
1596    /**
1597     * Implements DatabaseMetaData.getFunctionParameters() for an embedded
1598     * database. Queries the database to get information about
1599     * function parameters. Executes the
1600     * 'getFunctionParameters' query from metadata.properties to obtain the
1601     * ResultSet.<p> Compatibility: This is a new method in
1602     * the API which is only available with with Derby versions > 10.1 and
1603     * JDK versions >= 1.6 <p>Upgrade: Since this is a new query it
1604     * does not have an SPS, and will be available as soon as any
1605     * database, new or old, is booted with the new version of Derby,
1606     * (in <b>soft and hard</b> upgrade).
1607     * @param catalog limit the search to functions in this catalog
1608     * (not used)
1609     * @param schemaPattern limit the search to functions in schemas
1610     * matching this pattern
1611     * @param functionNamePattern limit the search to functions
1612     * matching this pattern
1613     * @param parameterNamePattern limit the search parameters
1614     * matching this pattern
1615     * @return a ResultSet with metadata information
1616     * @throws SQLException if a database error occurs
1617     */
1618        public ResultSet getFunctionParameters(String catalog,
1619                                                                                   String schemaPattern,
1620                                                                                   String functionNamePattern,
1621                                                                                   String parameterNamePattern) 
1622                throws SQLException {
1623                PreparedStatement s = getPreparedQuery("getFunctionParameters");
1624 
1625                // Cannot use doGetProcCols() because our query requires
1626                // parameterNamePattern twice, because both LIKE and = is
1627                // required to select parameters with an empty parameter
1628                // name. That is, WHERE paramName LIKE ? will not match an
1629                // empty paramName, but WHERE paramName LIKE ? OR paramName =
1630                // ? will.
1631                s.setString(1, swapNull(schemaPattern));
1632                s.setString(2, swapNull(functionNamePattern));
1633                s.setString(3, swapNull(parameterNamePattern));
1634                s.setString(4, swapNull(parameterNamePattern));
1635                return s.executeQuery();
1636        }
1637 
1638        /**
1639         * Does the actual work for the getProcedureColumns metadata
1640         * calls. See getProcedureColumns() method above for parameter
1641         * descriptions.
1642         * @param queryName Name of the query to execute; is used
1643         *        to determine whether the result set should conform to
1644         *        JDBC or ODBC specifications.
1645         */
1646        private ResultSet doGetProcCols(String catalog, String schemaPattern,
1647                        String procedureNamePattern, String columnNamePattern,
1648                        String queryName) throws SQLException {
1649 
1650                PreparedStatement s = getPreparedQuery(queryName);
1651                // 
1652                // catalog is not part of the query
1653                //
1654                s.setString(1, swapNull(schemaPattern));
1655                s.setString(2, swapNull(procedureNamePattern));
1656                s.setString(3, swapNull(columnNamePattern));
1657                return s.executeQuery();
1658        }
1659 
1660    /**
1661     * Get a description of tables available in a catalog.
1662     *
1663     * <P>Only table descriptions matching the catalog, schema, table
1664     * name and type criteria are returned.  They are ordered by
1665     * TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.
1666     *
1667     * <P>Each table description has the following columns:
1668     *  <OL>
1669     *        <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1670     *        <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1671     *        <LI><B>TABLE_NAME</B> String => table name
1672     *        <LI><B>TABLE_TYPE</B> String => table type.  Typical types are "TABLE",
1673     *                        "VIEW",        "SYSTEM TABLE", "GLOBAL TEMPORARY",
1674     *                        "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
1675     *        <LI><B>REMARKS</B> String => explanatory comment on the table
1676     *  </OL>
1677     *
1678     * <P><B>Note:</B> Some databases may not return information for
1679     * all tables.
1680     *
1681     * @param catalog a catalog name; "" retrieves those without a
1682     * catalog; null means drop catalog name from the selection criteria
1683     * @param schemaPattern a schema name pattern; "" retrieves those
1684     * without a schema
1685     * @param tableNamePattern a table name pattern
1686     * @param types a list of table types to include; null returns all types
1687     * @return ResultSet - each row is a table description
1688     * @see #getSearchStringEscape
1689         * @exception SQLException thrown on failure.
1690     */
1691        public ResultSet getTables(String catalog, String schemaPattern,
1692                String tableNamePattern, String types[]) throws SQLException {
1693                synchronized (getConnectionSynchronization()) {
1694                        setupContextStack();
1695                        ResultSet rs = null;
1696                        try {
1697                        
1698                        String queryText =
1699                                getQueryDescriptions(false).getProperty("getTables");
1700 
1701                        /*
1702                         * The query text is assumed to end with a "where" clause, so
1703                         * that we can safely append
1704                         * "and table_Type in ('xxx','yyy','zzz', ...)" and
1705                         * have it become part of the where clause.
1706                         *
1707                         * Let's assume for now that the table type first char corresponds
1708                         * to JBMS table type identifiers.
1709                         */
1710                        StringBuffer whereClauseTail = new StringBuffer(queryText);
1711 
1712                        if (types != null  &&  types.length >= 1) {
1713                                whereClauseTail.append(" AND TABLETYPE IN ('");
1714                                whereClauseTail.append(types[0].substring(0, 1));
1715 
1716                                for (int i=1; i<types.length; i++) {
1717                                        whereClauseTail.append("','");
1718                                        whereClauseTail.append(types[i].substring(0, 1));
1719                                }
1720                                whereClauseTail.append("')");
1721                        }
1722                        // Add the order by clause after the 'in' list.
1723                        whereClauseTail.append(
1724                                " ORDER BY TABLE_TYPE, TABLE_SCHEM, TABLE_NAME");
1725 
1726                        PreparedStatement s =
1727                                getEmbedConnection().prepareMetaDataStatement(whereClauseTail.toString());
1728 
1729                        s.setString(1, swapNull(catalog));
1730                        s.setString(2, swapNull(schemaPattern));
1731                        s.setString(3, swapNull(tableNamePattern));
1732 
1733                        rs = s.executeQuery();
1734                    } catch (Throwable t) {
1735                                throw handleException(t);
1736                        } finally {
1737                            restoreContextStack();
1738                        }
1739 
1740                        return rs;
1741                }
1742        }
1743 
1744    /**
1745     * Get the schema names available in this database.  The results
1746     * are ordered by schema name.
1747     *
1748     * <P>The schema columns are:
1749     *  <OL>
1750     *  <li><strong>TABLE_SCHEM</strong> String =&gt; schema name</li>
1751     *  <li><strong>TABLE_CATALOG</strong> String =&gt; catalog name
1752     *  (may be <code>null</code>)</li>
1753     *  </OL>
1754     *
1755     * @return ResultSet - each row is a schema description
1756         * @exception SQLException thrown on failure.
1757     */
1758        public ResultSet getSchemas() throws SQLException {
1759                return getSchemas(null, null);
1760        }
1761 
1762    /**
1763     * Get the catalog names available in this database.  The results
1764     * are ordered by catalog name.
1765     *
1766     * <P>The catalog column is:
1767     *  <OL>
1768     *        <LI><B>TABLE_CAT</B> String => catalog name
1769     *  </OL>
1770     *
1771     * @return ResultSet - each row has a single String column that is a
1772     * catalog name
1773         * @exception SQLException thrown on failure.
1774     */
1775        public ResultSet getCatalogs() throws SQLException {
1776                return getSimpleQuery("getCatalogs");
1777        }
1778 
1779    /**
1780     * Get the table types available in this database.  The results
1781     * are ordered by table type.
1782     *
1783     * <P>The table type is:
1784     *  <OL>
1785     *        <LI><B>TABLE_TYPE</B> String => table type.  Typical types are "TABLE",
1786     *                        "VIEW",        "SYSTEM TABLE", "GLOBAL TEMPORARY",
1787     *                        "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
1788     *  </OL>
1789     *
1790     * @return ResultSet - each row has a single String column that is a
1791     * table type
1792         * @exception SQLException thrown on failure.
1793     */
1794        public ResultSet getTableTypes() throws SQLException {
1795                return getSimpleQuery("getTableTypes");
1796        }
1797 
1798    /**
1799     * Get a description of table columns available in a catalog.
1800     *
1801     * <P>Only column descriptions matching the catalog, schema, table
1802     * and column name criteria are returned.  They are ordered by
1803     * TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.
1804     *
1805     * <P>Each column description has the following columns:
1806     *  <OL>
1807     *        <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1808     *        <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1809     *        <LI><B>TABLE_NAME</B> String => table name
1810     *        <LI><B>COLUMN_NAME</B> String => column name
1811     *        <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types
1812     *        <LI><B>TYPE_NAME</B> String => Data source dependent type name
1813     *        <LI><B>COLUMN_SIZE</B> int => column size.  For char or date
1814     *            types this is the maximum number of characters, for numeric or
1815     *            decimal types this is precision.
1816     *        <LI><B>BUFFER_LENGTH</B> is not used.
1817     *        <LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits
1818     *        <LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)
1819     *        <LI><B>NULLABLE</B> int => is NULL allowed?
1820     *      <UL>
1821     *      <LI> columnNoNulls - might not allow NULL values
1822     *      <LI> columnNullable - definitely allows NULL values
1823     *      <LI> columnNullableUnknown - nullability unknown
1824     *      </UL>
1825     *        <LI><B>REMARKS</B> String => comment describing column (may be null)
1826     *         <LI><B>COLUMN_DEF</B> String => default value (may be null)
1827     *        <LI><B>SQL_DATA_TYPE</B> int => unused
1828     *        <LI><B>SQL_DATETIME_SUB</B> int => unused
1829     *        <LI><B>CHAR_OCTET_LENGTH</B> int => for char types the
1830     *       maximum number of bytes in the column
1831     *        <LI><B>ORDINAL_POSITION</B> int        => index of column in table
1832     *      (starting at 1)
1833     *        <LI><B>IS_NULLABLE</B> String => "NO" means column definitely
1834     *      does not allow NULL values; "YES" means the column might
1835     *      allow NULL values.  An empty string means nobody knows.
1836     *  </OL>
1837     *
1838     * @param catalog a catalog name; "" retrieves those without a
1839     * catalog; null means drop catalog name from the selection criteria
1840     * @param schemaPattern a schema name pattern; "" retrieves those
1841     * without a schema
1842     * @param tableNamePattern a table name pattern
1843     * @param columnNamePattern a column name pattern
1844     * @return ResultSet - each row is a column description
1845     * @see #getSearchStringEscape
1846         * @exception SQLException thrown on failure.
1847     */
1848        public ResultSet getColumns(String catalog, String schemaPattern,
1849                String tableNamePattern, String columnNamePattern)
1850                                        throws SQLException {
1851 
1852                return doGetCols(catalog, schemaPattern, tableNamePattern,
1853                        columnNamePattern, "getColumns");
1854        }
1855 
1856        /**
1857         * Get a description of table columns available in a catalog.
1858         * Same as getColumns() above, except that the result set
1859         * will conform to ODBC specifications.
1860         */
1861        public ResultSet getColumnsForODBC(String catalog, String schemaPattern,
1862                String tableNamePattern, String columnNamePattern)
1863                throws SQLException {
1864 
1865                return doGetCols(catalog, schemaPattern, tableNamePattern,
1866                        columnNamePattern, "odbc_getColumns");
1867        }
1868 
1869        /**
1870         * Does the actual work for the getColumns metadata calls.
1871         * See getColumns() method above for parameter descriptions.
1872         * @param queryName Name of the query to execute; is used
1873         *        to determine whether the result set should conform to
1874         *        JDBC or ODBC specifications.
1875         */
1876        private ResultSet doGetCols(String catalog, String schemaPattern,
1877                String tableNamePattern, String columnNamePattern,
1878                String queryName) throws SQLException {
1879 
1880                PreparedStatement s = getPreparedQuery(queryName);
1881                s.setString(1, swapNull(catalog));
1882                s.setString(2, swapNull(schemaPattern));
1883                s.setString(3, swapNull(tableNamePattern));
1884                s.setString(4, swapNull(columnNamePattern));
1885                return s.executeQuery();
1886        }
1887 
1888    /**
1889     * Get a description of the access rights for a table's columns.
1890     *
1891     * <P>Only privileges matching the column name criteria are
1892     * returned.  They are ordered by COLUMN_NAME and PRIVILEGE.
1893     *
1894     * <P>Each privilige description has the following columns:
1895     *  <OL>
1896     *        <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1897     *        <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1898     *        <LI><B>TABLE_NAME</B> String => table name
1899     *        <LI><B>COLUMN_NAME</B> String => column name
1900     *        <LI><B>GRANTOR</B> => grantor of access (may be null)
1901     *        <LI><B>GRANTEE</B> String => grantee of access
1902     *        <LI><B>PRIVILEGE</B> String => name of access (SELECT,
1903     *      INSERT, UPDATE, REFRENCES, ...)
1904     *        <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
1905     *      to grant to others; "NO" if not; null if unknown
1906     *  </OL>
1907     *
1908     * @param catalog a catalog name; "" retrieves those without a
1909     * catalog; null means drop catalog name from the selection criteria
1910     * @param schema a schema name; "" retrieves those without a schema
1911     * @param table a table name
1912     * @param columnNamePattern a column name pattern
1913     * @return ResultSet - each row is a column privilege description
1914     * @see #getSearchStringEscape
1915         * @exception SQLException thrown on failure.
1916     */
1917        public ResultSet getColumnPrivileges(String catalog, String schema,
1918                String table, String columnNamePattern) throws SQLException {
1919                PreparedStatement s = getPreparedQuery("getColumnPrivileges");
1920                s.setString(1, swapNull(catalog));
1921                s.setString(2, swapNull(schema));
1922                s.setString(3, swapNull(table));
1923                s.setString(4, swapNull(columnNamePattern));
1924                return s.executeQuery();
1925        }
1926 
1927    /**
1928     * Get a description of the access rights for each table available
1929     * in a catalog. Note that a table privilege applies to one or
1930     * more columns in the table. It would be wrong to assume that
1931     * this priviledge applies to all columns (this may be true for
1932     * some systems but is not true for all.)
1933     *
1934     * <P>Only privileges matching the schema and table name
1935     * criteria are returned.  They are ordered by TABLE_SCHEM,
1936     * TABLE_NAME, and PRIVILEGE.
1937     *
1938     * <P>Each privilige description has the following columns:
1939     *  <OL>
1940     *        <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1941     *        <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1942     *        <LI><B>TABLE_NAME</B> String => table name
1943     *        <LI><B>GRANTOR</B> => grantor of access (may be null)
1944     *        <LI><B>GRANTEE</B> String => grantee of access
1945     *        <LI><B>PRIVILEGE</B> String => name of access (SELECT,
1946     *      INSERT, UPDATE, REFRENCES, ...)
1947     *        <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
1948     *      to grant to others; "NO" if not; null if unknown
1949     *  </OL>
1950     *
1951     * @param catalog a catalog name; "" retrieves those without a
1952     * catalog; null means drop catalog name from the selection criteria
1953     * @param schemaPattern a schema name pattern; "" retrieves those
1954     * without a schema
1955     * @param tableNamePattern a table name pattern
1956     * @return ResultSet - each row is a table privilege description
1957     * @see #getSearchStringEscape
1958         * @exception SQLException thrown on failure.
1959     */
1960        public ResultSet getTablePrivileges(String catalog, String schemaPattern,
1961                                String tableNamePattern) throws SQLException {
1962                PreparedStatement s = getPreparedQuery("getTablePrivileges");
1963                s.setString(1, swapNull(catalog));
1964                s.setString(2, swapNull(schemaPattern));
1965                s.setString(3, swapNull(tableNamePattern));
1966                return s.executeQuery();
1967        }
1968 
1969    /**
1970     * Get a description of a table's optimal set of columns that
1971     * uniquely identifies a row. They are ordered by SCOPE.
1972     *
1973     * <P>Each column description has the following columns:
1974     *  <OL>
1975     *        <LI><B>SCOPE</B> short => actual scope of result
1976     *      <UL>
1977     *      <LI> bestRowTemporary - very temporary, while using row
1978     *      <LI> bestRowTransaction - valid for remainder of current transaction
1979     *      <LI> bestRowSession - valid for remainder of current session
1980     *      </UL>
1981     *        <LI><B>COLUMN_NAME</B> String => column name
1982     *        <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types
1983     *        <LI><B>TYPE_NAME</B> String => Data source dependent type name
1984     *        <LI><B>COLUMN_SIZE</B> int => precision
1985     *        <LI><B>BUFFER_LENGTH</B> int => not used
1986     *        <LI><B>DECIMAL_DIGITS</B> short         => scale
1987     *        <LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column
1988     *      like an Oracle ROWID
1989     *      <UL>
1990     *      <LI> bestRowUnknown - may or may not be pseudo column
1991     *      <LI> bestRowNotPseudo - is NOT a pseudo column
1992     *      <LI> bestRowPseudo - is a pseudo column
1993     *      </UL>
1994     *  </OL>
1995     *
1996     * @param catalogPattern a catalog name; "" retrieves those without a
1997     * catalog; null means drop catalog name from the selection criteria
1998     * @param schemaPattern a schema name; "" retrieves those without a schema
1999     * @param tablePattern a table name
2000     * @param scope the scope of interest; use same values as SCOPE
2001     * @param nullable include columns that are nullable?
2002     * @return ResultSet - each row is a column description
2003         * @exception SQLException thrown on failure.
2004     */
2005        public ResultSet getBestRowIdentifier
2006        (
2007                String catalogPattern,
2008                String schemaPattern,
2009                String tablePattern,
2010                int scope,
2011                boolean nullable
2012        ) throws SQLException
2013        {
2014                return doGetBestRowId(catalogPattern, schemaPattern, tablePattern,
2015                        scope, nullable, "");
2016        }
2017 
2018        /**
2019         * Get a description of a table's optimal set of columns that
2020         * uniquely identifies a row. They are ordered by SCOPE.
2021         * Same as getBestRowIdentifier() above, except that the result
2022         * set will conform to ODBC specifications.
2023         */
2024        public ResultSet getBestRowIdentifierForODBC(String catalogPattern,
2025                String schemaPattern, String tablePattern, int scope,
2026                boolean nullable) throws SQLException {
2027 
2028                return doGetBestRowId(catalogPattern, schemaPattern, tablePattern,
2029                        scope, nullable, "odbc_");
2030        }
2031 
2032        /**
2033         * Does the actual work for the getBestRowIdentifier metadata
2034         * calls.  See getBestRowIdentifier() method above for parameter
2035         * descriptions.
2036         * @param queryPrefix Prefix to be appended to the names of
2037         *        the queries used in this method.  This is used
2038         *        to determine whether the result set should conform to
2039         *        JDBC or ODBC specifications.
2040         */
2041        private ResultSet doGetBestRowId(String catalogPattern,
2042                String schemaPattern, String tablePattern, int scope,
2043                boolean nullable, String queryPrefix) throws SQLException {
2044 
2045                int nullableInIntForm = 0;
2046                if (nullable)
2047                        nullableInIntForm = 1;
2048      
2049                if (catalogPattern == null)
2050                {
2051                        catalogPattern = "%";
2052                }
2053                if (schemaPattern == null)
2054                {
2055                        schemaPattern = "%";
2056                }
2057                if (tablePattern == null)
2058                {
2059                        tablePattern = "%";
2060                }
2061 
2062                        PreparedStatement ps;
2063                        boolean done;
2064        
2065                        // scope value is bad, return an empty result
2066                        if (scope < 0 || scope > 2) {
2067                                ps = getPreparedQuery("getBestRowIdentifierEmpty");
2068                                return ps.executeQuery();
2069                        }
2070        
2071                        // see if there is a primary key, use it.
2072                        ps = getPreparedQuery("getBestRowIdentifierPrimaryKey");
2073                        ps.setString(1,catalogPattern);
2074                        ps.setString(2,schemaPattern);
2075                        ps.setString(3,tablePattern);
2076        
2077                        ResultSet rs = ps.executeQuery();
2078                        done = rs.next();
2079                        String constraintId = "";
2080                        if (done) {
2081                            constraintId = rs.getString(1);
2082                        }
2083        
2084                        rs.close();
2085                        ps.close();
2086        
2087                        if (done) 
2088                        {
2089                                // this one's it, do the real thing and return it.
2090                                // we don't need to check catalog, schema, table name
2091                                // or scope again.
2092                                ps = getPreparedQuery(queryPrefix + "getBestRowIdentifierPrimaryKeyColumns");
2093                                ps.setString(1,constraintId);
2094                                ps.setString(2,constraintId);
2095                                // note, primary key columns aren't nullable,
2096                                // so we skip the nullOk parameter.
2097                                return ps.executeQuery();
2098                        }
2099        
2100                        // get the unique constraint with the fewest columns.
2101                        ps = getPreparedQuery("getBestRowIdentifierUniqueConstraint");
2102                        ps.setString(1,catalogPattern);
2103                        ps.setString(2,schemaPattern);
2104                        ps.setString(3,tablePattern);
2105        
2106                        rs = ps.executeQuery();
2107                        done = rs.next();
2108                        if (done) {
2109                            constraintId = rs.getString(1);
2110                        }
2111                        // REMIND: we need to actually check for null columns
2112                        // and toss out constraints with null columns if they aren't
2113                        // desired... recode this as a WHILE returning at the
2114                        // first match or falling off the end.
2115        
2116                        rs.close();
2117                        ps.close();
2118                        if (done) 
2119                        {
2120                                // this one's it, do the real thing and return it.
2121                                ps = getPreparedQuery(queryPrefix + "getBestRowIdentifierUniqueKeyColumns");
2122                                ps.setString(1,constraintId);
2123                                ps.setString(2,constraintId);
2124                                ps.setInt(3,nullableInIntForm);
2125                                return ps.executeQuery();
2126                        }
2127        
2128        
2129                        // second-to last try -- unique index with minimal # columns
2130                        // (only non null columns if so required)
2131                        ps = getPreparedQuery("getBestRowIdentifierUniqueIndex");
2132                        ps.setString(1,catalogPattern);
2133                        ps.setString(2,schemaPattern);
2134                        ps.setString(3,tablePattern);
2135        
2136                        rs = ps.executeQuery();
2137                        done = rs.next();
2138                        long indexNum = 0;
2139                        if (done) {
2140                            indexNum = rs.getLong(1);
2141                        }
2142                        // REMIND: we need to actually check for null columns
2143                        // and toss out constraints with null columns if they aren't
2144                        // desired... recode this as a WHILE returning at the
2145                        // first match or falling off the end.
2146        
2147                        rs.close();
2148                        ps.close();
2149                        if (done) {
2150                                // this one's it, do the real thing and return it.
2151                                ps = getPreparedQuery(queryPrefix + "getBestRowIdentifierUniqueIndexColumns");
2152                                ps.setLong(1,indexNum);
2153                                ps.setInt(2,nullableInIntForm);
2154                                return ps.executeQuery();
2155                        }
2156 
2157                        // last try -- just return all columns of the table
2158                        // the not null ones if that restriction is upon us.
2159                        ps = getPreparedQuery(queryPrefix + "getBestRowIdentifierAllColumns");
2160                        ps.setString(1,catalogPattern);
2161                        ps.setString(2,schemaPattern);
2162                        ps.setString(3,tablePattern);
2163                        ps.setInt(4,scope);
2164                        ps.setInt(5,nullableInIntForm);
2165                        return ps.executeQuery();
2166        }
2167 
2168    /**
2169     * Get a description of a table's columns that are automatically
2170     * updated when any value in a row is updated.  They are
2171     * unordered.
2172     *
2173     * <P>Each column description has the following columns:
2174     *  <OL>
2175     *        <LI><B>SCOPE</B> short => is not used
2176     *        <LI><B>COLUMN_NAME</B> String => column name
2177     *        <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types
2178     *        <LI><B>TYPE_NAME</B> String => Data source dependent type name
2179     *        <LI><B>COLUMN_SIZE</B> int => precision
2180     *        <LI><B>BUFFER_LENGTH</B> int => length of column value in bytes
2181     *        <LI><B>DECIMAL_DIGITS</B> short         => scale
2182     *        <LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column
2183     *      like an Oracle ROWID
2184     *      <UL>
2185     *      <LI> versionColumnUnknown - may or may not be pseudo column
2186     *      <LI> versionColumnNotPseudo - is NOT a pseudo column
2187     *      <LI> versionColumnPseudo - is a pseudo column
2188     *      </UL>
2189     *  </OL>
2190     *
2191     * @param catalog a catalog name; "" retrieves those without a
2192     * catalog; null means drop catalog name from the selection criteria
2193     * @param schema a schema name; "" retrieves those without a schema
2194     * @param table a table name
2195     * @return ResultSet - each row is a column description
2196         * @exception SQLException thrown on failure.
2197     */
2198        public ResultSet getVersionColumns(String catalog, String schema,
2199                                String table) throws SQLException {
2200                return doGetVersionCols(catalog, schema, table, "getVersionColumns");
2201        }
2202 
2203        /**
2204         * Get a description of a table's columns that are automatically
2205         * updated when any value in a row is updated.  They are
2206         * unordered.  Same as getVersionColumns() above, except that
2207         * the result set will conform to ODBC specifications.
2208         */
2209        public ResultSet getVersionColumnsForODBC(String catalog, String schema,
2210                                String table) throws SQLException {
2211                return doGetVersionCols(catalog, schema, table, "odbc_getVersionColumns");
2212        }
2213 
2214        /**
2215         * Does the actual work for the getVersionColumns metadata
2216         * calls.  See getVersionColumns() method above for parameter
2217         * descriptions.
2218         * @param queryName Name of the query to execute; is used
2219         *        to determine whether the result set should conform to
2220         *        JDBC or ODBC specifications.
2221         */
2222        private ResultSet doGetVersionCols(String catalog, String schema,
2223                String table, String queryName) throws SQLException {
2224 
2225                PreparedStatement s = getPreparedQuery(queryName);
2226                s.setString(1, swapNull(catalog));
2227                s.setString(2, swapNull(schema));
2228                s.setString(3, swapNull(table));
2229                return s.executeQuery();
2230        }
2231 
2232    /**
2233     * check if the dictionary is at the same version as the engine. If not, 
2234     * then that means stored versions of the JDBC database metadata queries
2235     * may not be compatible with this version of the software.
2236     * This can happen if we are in soft upgrade mode. Since in soft upgrade 
2237     * mode, we can't change these stored metadata queries in a backward 
2238     * incompatible way, engine needs to read the metadata sql from 
2239     * metadata.properties or metadata_net.properties file rather than
2240     * rely on system tables.
2241     * 
2242     * @return true if we are not in soft upgrade mode
2243     * @throws SQLException
2244     */
2245        private boolean notInSoftUpgradeMode() 
2246                throws SQLException {
2247                if ( getEmbedConnection().isClosed())
2248                        throw Util.noCurrentConnection();
2249 
2250                boolean notInSoftUpgradeMode;
2251                try {
2252                        notInSoftUpgradeMode =
2253                                getLanguageConnectionContext().getDataDictionary().checkVersion(
2254                                                DataDictionary.DD_VERSION_CURRENT,null);
2255                } catch (Throwable t) {
2256                        throw handleException(t);
2257                }
2258                return notInSoftUpgradeMode;
2259        }
2260        
2261        
2262    /**
2263     * Get a description of a table's primary key columns.  They
2264     * are ordered by COLUMN_NAME.
2265     *
2266     * <P>Each primary key column description has the following columns:
2267     *  <OL>
2268     *        <LI><B>TABLE_CAT</B> String => table catalog (may be null)
2269     *        <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
2270     *        <LI><B>TABLE_NAME</B> String => table name
2271     *        <LI><B>COLUMN_NAME</B> String => column name
2272     *        <LI><B>KEY_SEQ</B> short => sequence number within primary key
2273     *        <LI><B>PK_NAME</B> String => primary key name (may be null)
2274     *  </OL>
2275     *
2276     * @param catalog a catalog name; "" retrieves those without a
2277     * catalog; null means drop catalog name from the selection criteria
2278     * @param schema a schema name pattern; "" retrieves those
2279     * without a schema
2280     * @param table a table name
2281     * @return ResultSet - each row is a primary key column description
2282         * @exception SQLException thrown on failure.
2283     */
2284        public ResultSet getPrimaryKeys(String catalog, String schema,
2285                        String table) throws SQLException {
2286                return doGetPrimaryKeys(catalog, schema, table, "getPrimaryKeys");
2287        }
2288 
2289        /**
2290         * Get a description of a table's primary key columns.  They
2291         * are ordered by COLUMN_NAME.  Same as getPrimaryKeys above,
2292         * except that the result set will conform to ODBC specifications.
2293         */
2294        public ResultSet getPrimaryKeysForODBC(String catalog, String schema,
2295                                String table) throws SQLException {
2296                return doGetPrimaryKeys(catalog, schema, table, "odbc_getPrimaryKeys");
2297        }
2298 
2299        /**
2300         * Does the actual work for the getPrimaryKeys metadata
2301         * calls.  See getPrimaryKeys() method above for parameter
2302         * descriptions.
2303         * @param queryName Name of the query to execute; is used
2304         *        to determine whether the result set should conform to
2305         *        JDBC or ODBC specifications.
2306         */
2307        private ResultSet doGetPrimaryKeys(String catalog, String schema,
2308                String table, String queryName) throws SQLException {
2309 
2310                PreparedStatement s = getPreparedQuery(queryName);
2311                s.setString(1, swapNull(catalog));
2312                s.setString(2, swapNull(schema));
2313                s.setString(3, swapNull(table));
2314                return s.executeQuery();
2315        }        
2316 
2317        /**
2318     * Get a description of the primary key columns that are
2319     * referenced by a table's foreign key columns (the primary keys
2320     * imported by a table).  They are ordered by PKTABLE_CAT,
2321     * PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ.
2322     *
2323     * <P>Each primary key column description has the following columns:
2324     *  <OL>
2325     *        <LI><B>PKTABLE_CAT</B> String => primary key table catalog
2326     *      being imported (may be null)
2327     *        <LI><B>PKTABLE_SCHEM</B> String => primary key table schema
2328     *      being imported (may be null)
2329     *        <LI><B>PKTABLE_NAME</B> String => primary key table name
2330     *      being imported
2331     *        <LI><B>PKCOLUMN_NAME</B> String => primary key column name
2332     *      being imported
2333     *        <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
2334     *        <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
2335     *        <LI><B>FKTABLE_NAME</B> String => foreign key table name
2336     *        <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
2337     *        <LI><B>KEY_SEQ</B> short => sequence number within foreign key
2338     *        <LI><B>UPDATE_RULE</B> short => What happens to
2339     *       foreign key when primary is updated:
2340     *      <UL>
2341     *      <LI> importedNoAction - do not allow update of primary
2342     *               key if it has been imported
2343     *      <LI> importedKeyCascade - change imported key to agree
2344     *               with primary key update
2345     *      <LI> importedKeySetNull - change imported key to NULL if
2346     *               its primary key has been updated
2347     *      <LI> importedKeySetDefault - change imported key to default values
2348     *               if its primary key has been updated
2349     *      <LI> importedKeyRestrict - same as importedKeyNoAction
2350     *                                 (for ODBC 2.x compatibility)
2351     *      </UL>
2352     *        <LI><B>DELETE_RULE</B> short => What happens to
2353     *      the foreign key when primary is deleted.
2354     *      <UL>
2355     *      <LI> importedKeyNoAction - do not allow delete of primary
2356     *               key if it has been imported
2357     *      <LI> importedKeyCascade - delete rows that import a deleted key
2358     *      <LI> importedKeySetNull - change imported key to NULL if
2359     *               its primary key has been deleted
2360     *      <LI> importedKeyRestrict - same as importedKeyNoAction
2361     *                                 (for ODBC 2.x compatibility)
2362     *      <LI> importedKeySetDefault - change imported key to default if
2363     *               its primary key has been deleted
2364     *      </UL>
2365     *        <LI><B>FK_NAME</B> String => foreign key name (may be null)
2366     *        <LI><B>PK_NAME</B> String => primary key name (may be null)
2367     *        <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
2368     *      constraints be deferred until commit
2369     *      <UL>
2370     *      <LI> importedKeyInitiallyDeferred - see SQL92 for definition
2371     *      <LI> importedKeyInitiallyImmediate - see SQL92 for definition
2372     *      <LI> importedKeyNotDeferrable - see SQL92 for definition
2373     *      </UL>
2374     *  </OL>
2375     *
2376     * @param catalog a catalog name; "" retrieves those without a
2377     * catalog; null means drop catalog name from the selection criteria
2378     * @param schema a schema name pattern; "" retrieves those
2379     * without a schema
2380     * @param table a table name
2381     * @return ResultSet - each row is a primary key column description
2382     * @see #getExportedKeys
2383         * @exception SQLException thrown on failure.
2384     */
2385        public ResultSet getImportedKeys(String catalog, String schema,
2386                                String table) throws SQLException {
2387                PreparedStatement s = getPreparedQuery("getImportedKeys");
2388                s.setString(1, swapNull(catalog));
2389                s.setString(2, swapNull(schema));
2390                s.setString(3, swapNull(table));
2391                return s.executeQuery();
2392        }
2393 
2394 
2395    /**
2396     * Get a description of the foreign key columns that reference a
2397     * table's primary key columns (the foreign keys exported by a
2398     * table).  They are ordered by FKTABLE_CAT, FKTABLE_SCHEM,
2399     * FKTABLE_NAME, and KEY_SEQ.
2400     *
2401     * <P>Each foreign key column description has the following columns:
2402     *  <OL>
2403     *        <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)
2404     *        <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)
2405     *        <LI><B>PKTABLE_NAME</B> String => primary key table name
2406     *        <LI><B>PKCOLUMN_NAME</B> String => primary key column name
2407     *        <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
2408     *      being exported (may be null)
2409     *        <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
2410     *      being exported (may be null)
2411     *        <LI><B>FKTABLE_NAME</B> String => foreign key table name
2412     *      being exported
2413     *        <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
2414     *      being exported
2415     *        <LI><B>KEY_SEQ</B> short => sequence number within foreign key
2416     *        <LI><B>UPDATE_RULE</B> short => What happens to
2417     *       foreign key when primary is updated:
2418     *      <UL>
2419     *      <LI> importedNoAction - do not allow update of primary
2420     *               key if it has been imported
2421     *      <LI> importedKeyCascade - change imported key to agree
2422     *               with primary key update
2423     *      <LI> importedKeySetNull - change imported key to NULL if
2424     *               its primary key has been updated
2425     *      <LI> importedKeySetDefault - change imported key to default values
2426     *               if its primary key has been updated
2427     *      <LI> importedKeyRestrict - same as importedKeyNoAction
2428     *                                 (for ODBC 2.x compatibility)
2429     *      </UL>
2430     *        <LI><B>DELETE_RULE</B> short => What happens to
2431     *      the foreign key when primary is deleted.
2432     *      <UL>
2433     *      <LI> importedKeyNoAction - do not allow delete of primary
2434     *               key if it has been imported
2435     *      <LI> importedKeyCascade - delete rows that import a deleted key
2436     *      <LI> importedKeySetNull - change imported key to NULL if
2437     *               its primary key has been deleted
2438     *      <LI> importedKeyRestrict - same as importedKeyNoAction
2439     *                                 (for ODBC 2.x compatibility)
2440     *      <LI> importedKeySetDefault - change imported key to default if
2441     *               its primary key has been deleted
2442     *      </UL>
2443     *        <LI><B>FK_NAME</B> String => foreign key name (may be null)
2444     *        <LI><B>PK_NAME</B> String => primary key name (may be null)
2445     *        <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
2446     *      constraints be deferred until commit
2447     *      <UL>
2448     *      <LI> importedKeyInitiallyDeferred - see SQL92 for definition
2449     *      <LI> importedKeyInitiallyImmediate - see SQL92 for definition
2450     *      <LI> importedKeyNotDeferrable - see SQL92 for definition
2451     *      </UL>
2452     *  </OL>
2453     *
2454     * @param catalog a catalog name; "" retrieves those without a
2455     * catalog; null means drop catalog name from the selection criteria
2456     * @param schema a schema name pattern; "" retrieves those
2457     * without a schema
2458     * @param table a table name
2459     * @return ResultSet - each row is a foreign key column description
2460     * @see #getImportedKeys
2461         * @exception SQLException thrown on failure.
2462     */
2463        public ResultSet getExportedKeys(String catalog, String schema,
2464                                String table) throws SQLException {
2465                PreparedStatement s = getPreparedQuery("getCrossReference");
2466                s.setString(1, swapNull(catalog));
2467                s.setString(2, swapNull(schema));
2468                s.setString(3, swapNull(table));
2469                s.setString(4, swapNull(null));
2470                s.setString(5, swapNull(null));
2471                s.setString(6, swapNull(null));
2472                return s.executeQuery();
2473        }
2474 
2475    /**
2476     * Get a description of the foreign key columns in the foreign key
2477     * table that reference the primary key columns of the primary key
2478     * table (describe how one table imports another's key.) This
2479     * should normally return a single foreign key/primary key pair
2480     * (most tables only import a foreign key from a table once.)  They
2481     * are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and
2482     * KEY_SEQ.
2483     *
2484     * <P>Each foreign key column description has the following columns:
2485     *  <OL>
2486     *        <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)
2487     *        <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)
2488     *        <LI><B>PKTABLE_NAME</B> String => primary key table name
2489     *        <LI><B>PKCOLUMN_NAME</B> String => primary key column name
2490     *        <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
2491     *      being exported (may be null)
2492     *        <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
2493     *      being exported (may be null)
2494     *        <LI><B>FKTABLE_NAME</B> String => foreign key table name
2495     *      being exported
2496     *        <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
2497     *      being exported
2498     *        <LI><B>KEY_SEQ</B> short => sequence number within foreign key
2499     *        <LI><B>UPDATE_RULE</B> short => What happens to
2500     *       foreign key when primary is updated:
2501     *      <UL>
2502     *      <LI> importedNoAction - do not allow update of primary
2503     *               key if it has been imported
2504     *      <LI> importedKeyCascade - change imported key to agree
2505     *               with primary key update
2506     *      <LI> importedKeySetNull - change imported key to NULL if
2507     *               its primary key has been updated
2508     *      <LI> importedKeySetDefault - change imported key to default values
2509     *               if its primary key has been updated
2510     *      <LI> importedKeyRestrict - same as importedKeyNoAction
2511     *                                 (for ODBC 2.x compatibility)
2512     *      </UL>
2513     *        <LI><B>DELETE_RULE</B> short => What happens to
2514     *      the foreign key when primary is deleted.
2515     *      <UL>
2516     *      <LI> importedKeyNoAction - do not allow delete of primary
2517     *               key if it has been imported
2518     *      <LI> importedKeyCascade - delete rows that import a deleted key
2519     *      <LI> importedKeySetNull - change imported key to NULL if
2520     *               its primary key has been deleted
2521     *      <LI> importedKeyRestrict - same as importedKeyNoAction
2522     *                                 (for ODBC 2.x compatibility)
2523     *      <LI> importedKeySetDefault - change imported key to default if
2524     *               its primary key has been deleted
2525     *      </UL>
2526     *        <LI><B>FK_NAME</B> String => foreign key name (may be null)
2527     *        <LI><B>PK_NAME</B> String => primary key name (may be null)
2528     *        <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
2529     *      constraints be deferred until commit
2530     *      <UL>
2531     *      <LI> importedKeyInitiallyDeferred - see SQL92 for definition
2532     *      <LI> importedKeyInitiallyImmediate - see SQL92 for definition
2533     *      <LI> importedKeyNotDeferrable - see SQL92 for definition
2534     *      </UL>
2535     *  </OL>
2536     *
2537     * @param primaryCatalog a catalog name; "" retrieves those without a
2538     * catalog; null means drop catalog name from the selection criteria
2539     * @param primarySchema a schema name pattern; "" retrieves those
2540     * without a schema
2541     * @param primaryTable the table name that exports the key
2542     * @param foreignCatalog a catalog name; "" retrieves those without a
2543     * catalog; null means drop catalog name from the selection criteria
2544     * @param foreignSchema a schema name pattern; "" retrieves those
2545     * without a schema
2546     * @param foreignTable the table name that imports the key
2547     * @return ResultSet - each row is a foreign key column description
2548     * @see #getImportedKeys
2549         * @exception SQLException thrown on failure.
2550     */
2551        public ResultSet getCrossReference(
2552                String primaryCatalog, String primarySchema, String primaryTable,
2553                String foreignCatalog, String foreignSchema, String foreignTable
2554                ) throws SQLException {
2555                PreparedStatement s = getPreparedQuery("getCrossReference");
2556                s.setString(1, swapNull(primaryCatalog));
2557                s.setString(2, swapNull(primarySchema));
2558                s.setString(3, swapNull(primaryTable));
2559                s.setString(4, swapNull(foreignCatalog));
2560                s.setString(5, swapNull(foreignSchema));
2561                s.setString(6, swapNull(foreignTable));
2562                return s.executeQuery();
2563        }
2564 
2565    /**
2566     * Get a description of all the standard SQL types supported by
2567     * this database. They are ordered by DATA_TYPE and then by how
2568     * closely the data type maps to the corresponding JDBC SQL type.
2569     *
2570     * <P>Each type description has the following columns:
2571     *  <OL>
2572     *        <LI><B>TYPE_NAME</B> String => Type name
2573     *        <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types
2574     *        <LI><B>PRECISION</B> int => maximum precision
2575     *        <LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal
2576     *      (may be null)
2577     *        <LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal
2578            (may be null)
2579     *        <LI><B>CREATE_PARAMS</B> String => parameters used in creating
2580     *      the type (may be null)
2581     *        <LI><B>NULLABLE</B> short => can you use NULL for this type?
2582     *      <UL>
2583     *      <LI> typeNoNulls - does not allow NULL values
2584     *      <LI> typeNullable - allows NULL values
2585     *      <LI> typeNullableUnknown - nullability unknown
2586     *      </UL>
2587     *        <LI><B>CASE_SENSITIVE</B> boolean=> is it case sensitive?
2588     *        <LI><B>SEARCHABLE</B> short => can you use "WHERE" based on this type:
2589     *      <UL>
2590     *      <LI> typePredNone - No support
2591     *      <LI> typePredChar - Only supported with WHERE .. LIKE
2592     *      <LI> typePredBasic - Supported except for WHERE .. LIKE
2593     *      <LI> typeSearchable - Supported for all WHERE ..
2594     *      </UL>
2595     *        <LI><B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned?
2596     *        <LI><B>FIXED_PREC_SCALE</B> boolean => can it be a money value?
2597     *        <LI><B>AUTO_INCREMENT</B> boolean => can it be used for an
2598     *      auto-increment value?
2599     *        <LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name
2600     *      (may be null)
2601     *        <LI><B>MINIMUM_SCALE</B> short => minimum scale supported
2602     *        <LI><B>MAXIMUM_SCALE</B> short => maximum scale supported
2603     *        <LI><B>SQL_DATA_TYPE</B> int => unused
2604     *        <LI><B>SQL_DATETIME_SUB</B> int => unused
2605     *        <LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10
2606     *  </OL>
2607     *
2608     * @return ResultSet - each row is a SQL type description
2609         * @exception SQLException thrown on failure.
2610     */
2611        public ResultSet getTypeInfo() throws SQLException {
2612                return getSimpleQuery("getTypeInfo");
2613        }
2614 
2615        /**
2616         * Get a description of all the standard SQL types supported by
2617         * this database. They are ordered by DATA_TYPE and then by how
2618         * closely the data type maps to the corresponding JDBC SQL type.
2619         * Same as getTypeInfo above, except that the result set will
2620         * conform to ODBC specifications.
2621         */
2622        public ResultSet getTypeInfoForODBC() throws SQLException {
2623                return getSimpleQuery("odbc_getTypeInfo");
2624        }
2625 
2626    /**
2627     * Get a description of a table's indices and statistics. They are
2628     * ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.
2629     *
2630     * <P>Each index column description has the following columns:
2631     *  <OL>
2632     *        <LI><B>TABLE_CAT</B> String => table catalog (may be null)
2633     *        <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
2634     *        <LI><B>TABLE_NAME</B> String => table name
2635     *        <LI><B>NON_UNIQUE</B> boolean => Can index values be non-unique?
2636     *      false when TYPE is tableIndexStatistic
2637     *        <LI><B>INDEX_QUALIFIER</B> String => index catalog (may be null);
2638     *      null when TYPE is tableIndexStatistic
2639     *        <LI><B>INDEX_NAME</B> String => index name; null when TYPE is
2640     *      tableIndexStatistic
2641     *        <LI><B>TYPE</B> short => index type:
2642     *      <UL>
2643     *      <LI> tableIndexStatistic - this identifies table statistics that are
2644     *           returned in conjuction with a table's index descriptions
2645     *      <LI> tableIndexClustered - this is a clustered index
2646     *      <LI> tableIndexHashed - this is a hashed index
2647     *      <LI> tableIndexOther - this is some other style of index
2648     *      </UL>
2649     *        <LI><B>ORDINAL_POSITION</B> short => column sequence number
2650     *      within index; zero when TYPE is tableIndexStatistic
2651     *        <LI><B>COLUMN_NAME</B> String => column name; null when TYPE is
2652     *      tableIndexStatistic
2653     *        <LI><B>ASC_OR_DESC</B> String => column sort sequence, "A" => ascending,
2654     *      "D" => descending, may be null if sort sequence is not supported;
2655     *      null when TYPE is tableIndexStatistic
2656     *        <LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatistic, then
2657     *      this is the number of rows in the table; otherwise, it is the
2658     *      number of unique values in the index.
2659     *        <LI><B>PAGES</B> int => When TYPE is  tableIndexStatisic then
2660     *      this is the number of pages used for the table, otherwise it
2661     *      is the number of pages used for the current index.
2662     *        <LI><B>FILTER_CONDITION</B> String => Filter condition, if any.
2663     *      (may be null)
2664     *  </OL>
2665     *
2666     * @param catalog a catalog name; "" retrieves those without a
2667     * catalog; null means drop catalog name from the selection criteria
2668     * @param schema a schema name pattern; "" retrieves those without a schema
2669     * @param table a table name
2670     * @param unique when true, return only indices for unique values;
2671     *     when false, return indices regardless of whether unique or not
2672     * @param approximate when true, result is allowed to reflect approximate
2673     *     or out of data values; when false, results are requested to be
2674     *     accurate
2675     * @return ResultSet - each row is an index column description
2676         * @exception SQLException thrown on failure.
2677     */
2678        public ResultSet getIndexInfo(String catalog, String schema, String table,
2679                        boolean unique, boolean approximate)
2680                                        throws SQLException {
2681                return doGetIndexInfo(catalog, schema, table, unique, approximate, "getIndexInfo");
2682        }
2683 
2684        /**
2685         * Get a description of a table's indices and statistics. They are
2686         * ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.
2687         * Same as getIndexInfo above, except that the result set will
2688         * conform to ODBC specifications.
2689         */
2690        public ResultSet getIndexInfoForODBC(String catalog, String schema, String table,
2691                boolean unique, boolean approximate) throws SQLException
2692        {
2693                return doGetIndexInfo(catalog, schema, table, unique, approximate, "odbc_getIndexInfo");
2694        }
2695 
2696        /**
2697         * Does the actual work for the getIndexInfo metadata
2698         * calls.  See getIndexInfo() method above for parameter
2699         * descriptions.
2700         * @param queryName Name of the query to execute; is used
2701         *        to determine whether the result set should conform to
2702         *        JDBC or ODBC specifications.
2703         */
2704        private ResultSet doGetIndexInfo(String catalog, String schema, String table,
2705                boolean unique, boolean approximate, String queryName)
2706                throws SQLException {
2707 
2708                int approximateInInt = 0;
2709                if (approximate) approximateInInt = 1;
2710                PreparedStatement s = getPreparedQuery(queryName);
2711                s.setString(1, swapNull(catalog));
2712                s.setString(2, swapNull(schema));
2713                s.setString(3, swapNull(table));
2714                s.setBoolean(4, unique);
2715                s.setInt(5, approximateInInt);
2716                return s.executeQuery();
2717        }
2718 
2719        /////////////////////////////////////////////////////////////////////////
2720        //
2721        //        JDBC 2.0        -        New public methods
2722        //
2723        /////////////////////////////////////////////////////////////////////////
2724 
2725    /**
2726     * JDBC 2.0
2727     *
2728     * Does the database support the given result set type?
2729     *
2730     * @param type defined in java.sql.ResultSet
2731     * @return true if so 
2732     * @see Connection
2733     */
2734        public boolean supportsResultSetType(int type) {
2735                if ((type == JDBC20Translation.TYPE_FORWARD_ONLY) ||
2736                    (type == JDBC20Translation.TYPE_SCROLL_INSENSITIVE)) {
2737                        return true;
2738                }
2739    //we don't support TYPE_SCROLL_SENSITIVE yet.
2740    return false;
2741        }
2742 
2743    /**
2744     * JDBC 2.0
2745     *
2746     * Does the database support the concurrency type in combination
2747     * with the given result set type?
2748     *
2749     * @param type defined in java.sql.ResultSet
2750     * @param concurrency type defined in java.sql.ResultSet
2751     * @return true if so 
2752     * @see Connection
2753     */
2754        public boolean supportsResultSetConcurrency(int type, int concurrency) {
2755                 if (type == JDBC20Translation.TYPE_SCROLL_SENSITIVE) {
2756                         // (TYPE_SCROLL_SENSITIVE, *)
2757                          return false;
2758                 } else {
2759                         // (FORWARD_ONLY, CONCUR_UPDATABLE)
2760                         // (FORWARD_ONLY, CONCUR_READ_ONLY)
2761                         // (TYPE_SCROLL_INSENSITIVE, CONCUR_UPDATABLE)
2762                         // (TYPE_SCROLL_INSENSITIVE, READ_ONLY)
2763                         return true;
2764                 }
2765        }
2766 
2767    /**
2768     * JDBC 2.0
2769     *
2770     * Determine whether a result set's updates are visible.
2771     *
2772     * @param type result set type, i.e. ResultSet.TYPE_XXX
2773     * @return true if updates are visible for the result set type
2774     */
2775    public boolean ownUpdatesAreVisible(int type)   {
2776                 if (type == JDBC20Translation.TYPE_SCROLL_INSENSITIVE) {
2777                         return true;
2778                 } else {
2779                         return false;
2780                 }
2781        }
2782 
2783    /**
2784     * JDBC 2.0
2785     *
2786     * Determine whether a result set's deletes are visible.
2787     *
2788     * @param type result set type, i.e. ResultSet.TYPE_XXX
2789     * @return true if deletes are visible for the result set type
2790     */
2791    public boolean ownDeletesAreVisible(int type)   {
2792                 if (type == JDBC20Translation.TYPE_SCROLL_INSENSITIVE) {
2793                         return true;
2794                 } else {
2795                         return false;
2796                 }
2797        }
2798 
2799     /**
2800      * JDBC 2.0
2801      *
2802      * Determine whether a result set's inserts are visible.
2803      *
2804      * @param type result set type, i.e. ResultSet.TYPE_XXX
2805      * @return true if inserts are visible for the result set type
2806      */
2807     public boolean ownInsertsAreVisible(int type)  {
2808                 return false;
2809          }
2810 
2811      // Since Derby materializes a forward only ResultSet incrementally, it is 
2812      // possible to see changes made by others and hence following 3 metadata 
2813      // calls will return true for forward only ResultSets.
2814 
2815      /**
2816       * JDBC 2.0
2817       *
2818       * Determine whether updates made by others are visible.
2819       *
2820       * @param type result set type, i.e. ResultSet.TYPE_XXX
2821       * @return true if updates are visible for the result set type
2822       */
2823    public boolean othersUpdatesAreVisible(int type) {
2824                if (type == JDBC20Translation.TYPE_FORWARD_ONLY)
2825                        return true;
2826                return false;
2827        }
2828 
2829    /**
2830     * JDBC 2.0
2831     *
2832     * Determine whether deletes made by others are visible.
2833     *
2834     * @param type result set type, i.e. ResultSet.TYPE_XXX
2835     * @return true if deletes are visible for the result set type
2836     */
2837    public boolean othersDeletesAreVisible(int type)  {
2838                if (type == JDBC20Translation.TYPE_FORWARD_ONLY)
2839                        return true;
2840                return false;
2841        }
2842 
2843    /**
2844     * JDBC 2.0
2845     *
2846     * Determine whether inserts made by others are visible.
2847     *
2848     * @param type result set type, i.e. ResultSet.TYPE_XXX
2849     * @return true if inserts are visible for the result set type
2850     */
2851    public boolean othersInsertsAreVisible(int type)  {
2852                if (type == JDBC20Translation.TYPE_FORWARD_ONLY)
2853                        return true;
2854                return false;
2855        }
2856 
2857    /**
2858     * JDBC 2.0
2859     *
2860     * Determine whether or not a visible row update can be detected by 
2861     * calling ResultSet.rowUpdated().
2862     *
2863     * @param type result set type, i.e. ResultSet.TYPE_XXX
2864     * @return true if updates are detected by the resultset type
2865     */
2866    public boolean updatesAreDetected(int type) {
2867                if (type == JDBC20Translation.TYPE_SCROLL_INSENSITIVE) {
2868                        return true;
2869                } else {
2870                        // For forward only resultsets, we move to before the next
2871                        // row after a update and that is why updatesAreDetected
2872                        // returns false.
2873                        return false;
2874                }
2875        }
2876 
2877    /**
2878     * JDBC 2.0
2879     *
2880     * Determine whether or not a visible row delete can be detected by
2881     * calling ResultSet.rowDeleted().  If deletesAreDetected()
2882     * returns false, then deleted rows are removed from the result set.
2883     *
2884     * @param type result set type, i.e. ResultSet.TYPE_XXX
2885     * @return true if deletes are detected by the resultset type
2886     */
2887    public boolean deletesAreDetected(int type) {
2888                if (type == JDBC20Translation.TYPE_SCROLL_INSENSITIVE) {
2889                        return true;
2890                } else {
2891                        // For forward only resultsets, we move to before the next
2892                        // row after a delete and that is why deletesAreDetected
2893                        // returns false
2894                        return false;
2895                }
2896        }
2897 
2898    /**
2899     * JDBC 2.0
2900     *
2901     * Determine whether or not a visible row insert can be detected
2902     * by calling ResultSet.rowInserted().
2903     *
2904     * @param type result set type, i.e. ResultSet.TYPE_XXX
2905     * @return true if inserts are detected by the resultset type
2906     */
2907    public boolean insertsAreDetected(int type) {
2908                  return false;
2909        }
2910 
2911    /**
2912     * JDBC 2.0
2913     *
2914     * Return true if the driver supports batch updates, else return false.
2915     *
2916     */
2917    public boolean supportsBatchUpdates() {
2918                  return true;
2919        }
2920 
2921    /**
2922     * JDBC 2.0
2923     *
2924     * Get a description of the user-defined types defined in a particular
2925     * schema.  Schema specific UDTs may have type JAVA_OBJECT, STRUCT, 
2926     * or DISTINCT.
2927     *
2928     * <P>Only types matching the catalog, schema, type name and type  
2929     * criteria are returned.  They are ordered by DATA_TYPE, TYPE_SCHEM 
2930     * and TYPE_NAME.  The type name parameter may be a fully qualified 
2931     * name.  In this case, the catalog and schemaPattern parameters are
2932     * ignored.
2933     *
2934     * <P>Each type description has the following columns:
2935     *  <OL>
2936     *        <LI><B>TYPE_CAT</B> String => the type's catalog (may be null)
2937     *        <LI><B>TYPE_SCHEM</B> String => type's schema (may be null)
2938     *        <LI><B>TYPE_NAME</B> String => type name
2939     *  <LI><B>CLASS_NAME</B> String => Java class name
2940     *        <LI><B>DATA_TYPE</B> String => type value defined in java.sql.Types.  
2941     *  One of JAVA_OBJECT, STRUCT, or DISTINCT
2942     *        <LI><B>REMARKS</B> String => explanatory comment on the type
2943     *  </OL>
2944     *
2945     * <P><B>Note:</B> If the driver does not support UDTs then an empty
2946     * result set is returned.
2947     *
2948     * @param catalog a catalog name; "" retrieves those without a
2949     * catalog; null means drop catalog name from the selection criteria
2950     * @param schemaPattern a schema name pattern; "" retrieves those
2951     * without a schema
2952     * @param typeNamePattern a type name pattern; may be a fully qualified
2953     * name
2954     * @param types a list of user-named types to include (JAVA_OBJECT, 
2955     * STRUCT, or DISTINCT); null returns all types 
2956     * @return ResultSet - each row is a type description
2957     * @exception SQLException if a database-access error occurs.
2958     */
2959    public ResultSet getUDTs(String catalog, String schemaPattern, 
2960                      String typeNamePattern, int[] types)
2961      throws SQLException {
2962      //we don't have support for catalog names
2963      //we don't have java class types per schema, instead it's per database and hence
2964      //we ignore schemapattern.
2965      //the only type of user-named types we support are JAVA_OBJECT
2966      synchronized (getConnectionSynchronization()) {
2967      setupContextStack();
2968      ResultSet rs = null;
2969      int getClassTypes = 0;
2970      try {
2971        String queryText = getQueryDescriptions(false).getProperty("getUDTs");
2972 
2973        if (types != null  &&  types.length >= 1) {
2974          for (int i=0; i<types.length; i++){
2975            if (types[i] == java.sql.Types.JAVA_OBJECT)
2976              getClassTypes = 1;
2977          }
2978        } else
2979          getClassTypes = 1;
2980 
2981        PreparedStatement s =
2982          getEmbedConnection().prepareMetaDataStatement(queryText);
2983 
2984        s.setInt(1, java.sql.Types.JAVA_OBJECT);
2985        s.setString(2, catalog);
2986        s.setString(3, schemaPattern);
2987        s.setString(4, swapNull(typeNamePattern));
2988        s.setInt(5, getClassTypes);
2989 
2990        rs = s.executeQuery();
2991      } finally {
2992        restoreContextStack();
2993      }
2994      return rs;
2995    }
2996        }
2997 
2998    /**
2999     * JDBC 2.0
3000     *
3001     * Return the connection that produced this metadata object.
3002     *
3003     */
3004    public Connection getConnection() {
3005                  return getEmbedConnection().getApplicationConnection();
3006        }
3007 
3008        /**
3009    Following methods are for the new JDBC 3.0 methods in java.sql.DatabaseMetaData
3010    (see the JDBC 3.0 spec). We have the JDBC 3.0 methods in Local20
3011    package, so we don't have to have a new class in Local30.
3012    The new JDBC 3.0 methods don't make use of any new JDBC3.0 classes and
3013    so this will work fine in jdbc2.0 configuration.
3014        */
3015 
3016        /////////////////////////////////////////////////////////////////////////
3017        //
3018        //        JDBC 3.0        -        New public methods
3019        //
3020        /////////////////////////////////////////////////////////////////////////
3021 
3022        /**
3023    * JDBC 3.0
3024    *
3025    * Retrieves whether this database supports statement pooling.
3026    *
3027    * @return true if statement pooling is supported; false otherwise
3028        */
3029        public boolean supportsStatementPooling()
3030        {
3031                return false;
3032        }
3033 
3034        /**
3035    * JDBC 3.0
3036    *
3037    * Retrieves whether this database supports savepoints.
3038    *
3039    * @return true if savepoints are supported; false otherwise
3040        */
3041        public boolean supportsSavepoints()
3042        {
3043                return true;
3044        }
3045 
3046        /**
3047    * JDBC 3.0
3048    *
3049    * Retrieves whether this database supports named parameters to callable statements.
3050    *
3051    * @return true if named parameters are supported; false otherwise
3052        */
3053        public boolean supportsNamedParameters()
3054        {
3055                return false;
3056        }
3057 
3058        /**
3059    * JDBC 3.0
3060    *
3061    * Retrieves whether it is possible to have multiple ResultSet objects returned from a
3062    * CallableStatement object simultaneously.
3063    *
3064    * @return true if a CallableStatement object can return multiple ResultSet objects
3065    * simultaneously; false otherwise
3066        */
3067        public boolean supportsMultipleOpenResults()
3068        {
3069                return true;
3070        }
3071 
3072        /**
3073    * JDBC 3.0
3074    *
3075    * Retrieves whether auto-generated keys can be retrieved after a statement
3076    * has been executed.
3077    *
3078    * @return true if auto-generated keys can be retrieved after a statement has
3079    * executed; false otherwise
3080        */
3081        public boolean supportsGetGeneratedKeys()
3082        {
3083               /*
3084                * Currently reverting the returned value to false until there 
3085                * is more support for autogenerated keys in Derby.
3086                * (such as support for specifying the returned columns for
3087                * the autogenerated key)
3088                */
3089                return false;
3090        }
3091 
3092        /**
3093    * JDBC 3.0
3094    *
3095    * Retrieves whether this database supports the given result set holdability.
3096    *
3097    * @param holdability - one of the following constants:
3098    * ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT
3099    * @return true if so; false otherwise
3100    * executed; false otherwise
3101        */
3102        public boolean supportsResultSetHoldability(int holdability)
3103        {
3104                return true;
3105        }
3106 
3107        /**
3108    * JDBC 3.0
3109    *
3110    * Retrieves the default holdability of this ResultSet object.
3111    *
3112    * @return the default holdability which is ResultSet.HOLD_CURSORS_OVER_COMMIT
3113        */
3114        public int getResultSetHoldability()
3115  {
3116                return JDBC30Translation.HOLD_CURSORS_OVER_COMMIT;
3117        }
3118 
3119        /**
3120    * JDBC 3.0
3121    *
3122    * Retrieves the major version number of the underlying database.
3123    *
3124    * @return the underlying database's major version
3125        */
3126        public int getDatabaseMajorVersion()
3127        {
3128                ProductVersionHolder pvh = Monitor.getMonitor().getEngineVersion();
3129                if (pvh == null)
3130                {
3131                  return -1;
3132                }
3133                return pvh.getMajorVersion();
3134        }
3135 
3136        /**
3137    * JDBC 3.0
3138    *
3139    * Retrieves the minor version number of the underlying database.
3140    *
3141    * @return the underlying database's minor version
3142        */
3143        public int getDatabaseMinorVersion()
3144        {
3145                ProductVersionHolder pvh = Monitor.getMonitor().getEngineVersion();
3146                if (pvh == null)
3147                {
3148                  return -1;
3149                }
3150                return pvh.getMinorVersion();
3151        }
3152 
3153        /**
3154    * JDBC 3.0
3155    *
3156    * Retrieves the major JDBC version number for this driver.
3157    *
3158    * @return JDBC version major number
3159        */
3160        public int getJDBCMajorVersion()
3161        {
3162                return 3;
3163        }
3164 
3165        /**
3166    * JDBC 3.0
3167    *
3168    * Retrieves the minor JDBC version number for this driver.
3169    *
3170    * @return JDBC version minor number
3171        */
3172        public int getJDBCMinorVersion()
3173        {
3174                return 0;
3175        }
3176 
3177        /**
3178    * JDBC 3.0
3179    *
3180    * Indicates whether the SQLSTATEs returned by SQLException.getSQLState
3181    * is X/Open (now known as Open Group) SQL CLI or SQL99.
3182    *
3183    * @return the type of SQLSTATEs, one of: sqlStateXOpen or sqlStateSQL99
3184        */
3185        public int getSQLStateType()
3186        {
3187                return JDBC30Translation.SQL_STATE_SQL99;
3188        }
3189 
3190        /**
3191    * JDBC 3.0
3192    *
3193    * Indicates whether updates made to a LOB are made on a copy or
3194    * directly to the LOB.
3195    *
3196    * @return true if updates are made to a copy of the LOB; false if
3197    * updates are made directly to the LOB
3198    * @exception SQLException Feature not implemented for now.
3199        */
3200        public boolean locatorsUpdateCopy()
3201    throws SQLException
3202        {
3203                return false;
3204        }
3205 
3206        /**
3207    * JDBC 3.0
3208    *
3209    * Retrieves a description of the user-defined type (UDT) hierarchies defined
3210    * in a particular schema in this database. Only the immediate super type/ sub type
3211    * relationship is modeled.
3212    *
3213    * @param catalog - a catalog name; "" retrieves those without a catalog;
3214    * null means drop catalog name from the selection criteria
3215    * @param schemaPattern - a schema name pattern; "" retrieves those without a schema
3216    * @param typeNamePattern - a UDT name pattern; may be a fully-qualified name
3217    * @return a ResultSet object in which a row gives information about the designated UDT
3218    * @exception SQLException Feature not implemented for now.
3219        */
3220        public ResultSet getSuperTypes(String catalog, String schemaPattern, String typeNamePattern)
3221    throws SQLException
3222        {
3223                return getSimpleQuery("getSuperTypes");
3224        }
3225 
3226        /**
3227    * JDBC 3.0
3228    *
3229    * Retrieves a description of the table hierarchies defined in a particular
3230    * schema in this database.
3231    *
3232    * @param catalog - a catalog name; "" retrieves those without a catalog;
3233    * null means drop catalog name from the selection criteria
3234    * @param schemaPattern - a schema name pattern; "" retrieves those without a schema
3235    * @param typeNamePattern - a UDT name pattern; may be a fully-qualified name
3236    * @return a ResultSet object in which each row is a type description
3237    * @exception SQLException if a database access error occurs
3238        */
3239        public ResultSet getSuperTables(String catalog, String schemaPattern, String typeNamePattern)
3240    throws SQLException
3241        {
3242                return getSimpleQuery("getSuperTables");
3243        }
3244 
3245        /**
3246    * JDBC 3.0
3247    *
3248    * Retrieves a description of the given attribute of the given type for a
3249    * user-defined type (UDT) that is available in the given schema and catalog.
3250    *
3251    * @param catalog - a catalog name; must match the catalog name as it is
3252    * stored in the database; "" retrieves those without a catalog; null means that
3253    * the catalog name should not be used to narrow the search
3254    * @param schemaPattern - a schema name pattern; "" retrieves those without a schema;
3255    * null means that the schema name should not be used to narrow the search
3256    * @param typeNamePattern - a type name pattern; must match the type name as it is
3257    * stored in the database
3258    * @param attributeNamePattern - an attribute name pattern; must match the attribute
3259    * name as it is declared in the database
3260    * @return a ResultSet object in which each row is a type description
3261    * @exception SQLException if a database access error occurs.
3262        */
3263        public ResultSet getAttributes(String catalog, String schemaPattern,
3264  String typeNamePattern, String attributeNamePattern)
3265    throws SQLException
3266        {
3267        return getSimpleQuery("getAttributes");
3268        }
3269        
3270    /////////////////////////////////////////////////////////////////////////
3271    //
3272    //  JDBC 4.0 - New public methods
3273    //
3274    /////////////////////////////////////////////////////////////////////////
3275 
3276    /**
3277     * JDBC 4.0
3278     *
3279     * <p>Returns a list of the client info properties supported by
3280     * the driver. The result set contains the following columns:
3281     *
3282     * <p>
3283     * <ol>
3284     *  <li>NAME String=&gt; The name of the client info property.</li>
3285     *  <li>MAX_LEN int=&gt; The maximum length of the value for the
3286     *      property.</li>
3287     *  <li>DEFAULT_VALUE String=&gt; The default value of the property.</li>
3288     *  <li>DESCRIPTION String=&gt; A description of the property.</li>
3289     * </ol>
3290     *
3291     * <p>The <code>ResultSet</code> is sorted by the NAME column.
3292     *
3293     * @return A <code>ResultSet</code> object; each row is a
3294     * supported client info property
3295     * @exception SQLException if an error occurs
3296     */
3297    public ResultSet getClientInfoProperties() throws SQLException {
3298        return getSimpleQuery("getClientInfoProperties");
3299    }
3300 
3301    /**
3302     * JDBC 4.0
3303     *
3304     * <p>Get the schema names available in this database. The results
3305     * are ordered by schema name.
3306     *
3307     * <p>The schema columns are:
3308     *  <ol>
3309     *  <li><strong>TABLE_SCHEM</strong> String =&gt; schema name</li>
3310     *  <li><strong>TABLE_CATALOG</strong> String =&gt; catalog name
3311     *  (may be <code>null</code>)</li>
3312     *  </ol>
3313     *
3314     * @param catalog catalog name used to narrow down the search; ""
3315     * means no catalog, <code>null</code> means any catalog
3316     * @param schemaPattern schema name used to narrow down the
3317     * search, <code>null</code> means schema name should not be used
3318     * to narrow down search
3319     * @return a <code>ResultSet</code> object in which each row is a
3320     * schema description
3321     * @exception SQLException if a database error occurs
3322     */
3323    public ResultSet getSchemas(String catalog, String schemaPattern)
3324        throws SQLException
3325    {
3326        PreparedStatement s = getPreparedQuery("getSchemas");
3327        s.setString(1, swapNull(catalog));
3328        s.setString(2, swapNull(schemaPattern));
3329        return s.executeQuery();
3330    }
3331 
3332        //////////////////////////////////////////////////////////////
3333        //
3334        // MISC 
3335        //
3336        //////////////////////////////////////////////////////////////
3337        
3338    /**
3339     * Get metadata that the client driver will cache. The metadata is
3340     * fetched using SYSIBM.METADATA (found in metadata_net.properties).
3341     *
3342     * @return the result set returned by SYSIBM.METADATA
3343     * @exception SQLException if a database error occurs
3344     */
3345    public ResultSet getClientCachedMetaData() throws SQLException {
3346        return getSimpleQuery("METADATA", true);
3347    }
3348 
3349        /*
3350         * utility helper routines:
3351         */
3352 
3353    /**
3354     * Execute a query in metadata.properties (or SPS in the SYS
3355     * schema) or metadata_net.properties (or SPS in the SYSIBM
3356     * schema).
3357     *
3358     * @param nameKey the name of the query
3359     * @param net if <code>true</code>, execute a query in
3360     * metadata_net.properties; otherwise, execute a query in
3361     * metadata.properties
3362     * @return a <code>ResultSet</code> value
3363     * @exception SQLException if a database error occurs
3364     */
3365    private ResultSet getSimpleQuery(String nameKey, boolean net)
3366        throws SQLException
3367        {
3368                PreparedStatement ps = getPreparedQuery(nameKey, net);
3369                if (ps == null)
3370                        return null;
3371        
3372                return ps.executeQuery();
3373        }
3374 
3375    /**
3376     * Execute a query in metadata.properties, or an SPS in the SYS
3377     * schema.
3378     *
3379     * @param nameKey the name of the query
3380     * @return a <code>ResultSet</code> value
3381     * @exception SQLException if a database error occurs
3382     */
3383    protected ResultSet getSimpleQuery(String nameKey) throws SQLException {
3384        return getSimpleQuery(nameKey, false);
3385    }
3386 
3387    /**
3388     * Get a stored prepared statement from the system tables.
3389     *
3390     * @param nameKey the name of the query
3391     * @param net if <code>true</code>, find query in SYSIBM schema;
3392     * otherwise, find query in SYS schema
3393     * @return a <code>PreparedStatement</code> value
3394     * @exception SQLException if a database error occurs
3395     */
3396    private PreparedStatement getPreparedQueryUsingSystemTables(String nameKey,
3397                                                                boolean net)
3398        throws SQLException 
3399        {
3400                synchronized (getConnectionSynchronization())
3401                {
3402                        setupContextStack();
3403                        PreparedStatement ps = null;
3404 
3405                        try
3406                        {
3407                                String queryText =
3408                                        getQueryDescriptions(net).getProperty(nameKey);
3409                                if (queryText == null)
3410                                {
3411                    throw Util.notImplemented(nameKey);
3412                                }
3413                                
3414                ps = prepareSPS(nameKey, queryText, net);
3415                        }
3416 
3417                        catch (Throwable t) 
3418                        {
3419                                throw handleException(t);
3420                        }
3421 
3422                        finally 
3423                        {
3424                            restoreContextStack();
3425                        }
3426                        return ps;
3427                }
3428        }
3429 
3430        /**
3431         * Either get the prepared query for the metadata call from the
3432         * system tables, or from the metadata.properties or
3433         * metadata_net.properties file.
3434         * In soft upgrade mode, the queries stored in the system tables
3435         * might not be upto date with the Derby engine release because
3436         * system tables can't be modified in backward incompatible way in
3437         * soft upgrade mode. Because of this, if the database is in 
3438         * soft upgrade mode, get the queries from metadata.properties
3439         * file rather than from the system tables.
3440         *
3441         * Getting queries from metadata(_net).properties might cause problems
3442         * if system catalogs have been changed between versions either by
3443         * addition of columns or have new catalogs. To continue
3444         * to support soft upgrade from older versions of database, find
3445         * query that most closely matches database dictionary version.
3446         *
3447         * @param queryName Name of the metadata query for which we need
3448         * a prepared statement
3449         * @param net if <code>true</code>, use metadata_net.properties
3450         * instead of metadata.properties
3451         * @return PreparedStatement
3452         * @exception SQLException if a database error occurs
3453         */
3454        private PreparedStatement getPreparedQuery(String queryName,
3455                                                                                           boolean net)
3456                        throws SQLException {
3457                PreparedStatement s;
3458                //We can safely goto system table since we are not in soft upgrade
3459                //mode and hence metadata sql in system tables are uptodate
3460                //with this Derby release.
3461                if (notInSoftUpgradeMode())
3462                        s = getPreparedQueryUsingSystemTables(queryName, net);
3463                else {
3464                        try {
3465                                //Can't use stored prepared statements because we are in soft upgrade
3466                                //mode and hence need to get metadata sql from metadata.properties file 
3467                                //or metadata_net.properties
3468                                String queryText = getQueryFromDescription(queryName, net);
3469                                s = getEmbedConnection().prepareMetaDataStatement(queryText);
3470                        } catch (Throwable t) {
3471                                throw handleException(t);
3472                        } 
3473                }
3474                return s;
3475        }        
3476 
3477    /**
3478     * Get a prepared query from system tables or metadata.properties.
3479     *
3480     * @param queryName name of the query
3481     * @return a <code>PreparedStatement</code> value
3482     * @exception SQLException if a database error occurs
3483     */
3484    protected PreparedStatement getPreparedQuery(String queryName)
3485        throws SQLException
3486    {
3487        return getPreparedQuery(queryName, false);
3488    }
3489 
3490        /**
3491         * Given a queryName, find closest match in queryDescriptions. This method
3492         * should be called in soft-upgrade mode only, where current software version
3493         * doesn't match dictionary version. For these cases, there may be
3494         * multiple entries in queryDescriptions for given queryName. Find a
3495         * version of the query that closely matches dictionary version.
3496         *
3497         * This method is currently coded to handle two specific queries,
3498         * getColumnPrivileges and getTablePrivileges. Derby databases that are 10.1
3499         * or earlier will not have new system tables added for 10.2 for privileges.
3500         * 
3501         * It should be possible to automate finding closest match by generating
3502         * all Major_Minor versions between software version and dictionary version
3503         * and try each one from Dictionary version to current version. Since only
3504         * needed for two queries, overhead may not be worth it yet.
3505         *
3506         * @param queryName name of the query
3507         * @param net if <code>true</code>, get the query from
3508         * metadata_net.properties instead of metadata.properties
3509         * @return the query text
3510         * @exception StandardException if an error occurs
3511         */
3512        private String getQueryFromDescription(String queryName, boolean net)
3513                throws StandardException
3514        {
3515                DataDictionary dd = getLanguageConnectionContext().getDataDictionary();
3516 
3517                // If dictionary version is below 10.2, special case
3518                // getColumnPrivileges and getTablePrivileges since new system tables
3519                // for privileges wouldn't be present.
3520                if (!dd.checkVersion(DataDictionary.DD_VERSION_DERBY_10_2, null))
3521                {
3522                        if (queryName.equals("getColumnPrivileges"))
3523                                queryName = "getColumnPrivileges_10_1";
3524 
3525                        if (queryName.equals("getTablePrivileges"))
3526                                queryName = "getTablePrivileges_10_1";
3527                }
3528 
3529                return getQueryDescriptions(net).getProperty(queryName);
3530        }
3531 
3532        /*
3533        ** Given a SPS name and a query text it returns a 
3534        ** java.sql.PreparedStatement for the SPS. If the SPS
3535        ** doeesn't exist is created.
3536        ** 
3537        */
3538        private PreparedStatement prepareSPS(String        spsName, 
3539                                                                                 String        spsText,
3540                                                                                 boolean net)
3541                throws StandardException, SQLException
3542        {
3543 
3544                LanguageConnectionContext lcc = getLanguageConnectionContext();
3545 
3546                /* We now need to do this in sub transaction because we could possibly recompile SPS
3547                 * later, and the recompile is in a sub transaction, and will update the SYSSTATEMENTS
3548                 * entry.  Don't want to block.
3549                 */
3550                lcc.beginNestedTransaction(true);
3551 
3552                DataDictionary dd = getLanguageConnectionContext().getDataDictionary();
3553                SPSDescriptor spsd = dd.getSPSDescriptor(
3554                                                                                spsName, 
3555                                                                                net ? dd.getSysIBMSchemaDescriptor() :
3556                                                                                dd.getSystemSchemaDescriptor());
3557                lcc.commitNestedTransaction();
3558 
3559                if (spsd == null)
3560                {
3561                        throw Util.notImplemented(spsName);
3562                }
3563 
3564                /* manish:
3565                   There should be a nicer way of getting a 
3566                   java.sql.PreparedStatement from an SPS descriptor!
3567                */
3568                /*
3569                ** It is unnecessarily expensive to get the
3570                ** the statement, and then send an EXECUTE
3571                ** statement, but we have no (easy) way of turning
3572                ** the statement into a java.sql.PreparedStatement.
3573                */        
3574                String queryText =
3575                        "EXECUTE STATEMENT " + (net ? "SYSIBM" : "SYS") +
3576                        ".\"" + spsName + "\"";
3577                return getEmbedConnection().prepareMetaDataStatement(queryText);
3578 
3579        }
3580 
3581        static final protected String swapNull(String s) {
3582                return (s == null ? "%" : s);
3583        }
3584 
3585        /**
3586          *        Gets the constant action factory 
3587          *
3588          *        @return        the constant action factory.
3589          *
3590          * @exception StandardException                Thrown on failur4e
3591          */
3592        private GenericConstantActionFactory        getGenericConstantActionFactory()
3593                throws StandardException
3594        {
3595                if ( constantActionFactory == null )
3596                {
3597                        GenericExecutionFactory        execFactory = (GenericExecutionFactory)
3598                                getLanguageConnectionContext().getLanguageConnectionFactory().getExecutionFactory();
3599                        constantActionFactory = execFactory.getConstantActionFactory();
3600                }
3601 
3602                return        constantActionFactory;
3603        }
3604 
3605        /**
3606          *        Gets the LanguageConnectionContext for this connection.
3607          *
3608          *        @return        the lcc for this connection
3609          *
3610          */
3611        private        LanguageConnectionContext        getLanguageConnectionContext()
3612        {
3613                return getEmbedConnection().getLanguageConnection();
3614        }
3615 
3616        /*
3617        ** Priv block code, moved out of the old Java2 version.
3618        */
3619 
3620    /**
3621     * Loads the query descriptions from metadata.properties and
3622     * metadata_net.properties into <code>queryDescriptions</code> and
3623     * <code>queryDescriptions_net</code>.
3624     */
3625    private void loadQueryDescriptions() {
3626        java.security.AccessController.doPrivileged(this);
3627    }
3628 
3629        /**
3630         * Performs a privileged action. Reads the query descriptions.
3631         *
3632         * @return <code>null</code>
3633         */
3634        public final Object run() {
3635                // SECURITY PERMISSION - IP3
3636                PBloadQueryDescriptions();
3637                return null;
3638        }
3639 
3640}

[all classes][org.apache.derby.impl.jdbc]
EMMA 2.0.5312 (C) Vladimir Roubtsov