KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hsqldb > jdbc > jdbcDatabaseMetaData


1 /* Copyright (c) 2001-2005, The HSQL Development Group
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of the HSQL Development Group nor the names of its
15  * contributors may be used to endorse or promote products derived from this
16  * software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
22  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */

30
31
32 package org.hsqldb.jdbc;
33
34 import java.sql.Connection JavaDoc;
35 import java.sql.DatabaseMetaData JavaDoc;
36 import java.sql.ResultSet JavaDoc;
37 import java.sql.SQLException JavaDoc;
38
39 import org.hsqldb.Column;
40 import org.hsqldb.Library;
41 import org.hsqldb.Trace;
42 import org.hsqldb.lib.StringUtil;
43 import org.hsqldb.persist.HsqlDatabaseProperties;
44
45 // fredt@users 20020320 - patch 1.7.0 - JDBC 2 support and error trapping
46
// JDBC 2 methods can now be called from jdk 1.1.x - see javadoc comments
47
// boucherb@users 20020509 - added "throws SQLException" to all methods where
48
// it was missing here but specified in the java.sql.DatabaseMetaData interface,
49
// updated generic documentation to JDK 1.4, and added JDBC3 methods and docs
50
// boucherb@users and fredt@users 20020409/20020505 extensive review and update
51
// of docs and behaviour to comply with previous and latest java.sql
52
// specification
53
// boucherb@users 2002-20030121 - extensive rewrite to support new
54
// 1.7.2 metadata features.
55
// boucherb@users 20040422 - doc 1.7.2 - javadoc updates toward 1.7.2 final
56
// boucherb@users 200404xx - misc changes
57
// fredt@users 20050505 - patch 1.8.0 - enforced JDBC rules for non-pattern params
58

59 /** Comprehensive information about the database as a whole.
60  * <P>
61  * This interface is implemented by driver vendors to let users know the
62  * capabilities of a Database Management System (DBMS) in combination with
63  * the driver based on JDBC<sup><font size=-2>TM</font></sup> technology
64  * ("JDBC driver") that is used with it. Different relational DBMSs often
65  * support different features, implement features in different ways, and use
66  * different data types. In addition, a driver may implement a feature on
67  * top of what the DBMS offers. Information returned by methods in this
68  * interface applies to the capabilities of a particular driver and a
69  * particular DBMS working together. Note that as used in this documentation,
70  * the term "database" is used generically to refer to both the driver and DBMS.
71  * <P>
72  * A user for this interface is commonly a tool that needs to discover how to
73  * deal with the underlying DBMS. This is especially true for applications
74  * that are intended to be used with more than one DBMS. For example, a tool
75  * might use the method <code>getTypeInfo</code> to find out what data types
76  * can be used in a <code>CREATE TABLE</code> statement. Or a user might call
77  * the method <code>supportsCorrelatedSubqueries</code> to see if it is possible
78  * to use a correlated subquery or <code>supportsBatchUpdates</code> to see if
79  * it is possible to use batch updates.
80  * <P>
81  * Some <code>DatabaseMetaData</code> methods return lists of information
82  * in the form of <code>ResultSet</code> objects. Regular <code>ResultSet</code>
83  * methods, such as <code>getString</code> and <code>getInt</code>, can be used
84  * to retrieve the data from these <code>ResultSet</code> objects. If a given
85  * form of metadata is not available, the <code>ResultSet</code> getter methods
86  * throw an <code>SQLException</code>.
87  * <P>
88  * Some <code>DatabaseMetaData</code> methods take arguments that are
89  * String patterns. These arguments all have names such as fooPattern.
90  * Within a pattern String, "%" means match any substring of 0 or more
91  * characters, and "_" means match any one character. Only metadata
92  * entries matching the search pattern are returned. If a search pattern
93  * argument is set to <code>null</code>, that argument's criterion will
94  * be dropped from the search.
95  * <P>
96  * A method that gets information about a feature that the driver does not
97  * support will throw an <code>SQLException</code>.
98  * In the case of methods that return a <code>ResultSet</code>
99  * object, either a <code>ResultSet</code> object (which may be empty) is
100  * returned or an <code>SQLException</code> is thrown.<p>
101  *
102  * <!-- start release-specific documentation -->
103  * <div class="ReleaseSpecificDocumentation">
104  * <h3>HSQLDB-Specific Information:</h3> <p>
105  *
106  * Starting with HSQLDB 1.7.2, an option is provided to allow alternate
107  * system table production implementations. In this distribution, there are
108  * three implementations whose behaviour ranges from producing no system
109  * tables at all to producing a richer and more complete body of information
110  * about an HSQLDB database than was previously available. The information
111  * provided through the default implementation is, unlike previous
112  * versions, accessible to all database users, regardless of admin status.
113  * This is now possible because the table content it produces for each
114  * user is pre-filtered, based on the user's access rights. That is, each
115  * system table now acts like a security-aware View.<p>
116  *
117  * The process of installing a system table production class is transparent and
118  * occurs dynamically at runtime during the opening sequence of a
119  * <code>Database</code> instance, in the newDatabaseInformation() factory
120  * method of the revised DatabaseInformation class, using the following
121  * steps: <p>
122  *
123  * <div class="GeneralExample">
124  * <ol>
125  * <li>If a class whose fully qualified name is org.hsqldb.DatabaseInformationFull
126  * can be found and it has an accesible constructor that takes an
127  * org.hsqldb.Database object as its single parameter, then an instance of
128  * that class is reflectively instantiated and is used by the database
129  * instance to produce its system tables. <p>
130  *
131  * <li>If 1.) fails, then the process is repeated, attempting to create an
132  * instance of org.hsqldb.DatabaseInformationMain (which provides just the
133  * core set of system tables required to service this class, but now does
134  * so in a more security aware and comprehensive fashion). <p>
135  *
136  * <li>If 2.) fails, then an instance of org.hsqldb.DatabaseInformation is
137  * installed (that, by default, produces no system tables, meaning that
138  * calls to all related methods in this class will fail, throwing an
139  * SQLException stating that a required system table is not found). <p>
140  *
141  * </ol>
142  * </div> <p>
143  *
144  * The process of searching for alternate implementations of database
145  * support classes, ending with the installation of a minimal but functional
146  * default will be refered to henceforth as <i>graceful degradation</i>.
147  * This process is advantageous in that it allows developers and administrators
148  * to easily choose packaging options, simply by adding to or deleting concerned
149  * classes from an HSQLDB installation, without worry over providing complex
150  * initialization properties or disrupting the core operation of the engine.
151  * In this particular context, <i>graceful degradation</i> allows easy choices
152  * regarding database metadata, spanning the range of full (design-time),
153  * custom-written, minimal (production-time) or <CODE>null</CODE>
154  * (space-constrained) system table production implementations. <p>
155  *
156  * In the default full implementation, a number of new system tables are
157  * provided that, although not used directly by this class, present previously
158  * unavailable information about the database, such as about its triggers and
159  * aliases. <p>
160  *
161  * In order to better support graphical database exploration tools and as an
162  * experimental intermediate step toward more fully supporting SQL9n and
163  * SQL200n, the default installed DatabaseInformation implementation
164  * is also capable of reporting pseudo name space information, such as
165  * the catalog (database URI) of database objects. <p>
166  *
167  * The catalog reporting feature is turned off by default but
168  * can be turned on by providing the appropriate entries in the database
169  * properties file (see the advanced topics section of the product
170  * documentation). <p>
171  *
172  * When the feature is turned on, catalog is reported using
173  * the following conventions: <p>
174  *
175  * <ol>
176  * <li>All objects are reported as having a catalog equal to the URI of the
177  * database, which is equivalent to the catenation of the
178  * <b>&lt;type&gt;</b> and <b>&lt;path&gt;</b> portions of the HSQLDB
179  * internal JDBC connection URL.<p>
180  *
181  * Examples: <p>
182  *
183  * <pre class="JavaCodeExample">
184  * <span class="JavaStringLiteral">&quot;jdbc:hsqldb:file:test&quot;</span> => <span class="JavaStringLiteral">&quot;file:test&quot;</span>
185  * <span class="JavaStringLiteral">&quot;jdbc:hsqldb:mem:.&quot;</span> => <span class="JavaStringLiteral">&quot;mem:.&quot;</span>
186  * <span class="JavaStringLiteral">&quot;jdbc:hsqldb:hsql:/host/<alias>...&quot;</span> => URI of aliased database
187  * <span class="JavaStringLiteral">&quot;jdbc:hsqldb:http:/host/<alias>...&quot;</span> => URI of aliased database
188  * </pre>
189  *
190  * <b>Note:</b> No provision is made for qualifying database objects
191  * by catalog in DML or DDL SQL. This feature is functional only with
192  * respect to browsing the database through the DatabaseMetaData and system
193  * table interfaces. <p>
194  *
195  * </ol>
196  *
197  * Again, it should be well understood that this feature provide an
198  * <i>emulation</i> of catalog support and is intended only
199  * as an experimental implementation to enhance the browsing experience
200  * when using graphical database explorers and to make a first foray
201  * into tackling the issue of implementing true catalog support
202  * in the future. <p>
203  *
204  * Due the nature of the new database system table production process, fewer
205  * assumptions can be made by this class about what information is made
206  * available in the system tables supporting <code>DatabaseMetaData</code>
207  * methods. Because of this, the SQL queries behind the <code>ResultSet</code>
208  * producing methods have been cleaned up and made to adhere more strictly to
209  * the JDBC contracts specified in relation to the method parameters. <p>
210  *
211  * One of the remaining assumptions concerns the <code>approximate</code>
212  * argument of {@link #getIndexInfo getIndexInfo()}. This parameter is still
213  * ignored since there is not yet any process in place to internally gather
214  * and persist table and index statistics. A primitive version of a statistics
215  * gathering and reporting subsystem <em>may</em> be introduced some time in the
216  * 1.7.x series of releases, but no hard decision has yet been made. <p>
217  *
218  * Another assumption is that simple select queries against certain system
219  * tables will return rows in JDBC contract order in the absence of an
220  * &quot;ORDER BY&quot; clause. The reason for this is that results
221  * come back much faster when no &quot;ORDER BY&quot; clause is used.
222  * Developers wishing to extend or replace an existing system table production
223  * class should be aware of this, either adding the contract
224  * &quot;ORDER BY&quot; clause to the SQL in corresponding methods in this class,
225  * or, better, by maintaing rows in the correct order in the underlying
226  * system tables, prefereably by creating appropriate primary indices. <p>
227  *
228  * <hr>
229  *
230  * <b>JRE 1.1.x Notes:</b> <p>
231  *
232  * In general, JDBC 2 support requires Java 1.2 and above, and JDBC3 requires
233  * Java 1.4 and above. In HSQLDB, support for methods introduced in different
234  * versions of JDBC depends on the JDK version used for compiling and building
235  * HSQLDB.<p>
236  *
237  * Since 1.7.0, it is possible to build the product so that
238  * all JDBC 2 methods can be called while executing under the version 1.1.x
239  * <em>Java Runtime Environment</em><sup><font size="-2">TM</font></sup>.
240  * However, some of these method calls require <code>int</code> values that
241  * are defined only in the JDBC 2 or greater version of the
242  * {@link java.sql.ResultSet ResultSet} interface. For this reason, when the
243  * product is compiled under JDK 1.1.x, these values are defined in
244  * {@link jdbcResultSet jdbcResultSet}.<p>
245  *
246  * In a JRE 1.1.x environment, calling JDBC 2 methods that take or return the
247  * JDBC2-only <code>ResultSet</code> values can be achieved by referring
248  * to them in parameter specifications and return value comparisons,
249  * respectively, as follows: <p>
250  *
251  * <pre class="JavaCodeExample">
252  * jdbcResultSet.FETCH_FORWARD
253  * jdbcResultSet.TYPE_FORWARD_ONLY
254  * jdbcResultSet.TYPE_SCROLL_INSENSITIVE
255  * jdbcResultSet.CONCUR_READ_ONLY
256  * // etc
257  * </pre>
258  *
259  * However, please note that code written in such a manner will not be
260  * compatible for use with other JDBC 2 drivers, since they expect and use
261  * <code>ResultSet</code>, rather than <code>jdbcResultSet</code>. Also
262  * note, this feature is offered solely as a convenience to developers
263  * who must work under JDK 1.1.x due to operating constraints, yet wish to
264  * use some of the more advanced features available under the JDBC 2
265  * specification.<p>
266  *
267  * (fredt@users)<br>
268  * (boucherb@users)
269  * </div>
270  * <!-- end release-specific documentation -->
271  *
272  * @author boucherb@users
273  * @author fredt@users
274  * @version 1.7.2
275  * @see org.hsqldb.DatabaseInformation
276  * @see org.hsqldb.DatabaseInformationMain
277  * @see org.hsqldb.DatabaseInformationFull
278  */

279 public class jdbcDatabaseMetaData implements DatabaseMetaData JavaDoc {
280
281     /** Used by getBestRowIdentifier to avoid extra object construction */
282     static final Integer JavaDoc INT_COLUMNS_NO_NULLS = new Integer JavaDoc(columnNoNulls);
283
284     // -----------------------------------------------------------------------
285
// private attributes
286
// -----------------------------------------------------------------------
287

288     /**
289      * The connection this object uses to retrieve database instance-specific
290      * metadata.
291      */

292     private jdbcConnection connection;
293
294     /**
295      * Connection property for schema reporting.
296      */

297     private boolean useSchemaDefault;
298
299     /**
300      * A CSV list representing the SQL IN list to use when generating
301      * queries for <code>getBestRowIdentifier</code> when the
302      * <code>scope</code> argument is <code>bestRowSession</code>.
303      * @since HSQLDB 1.7.2
304      */

305     private static final String JavaDoc BRI_SESSION_SCOPE_IN_LIST = "("
306         + bestRowSession + ")";
307
308     /**
309      * A CSV list representing the SQL IN list to use when generating
310      * queries for <code>getBestRowIdentifier</code> when the
311      * <code>scope</code> argument is <code>bestRowTemporary</code>.
312      * @since HSQLDB 1.7.2
313      */

314     private static final String JavaDoc BRI_TEMPORARY_SCOPE_IN_LIST = "("
315         + bestRowTemporary + "," + bestRowTransaction + "," + bestRowSession
316         + ")";
317
318     /**
319      * A CSV list representing the SQL IN list to use when generating
320      * queries for <code>getBestRowIdentifier</code> when the
321      * <code>scope</code> argument is <code>bestRowTransaction</code>.
322      * @since HSQLDB 1.7.2
323      */

324     private static final String JavaDoc BRI_TRANSACTION_SCOPE_IN_LIST = "("
325         + bestRowTransaction + "," + bestRowSession + ")";
326
327     /**
328      * "SELECT * FROM ". <p>
329      *
330      * This attribute is in support of methods that use SQL SELECT statements to
331      * generate returned <code>ResultSet</code> objects. <p>
332      *
333      * @since HSQLDB 1.7.2
334      */

335     private static final String JavaDoc selstar = "SELECT * FROM INFORMATION_SCHEMA.";
336
337     /**
338      * " WHERE 1=1 ". <p>
339      *
340      * This attribute is in support of methods that use SQL SELECT statements to
341      * generate returned <code>ResultSet</code> objects. <p>
342      *
343      * A good optimizer will simply drop this when parsing a condition
344      * expression. And it makes our code much easier to write, since we don't
345      * have to check our "WHERE" clause productions as strictly for proper
346      * conjunction: we just stick additional conjunctive predicates on the
347      * end of this and Presto! Everything works :-) <p>
348      * @since HSQLDB 1.7.2
349      */

350     private static final String JavaDoc whereTrue = " WHERE 1=1";
351
352     //----------------------------------------------------------------------
353
// First, a variety of minor information about the target database.
354

355     /**
356      * Retrieves whether the current user can call all the procedures
357      * returned by the method <code>getProcedures</code>. <p>
358      *
359      * <!-- start release-specific documentation -->
360      * <div class="ReleaseSpecificDocumentation">
361      * <h3>HSQLDB-Specific Information:</h3> <p>
362      *
363      * This method still <em>always</em> returns
364      * <code>true</code>. <p>
365      *
366      * In a future release, the plugin interface may be modified to allow
367      * implementors to report different values here, based on their
368      * implementations.
369      * </div>
370      * <!-- end release-specific documentation -->
371      *
372      * @return <code>true</code> if so; <code>false</code> otherwise
373      * @exception SQLException if a database access error occurs
374      */

375     public boolean allProceduresAreCallable() throws SQLException JavaDoc {
376         return true;
377     }
378
379     /**
380      * Retrieves whether the current user can use all the tables returned
381      * by the method <code>getTables</code> in a <code>SELECT</code>
382      * statement. <p>
383      *
384      * <!-- start release-specific documentation -->
385      * <div class="ReleaseSpecificDocumentation">
386      * <h3>HSQLDB-Specific Information:</h3> <p>
387      *
388      * HSQLDB always reports <code>true</code>.<p>
389      *
390      * Please note that the default 1.7.2 <code>getTables</code> behaviour is
391      * omit from the list of <em>requested</em> tables only those to which the
392      * invoking user has <em>no</em> access of any kind. <p>
393      *
394      * </div>
395      * <!-- end release-specific documentation -->
396      *
397      * @return <code>true</code> if so; <code>false</code> otherwise
398      * @exception SQLException if a database access error occurs
399      */

400     public boolean allTablesAreSelectable() throws SQLException JavaDoc {
401         return true;
402     }
403
404     /**
405      * Retrieves the URL for this DBMS.
406      *
407      *
408      * @return the URL for this DBMS or <code>null</code> if it cannot be
409      * generated
410      * @exception SQLException if a database access error occurs
411      */

412     public String JavaDoc getURL() throws SQLException JavaDoc {
413         return connection.getURL();
414     }
415
416     /**
417      * Retrieves the user name as known to this database.
418      *
419      *
420      * @return the database user name
421      * @exception SQLException if a database access error occurs
422      */

423     public String JavaDoc getUserName() throws SQLException JavaDoc {
424
425         ResultSet JavaDoc rs = execute("CALL USER()");
426
427         rs.next();
428
429         String JavaDoc result = rs.getString(1);
430
431         rs.close();
432
433         return result;
434     }
435
436     /**
437      * Retrieves whether this database is in read-only mode. <p>
438      *
439      * <!-- start release-specific documentation -->
440      * <div class="ReleaseSpecificDocumentation">
441      * <h3>HSQLDB-Specific Information:</h3> <p>
442      *
443      * Starting with 1.7.2, this makes
444      * an SQL call to the new {@link Library#isReadOnlyDatabase} method
445      * which provides correct determination of the read-only status for
446      * both local and remote database instances.
447      * </div>
448      * <!-- end release-specific documentation -->
449      * @return <code>true</code> if so; <code>false</code> otherwise
450      * @exception SQLException if a database access error occurs
451      */

452     public boolean isReadOnly() throws SQLException JavaDoc {
453
454         ResultSet JavaDoc rs =
455             execute("CALL \"org.hsqldb.Library.isReadOnlyDatabase\"()");
456
457         rs.next();
458
459         boolean result = rs.getBoolean(1);
460
461         rs.close();
462
463         return result;
464     }
465
466     /**
467      * Retrieves whether <code>NULL</code> values are sorted high.
468      * Sorted high means that <code>NULL</code> values
469      * sort higher than any other value in a domain. In an ascending order,
470      * if this method returns <code>true</code>, <code>NULL</code> values
471      * will appear at the end. By contrast, the method
472      * <code>nullsAreSortedAtEnd</code> indicates whether <code>NULL</code> values
473      * are sorted at the end regardless of sort order. <p>
474      *
475      * <!-- start release-specific documentation -->
476      * <div class="ReleaseSpecificDocumentation">
477      * <h3>HSQLDB-Specific Information:</h3> <p>
478      *
479      * HSQLDB sorts null low; this method always returns <code>false</code>.
480      * </div>
481      * <!-- end release-specific documentation -->
482      *
483      *
484      * @return <code>true</code> if so; <code>false</code> otherwise
485      * @exception SQLException if a database access error occurs
486      */

487     public boolean nullsAreSortedHigh() throws SQLException JavaDoc {
488         return false;
489     }
490
491     /**
492      * Retrieves whether <code>NULL</code> values are sorted low.
493      * Sorted low means that <code>NULL</code> values
494      * sort lower than any other value in a domain. In an ascending order,
495      * if this method returns <code>true</code>, <code>NULL</code> values
496      * will appear at the beginning. By contrast, the method
497      * <code>nullsAreSortedAtStart</code> indicates whether <code>NULL</code> values
498      * are sorted at the beginning regardless of sort order. <p>
499      *
500      * <!-- start release-specific documentation -->
501      * <div class="ReleaseSpecificDocumentation">
502      * <h3>HSQLDB-Specific Information:</h3> <p>
503      *
504      * HSQLDB sorts null low; this method always returns <code>true</code>.
505      * </div>
506      * <!-- end release-specific documentation -->
507      *
508      *
509      * @return <code>true</code> if so; <code>false</code> otherwise
510      * @exception SQLException if a database access error occurs
511      */

512     public boolean nullsAreSortedLow() throws SQLException JavaDoc {
513         return true;
514     }
515
516     /**
517      * Retrieves whether <code>NULL</code> values are sorted at the start regardless
518      * of sort order. <p>
519      *
520      * <!-- start release-specific documentation -->
521      * <div class="ReleaseSpecificDocumentation">
522      * <h3>HSQLDB-Specific Information:</h3> <p>
523      *
524      * HSQLDB sorts null low; this method always returns <code>false</code>.
525      * </div>
526      * <!-- end release-specific documentation -->
527      *
528      *
529      * @return <code>true</code> if so; <code>false</code> otherwise
530      * @exception SQLException if a database access error occurs
531      */

532     public boolean nullsAreSortedAtStart() throws SQLException JavaDoc {
533         return false;
534     }
535
536     /**
537      * Retrieves whether <code>NULL</code> values are sorted at the end regardless of
538      * sort order. <p>
539      *
540      * <!-- start release-specific documentation -->
541      * <div class="ReleaseSpecificDocumentation">
542      * <h3>HSQLDB-Specific Information:</h3> <p>
543      *
544      * HSQLDB sorts null low; this method always returns <code>false</code>.
545      * </div>
546      * <!-- end release-specific documentation -->
547      *
548      *
549      * @return <code>true</code> if so; <code>false</code> otherwise
550      * @exception SQLException if a database access error occurs
551      */

552     public boolean nullsAreSortedAtEnd() throws SQLException JavaDoc {
553         return false;
554     }
555
556     /**
557      * Retrieves the name of this database product. <p>
558      *
559      * <div class="ReleaseSpecificDocumentation">
560      * <h3>HSQLDB-Specific Information:</h3> <p>
561      *
562      * Starting with HSQLDB 1.7.2, this value is retrieved through an
563      * SQL call to the new {@link Library#getDatabaseProductName} method
564      * which allows correct determination of the database product name
565      * for both local and remote database instances.
566      * </div> <p>
567      *
568      * @return database product name
569      * @exception SQLException if a database access error occurs
570      */

571     public String JavaDoc getDatabaseProductName() throws SQLException JavaDoc {
572
573         ResultSet JavaDoc rs =
574             execute("call \"org.hsqldb.Library.getDatabaseProductName\"()");
575
576         rs.next();
577
578         String JavaDoc result = rs.getString(1);
579
580         rs.close();
581
582         return result;
583     }
584
585     /**
586      * Retrieves the version number of this database product. <p>
587      *
588      * <div class="ReleaseSpecificDocumentation">
589      * <h3>HSQLDB-Specific Information:</h3> <p>
590      *
591      * Starting with HSQLDB 1.7.2, this value is retrieved through an
592      * SQL call to the new {@link Library#getDatabaseProductVersion} method
593      * which allows correct determination of the database product name
594      * for both local and remote database instances.
595      * </div> <p>
596      *
597      * @return database version number
598      * @exception SQLException if a database access error occurs
599      */

600     public String JavaDoc getDatabaseProductVersion() throws SQLException JavaDoc {
601
602         ResultSet JavaDoc rs = execute(
603             "call \"org.hsqldb.Library.getDatabaseProductVersion\"()");
604
605         rs.next();
606
607         String JavaDoc result = rs.getString(1);
608
609         rs.close();
610
611         return result;
612     }
613
614     /**
615      * Retrieves the name of this JDBC driver.
616      *
617      * @return JDBC driver name
618      * @exception SQLException if a database access error occurs
619      */

620     public String JavaDoc getDriverName() throws SQLException JavaDoc {
621         return HsqlDatabaseProperties.PRODUCT_NAME + " Driver";
622     }
623
624     /**
625      * Retrieves the version number of this JDBC driver as a <code>String</code>.
626      *
627      * @return JDBC driver version
628      * @exception SQLException if a database access error occurs
629      */

630     public String JavaDoc getDriverVersion() throws SQLException JavaDoc {
631         return HsqlDatabaseProperties.THIS_VERSION;
632     }
633
634     /**
635      * Retrieves this JDBC driver's major version number.
636      *
637      * @return JDBC driver major version
638      */

639     public int getDriverMajorVersion() {
640         return HsqlDatabaseProperties.MAJOR;
641     }
642
643     /**
644      * Retrieves this JDBC driver's minor version number.
645      *
646      * @return JDBC driver minor version number
647      */

648     public int getDriverMinorVersion() {
649         return HsqlDatabaseProperties.MINOR;
650     }
651
652     /**
653      * Retrieves whether this database stores tables in a local file. <p>
654      *
655      * <!-- start release-specific documentation -->
656      * <div class="ReleaseSpecificDocumentation">
657      * <h3>HSQLDB-Specific Information:</h3> <p>
658      *
659      * From HSQLDB 1.7.2 it is assumed that this refers to data being stored
660      * by the JDBC client. This method always returns false.
661      * </div>
662      * <!-- end release-specific documentation -->
663      * @return <code>true</code> if so; <code>false</code> otherwise
664      * @exception SQLException if a database access error occurs
665      */

666     public boolean usesLocalFiles() throws SQLException JavaDoc {
667         return false;
668     }
669
670     /**
671      * Retrieves whether this database uses a file for each table. <p>
672      *
673      * <!-- start release-specific documentation -->
674      * <div class="ReleaseSpecificDocumentation">
675      * <h3>HSQLDB-Specific Information:</h3> <p>
676      *
677      * Up to and including 1.7.2, HSQLDB does not use a file for each table.
678      * This method always returns <code>false</code>.
679      * </div>
680      * <!-- end release-specific documentation -->
681      * @return <code>true</code> if this database uses a local file for each table;
682      * <code>false</code> otherwise
683      * @exception SQLException if a database access error occurs
684      */

685     public boolean usesLocalFilePerTable() throws SQLException JavaDoc {
686         return false;
687     }
688
689     /**
690      * Retrieves whether this database treats mixed case unquoted SQL identifiers as
691      * case sensitive and as a result stores them in mixed case. <p>
692      *
693      * <!-- start release-specific documentation -->
694      * <div class="ReleaseSpecificDocumentation">
695      * <h3>HSQLDB-Specific Information:</h3> <p>
696      *
697      * HSQLDB treats unquoted identifiers as case insensitive and stores
698      * them in upper case. It treats quoted identifiers as case sensitive and
699      * stores them verbatim; this method always returns <code>false</code>.
700      * </div>
701      * <!-- end release-specific documentation -->
702      *
703      *
704      * @return <code>true</code> if so; <code>false</code> otherwise
705      * @exception SQLException if a database access error occurs
706      */

707     public boolean supportsMixedCaseIdentifiers() throws SQLException JavaDoc {
708         return false;
709     }
710
711     /**
712      * Retrieves whether this database treats mixed case unquoted SQL identifiers as
713      * case insensitive and stores them in upper case. <p>
714      *
715      * <!-- start release-specific documentation -->
716      * <div class="ReleaseSpecificDocumentation">
717      * <h3>HSQLDB-Specific Information:</h3> <p>
718      *
719      * HSQLDB treats unquoted identifiers as case insensitive and stores
720      * them in upper case. It treats quoted identifiers as case sensitive and
721      * stores them verbatim; this method always returns <code>true</code>.
722      * </div>
723      * <!-- end release-specific documentation -->
724      *
725      *
726      * @return <code>true</code> if so; <code>false</code> otherwise
727      * @exception SQLException if a database access error occurs
728      */

729     public boolean storesUpperCaseIdentifiers() throws SQLException JavaDoc {
730         return true;
731     }
732
733     /**
734      * Retrieves whether this database treats mixed case unquoted SQL identifiers as
735      * case insensitive and stores them in lower case. <p>
736      *
737      * <!-- start release-specific documentation -->
738      * <div class="ReleaseSpecificDocumentation">
739      * <h3>HSQLDB-Specific Information:</h3> <p>
740      *
741      * HSQLDB treats unquoted identifiers as case insensitive and stores
742      * them in upper case. It treats quoted identifiers as case sensitive and
743      * stores them verbatim; this method always returns <code>false</code>.
744      * </div>
745      * <!-- end release-specific documentation -->
746      *
747      *
748      * @return <code>true</code> if so; <code>false</code> otherwise
749      * @exception SQLException if a database access error occurs
750      */

751     public boolean storesLowerCaseIdentifiers() throws SQLException JavaDoc {
752         return false;
753     }
754
755     /**
756      * Retrieves whether this database treats mixed case unquoted SQL identifiers as
757      * case insensitive and stores them in mixed case. <p>
758      *
759      * <!-- start release-specific documentation -->
760      * <div class="ReleaseSpecificDocumentation">
761      * <h3>HSQLDB-Specific Information:</h3> <p>
762      *
763      * HSQLDB treats unquoted identifiers as case insensitive and stores
764      * them in upper case. It treats quoted identifiers as case sensitive and
765      * stores them verbatim; this method always returns <code>false</code>.
766      * </div>
767      * <!-- end release-specific documentation -->
768      *
769      *
770      * @return <code>true</code> if so; <code>false</code> otherwise
771      * @exception SQLException if a database access error occurs
772      */

773     public boolean storesMixedCaseIdentifiers() throws SQLException JavaDoc {
774         return false;
775     }
776
777     /**
778      * Retrieves whether this database treats mixed case quoted SQL identifiers as
779      * case sensitive and as a result stores them in mixed case. <p>
780      *
781      * <!-- start release-specific documentation -->
782      * <div class="ReleaseSpecificDocumentation">
783      * <h3>HSQLDB-Specific Information:</h3> <p>
784      *
785      * HSQLDB treats unquoted identifiers as case insensitive and stores
786      * them in upper case. It treats quoted identifiers as case sensitive and
787      * stores them verbatim; this method always returns <code>true</code>.
788      * </div>
789      * <!-- end release-specific documentation -->
790      *
791      *
792      * @return <code>true</code> if so; <code>false</code> otherwise
793      * @exception SQLException if a database access error occurs
794      */

795     public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException JavaDoc {
796         return true;
797     }
798
799     /**
800      * Retrieves whether this database treats mixed case quoted SQL identifiers as
801      * case insensitive and stores them in upper case. <p>
802      *
803      * <!-- start release-specific documentation -->
804      * <div class="ReleaseSpecificDocumentation">
805      * <h3>HSQLDB-Specific Information:</h3> <p>
806      *
807      * HSQLDB treats unquoted identifiers as case insensitive and stores
808      * them in upper case. It treats quoted identifiers as case sensitive and
809      * stores them verbatim; this method always returns <code>false</code>.
810      * </div>
811      * <!-- end release-specific documentation -->
812      *
813      *
814      * @return <code>true</code> if so; <code>false</code> otherwise
815      * @exception SQLException if a database access error occurs
816      */

817     public boolean storesUpperCaseQuotedIdentifiers() throws SQLException JavaDoc {
818         return false;
819     }
820
821     /**
822      * Retrieves whether this database treats mixed case quoted SQL identifiers as
823      * case insensitive and stores them in lower case. <p>
824      *
825      * <!-- start release-specific documentation -->
826      * <div class="ReleaseSpecificDocumentation">
827      * <h3>HSQLDB-Specific Information:</h3> <p>
828      *
829      * HSQLDB treats unquoted identifiers as case insensitive and stores
830      * them in upper case. It treats quoted identifiers as case sensitive and
831      * stores them verbatim; this method always returns <code>false</code>.
832      * </div>
833      * <!-- end release-specific documentation -->
834      * @return <code>true</code> if so; <code>false</code> otherwise
835      * @exception SQLException if a database access error occurs
836      */

837     public boolean storesLowerCaseQuotedIdentifiers() throws SQLException JavaDoc {
838         return false;
839     }
840
841     /**
842      * Retrieves whether this database treats mixed case quoted SQL identifiers as
843      * case insensitive and stores them in mixed case. <p>
844      *
845      * <!-- start release-specific documentation -->
846      * <div class="ReleaseSpecificDocumentation">
847      * <h3>HSQLDB-Specific Information:</h3> <p>
848      *
849      * HSQLDB treats unquoted identifiers as case insensitive and stores
850      * them in upper case. It treats quoted identifiers as case sensitive and
851      * stores them verbatim; this method always returns <code>false</code>.
852      * </div>
853      * <!-- end release-specific documentation -->
854      *
855      *
856      * @return <code>true</code> if so; <code>false</code> otherwise
857      * @exception SQLException if a database access error occurs
858      */

859     public boolean storesMixedCaseQuotedIdentifiers() throws SQLException JavaDoc {
860         return false;
861     }
862
863     /**
864      * Retrieves the string used to quote SQL identifiers.
865      * This method returns a space " " if identifier quoting is not supported. <p>
866      *
867      * <!-- start release-specific documentation -->
868      * <div class="ReleaseSpecificDocumentation">
869      * <h3>HSQLDB-Specific Information:</h3> <p>
870      *
871      * HSQLDB uses the standard SQL identifier quote character
872      * (the double quote character); this method always returns <b>"</b>.
873      * </div>
874      * <!-- end release-specific documentation -->
875      * @return the quoting string or a space if quoting is not supported
876      * @exception SQLException if a database access error occurs
877      */

878     public String JavaDoc getIdentifierQuoteString() throws SQLException JavaDoc {
879         return "\"";
880     }
881
882 //fredt@users 20020429 - JavaDoc comment - in 1.7.1 there are keywords such
883
// as TEMP, TEXT, CACHED that are not SQL 92 keywords
884

885     /**
886      * Retrieves a comma-separated list of all of this database's SQL keywords
887      * that are NOT also SQL92 keywords. <p>
888      *
889      * <!-- start release-specific documentation -->
890      * <div class="ReleaseSpecificDocumentation">
891      * <h3>HSQLDB-Specific Information:</h3> <p>
892      *
893      * The list returned contains HSQLDB keywords that are not in the list
894      * of reserved words. Some of these are in the list reserved
895      * words for SQL 2003 but are not SQL92 keywords.
896      * </div>
897      * <!-- end release-specific documentation -->
898      *
899      *
900      * @return the list of this database's keywords that are not also
901      * SQL92 keywords
902      * @exception SQLException if a database access error occurs
903      */

904     public String JavaDoc getSQLKeywords() throws SQLException JavaDoc {
905
906         return "BEFORE,BIGINT,BINARY,CACHED,DATETIME,"
907                + "LIMIT,LONGVARBINARY,LONGVARCHAR,OBJECT,OTHER,SAVEPOINT,"
908                + "TEMP,TEXT,TOP,TRIGGER,TINYINT,VARBINARY,VARCHAR_IGNORECASE";
909     }
910
911     /**
912      * Retrieves a comma-separated list of math functions available with
913      * this database. These are the Open Group CLI math function names used in
914      * the JDBC function escape clause.
915      * @return the list of math functions supported by this database
916      * @exception SQLException if a database access error occurs
917      */

918     public String JavaDoc getNumericFunctions() throws SQLException JavaDoc {
919         return StringUtil.getList(Library.sNumeric, ",", "");
920     }
921
922     /**
923      * Retrieves a comma-separated list of string functions available with
924      * this database. These are the Open Group CLI string function names used
925      * in the JDBC function escape clause.
926      * @return the list of string functions supported by this database
927      * @exception SQLException if a database access error occurs
928      */

929     public String JavaDoc getStringFunctions() throws SQLException JavaDoc {
930         return StringUtil.getList(Library.sString, ",", "");
931     }
932
933     /**
934      * Retrieves a comma-separated list of system functions available with
935      * this database. These are the Open Group CLI system function names used
936      * in the JDBC function escape clause.
937      * @return a list of system functions supported by this database
938      * @exception SQLException if a database access error occurs
939      */

940     public String JavaDoc getSystemFunctions() throws SQLException JavaDoc {
941         return StringUtil.getList(Library.sSystem, ",", "");
942     }
943
944     /**
945      * Retrieves a comma-separated list of the time and date functions available
946      * with this database.
947      * @return the list of time and date functions supported by this database
948      * @exception SQLException if a database access error occurs
949      */

950     public String JavaDoc getTimeDateFunctions() throws SQLException JavaDoc {
951         return StringUtil.getList(Library.sTimeDate, ",", "");
952     }
953
954     /**
955      * Retrieves the string that can be used to escape wildcard characters.
956      * This is the string that can be used to escape '_' or '%' in
957      * the catalog search parameters that are a pattern (and therefore use one
958      * of the wildcard characters).
959      *
960      * <P>The '_' character represents any single character;
961      * the '%' character represents any sequence of zero or
962      * more characters. <p>
963      *
964      * <!-- start release-specific documentation -->
965      * <div class="ReleaseSpecificDocumentation">
966      * <h3>HSQLDB-Specific Information:</h3> <p>
967      *
968      * HSQLDB uses the "\" character to escape wildcard characters.
969      * </div>
970      * <!-- end release-specific documentation -->
971      *
972      *
973      * @return the string used to escape wildcard characters
974      * @exception SQLException if a database access error occurs
975      */

976     public String JavaDoc getSearchStringEscape() throws SQLException JavaDoc {
977         return "\\";
978     }
979
980     /**
981      * Retrieves all the "extra" characters that can be used in unquoted
982      * identifier names (those beyond a-z, A-Z, 0-9 and _). <p>
983      *
984      * <!-- start release-specific documentation -->
985      * <div class="ReleaseSpecificDocumentation">
986      * <h3>HSQLDB-Specific Information:</h3> <p>
987      *
988      * HSQLDB does not support using any "extra" characters in unquoted
989      * identifier names; this method always returns the empty String.
990      * </div>
991      * <!-- end release-specific documentation -->
992      *
993      *
994      * @return the string containing the extra characters
995      * @exception SQLException if a database access error occurs
996      */

997     public String JavaDoc getExtraNameCharacters() throws SQLException JavaDoc {
998         return "";
999     }
1000
1001    //--------------------------------------------------------------------
1002
// Functions describing which features are supported.
1003

1004    /**
1005     * Retrieves whether this database supports <code>ALTER TABLE</code>
1006     * with add column. <p>
1007     *
1008     * <!-- start release-specific documentation -->
1009     * <div class="ReleaseSpecificDocumentation">
1010     * <h3>HSQLDB-Specific Information:</h3> <p>
1011     *
1012     * From 1.7.0, HSQLDB supports this type of
1013     * <code>ALTER TABLE</code> statement; this method always
1014     * returns <code>true</code>.
1015     * </div>
1016   &nb