KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > jdbc > EmbedDatabaseMetaData


1 /*
2
3    Derby - Class org.apache.derby.impl.jdbc.EmbedDatabaseMetaData
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.jdbc;
23
24 import org.apache.derby.iapi.services.info.ProductVersionHolder;
25
26 import org.apache.derby.iapi.services.monitor.Monitor;
27
28 import org.apache.derby.iapi.services.sanity.SanityManager;
29
30 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
31
32 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
33 import org.apache.derby.iapi.sql.dictionary.SPSDescriptor;
34
35 import org.apache.derby.iapi.error.StandardException;
36
37 import org.apache.derby.impl.sql.execute.GenericConstantActionFactory;
38 import org.apache.derby.impl.sql.execute.GenericExecutionFactory;
39
40 import org.apache.derby.iapi.reference.Limits;
41 import org.apache.derby.iapi.reference.JDBC20Translation;
42 import org.apache.derby.iapi.reference.JDBC30Translation;
43
44 import java.util.Properties JavaDoc;
45
46 import java.sql.DatabaseMetaData JavaDoc;
47 import java.sql.Connection JavaDoc;
48 import java.sql.PreparedStatement JavaDoc;
49 import java.sql.SQLException JavaDoc;
50 import java.sql.ResultSet JavaDoc;
51 import java.sql.Types JavaDoc;
52
53 import java.io.IOException JavaDoc;
54 import java.io.InputStream JavaDoc;
55
56 /**
57  * This class provides information about the database as a whole.
58  *
59  * <P>Many of the methods here return lists of information in ResultSets.
60  * You can use the normal ResultSet methods such as getString and getInt
61  * to retrieve the data from these ResultSets. If a given form of
62  * metadata is not available, these methods should throw a SQLException.
63  *
64  * <P>Some of these methods take arguments that are String patterns. These
65  * arguments all have names such as fooPattern. Within a pattern String, "%"
66  * means match any substring of 0 or more characters, and "_" means match
67  * any one character. Only metadata entries matching the search pattern
68  * are returned. If a search pattern argument is set to a null ref, it means
69  * that argument's criteria should be dropped from the search.
70  *
71  * <P>A SQLException will be thrown if a driver does not support a meta
72  * data method. In the case of methods that return a ResultSet,
73  * either a ResultSet (which may be empty) is returned or a
74  * SQLException is thrown.
75  * <p>
76  * This implementation gets instructions from the Database for how to satisfy
77  * most requests for information. Each instruction is either a simple string
78  * containing the desired information, or the text of a query that may be
79  * executed on the database connection to gather the information. We get the
80  * instructions via an "InstructionReader," which requires the database
81  * Connection for initialization.
82  * <p>
83  * Those few pieces of metadata that are related to the driver, rather than the
84  * database, come from a separate InstructionReader. Note that in that case it
85  * probably doesn't make sense to allow an instruction to specify a query.
86  *
87  * @author ames
88  */

89 public class EmbedDatabaseMetaData extends ConnectionChild
90     implements DatabaseMetaData JavaDoc, java.security.PrivilegedAction JavaDoc {
91
92     /*
93     ** Property and values related to using
94     ** stored prepared statements for metatdata.
95     */

96
97     private final String JavaDoc url;
98     
99     /*
100     ** Set to true if metadata is off
101     */

102
103     private GenericConstantActionFactory constantActionFactory;
104     
105     //////////////////////////////////////////////////////////////
106
//
107
// CONSTRUCTORS
108
//
109
//////////////////////////////////////////////////////////////
110
/**
111         @exception SQLException on error
112      */

113     public EmbedDatabaseMetaData (EmbedConnection connection, String JavaDoc url)
114         throws SQLException JavaDoc {
115
116         super(connection);
117         this.url = url;
118
119     }
120
121     /** Cached query descriptions from metadata.properties. */
122     private static Properties JavaDoc queryDescriptions;
123     /** Cached query descriptions from metadata_net.properties. */
124     private static Properties JavaDoc queryDescriptions_net;
125     /**
126      * Return all queries found in either metadata.properties or
127      * metadata_net.properties.
128      *
129      * @param net if <code>true</code>, read metadata_net.properties;
130      * otherwise, read metadata.properties.
131      * @return a <code>Properties</code> value with the queries
132      */

133     private Properties JavaDoc getQueryDescriptions(boolean net) {
134         Properties JavaDoc p = net ? queryDescriptions_net : queryDescriptions;
135         if (p != null) {
136             return p;
137         }
138         loadQueryDescriptions();
139         return net ? queryDescriptions_net : queryDescriptions;
140     }
141
142     /**
143      * Read the query descriptions from metadata.properties and
144      * metadata_net.properties. This method must be invoked from
145      * within a privileged block.
146      */

147     private void PBloadQueryDescriptions() {
148         String JavaDoc[] files = {
149             "metadata.properties",
150             "/org/apache/derby/impl/sql/catalog/metadata_net.properties"
151         };
152         Properties JavaDoc[] props = new Properties JavaDoc[files.length];
153         for (int i = 0; i < files.length; ++i) {
154             try {
155                 props[i] = new Properties JavaDoc();
156                 // SECURITY PERMISSION - IP3
157
InputStream JavaDoc is = getClass().getResourceAsStream(files[i]);
158                 props[i].load(is);
159                 is.close();
160             } catch (IOException JavaDoc ioe) {
161                 if (SanityManager.DEBUG) {
162                     SanityManager.THROWASSERT("Error reading " + files[i], ioe);
163                 }
164             }
165         }
166         queryDescriptions = props[0];
167         queryDescriptions_net = props[1];
168     }
169
170     //////////////////////////////////////////////////////////////
171
//
172
// DatabaseMetaData interface
173
//
174
//////////////////////////////////////////////////////////////
175

176     //----------------------------------------------------------------------
177
// First, a variety of minor information about the target database.
178

179     /**
180      * Can all the procedures returned by getProcedures be called by the
181      * current user?
182      *
183      * @return true if so
184      */

185     public boolean allProceduresAreCallable() {
186         return true;
187     }
188
189     /**
190      * Can all the tables returned by getTable be SELECTed by the
191      * current user?
192      *
193      * @return true if so
194      */

195     public boolean allTablesAreSelectable() {
196         return true;
197     }
198
199     /**
200      * What's the url for this database?
201      *
202      * @return the url or null if it can't be generated
203      */

204     public final String JavaDoc getURL() {
205
206         if (url == null)
207             return url;
208         int attributeStart = url.indexOf(';');
209         if (attributeStart == -1)
210             return url;
211         else
212             return url.substring(0,attributeStart);
213     }
214
215     /**
216      * What's our user name as known to the database?
217      *
218      * @return our database user name
219      */

220     public String JavaDoc getUserName() {
221         return (getEmbedConnection().getTR().getUserName());
222     }
223
224     /**
225      * Is the database in read-only mode?
226      *
227      * @return true if so
228      */

229     public boolean isReadOnly() {
230         return getLanguageConnectionContext().getDatabase().isReadOnly();
231     }
232
233     /**
234      * Are NULL values sorted high?
235      *
236      * @return true if so
237      */

238     public boolean nullsAreSortedHigh() {
239         return true;
240     }
241
242     /**
243      * Are NULL values sorted low?
244      *
245      * @return true if so
246      */

247     public boolean nullsAreSortedLow() {
248         return false;
249     }
250
251     /**
252      * Are NULL values sorted at the start regardless of sort order?
253      *
254      * @return true if so
255      */

256     public boolean nullsAreSortedAtStart() {
257         return false;
258     }
259
260     /**
261      * Are NULL values sorted at the end regardless of sort order?
262      *
263      * @return true if so
264      */

265     public boolean nullsAreSortedAtEnd() {
266         return false;
267     }
268
269     /**
270      * What's the name of this database product?
271      *
272      * @return database product name
273      */

274     public String JavaDoc getDatabaseProductName() {
275         return Monitor.getMonitor().getEngineVersion().getProductName();
276     }
277
278     /**
279      * What's the version of this database product?
280      *
281      * @return database version
282      */

283     public String JavaDoc getDatabaseProductVersion() {
284         ProductVersionHolder myPVH = Monitor.getMonitor().getEngineVersion();
285
286         return myPVH.getVersionBuildString(true);
287     }
288
289     /**
290      * What's the name of this JDBC driver?
291      *
292      * @return JDBC driver name
293      */

294     public String JavaDoc getDriverName() {
295         return "Apache Derby Embedded JDBC Driver";
296     }
297
298     /**
299      * What's the version of this JDBC driver?
300      *
301      * @return JDBC driver version
302      */

303     public String JavaDoc getDriverVersion() {
304         return getDatabaseProductVersion();
305     }
306
307     /**
308      * What's this JDBC driver's major version number?
309      *
310      * @return JDBC driver major version
311      */

312     public int getDriverMajorVersion() {
313         return getEmbedConnection().getLocalDriver().getMajorVersion();
314     }
315
316     /**
317      * What's this JDBC driver's minor version number?
318      *
319      * @return JDBC driver minor version number
320      */

321     public int getDriverMinorVersion() {
322         return getEmbedConnection().getLocalDriver().getMinorVersion();
323     }
324
325     /**
326      * Does the database store tables in a local file?
327      *
328      * @return true if so
329      */

330     public boolean usesLocalFiles() {
331         return true;
332     }
333
334     /**
335      * Does the database use a file for each table?
336      *
337      * @return true if the database uses a local file for each table
338      */

339     public boolean usesLocalFilePerTable() {
340         return true;
341     }
342
343     /**
344      * Does the database treat mixed case unquoted SQL identifiers as
345      * case sensitive and as a result store them in mixed case?
346      *
347      * A JDBC-Compliant driver will always return false.
348      *
349      * @return true if so
350      */

351     public boolean supportsMixedCaseIdentifiers() {
352         return false;
353     }
354
355     /**
356      * Does the database treat mixed case unquoted SQL identifiers as
357      * case insensitive and store them in upper case?
358      *
359      * @return true if so
360      */

361     public boolean storesUpperCaseIdentifiers() {
362         return true;
363     }
364
365     /**
366      * Does the database treat mixed case unquoted SQL identifiers as
367      * case insensitive and store them in lower case?
368      *
369      * @return true if so
370      */

371     public boolean storesLowerCaseIdentifiers() {
372         return false;
373     }
374
375     /**
376      * Does the database treat mixed case unquoted SQL identifiers as
377      * case insensitive and store them in mixed case?
378      *
379      * @return true if so
380      */

381     public boolean storesMixedCaseIdentifiers() {
382         return false;
383     }
384
385     /**
386      * Does the database treat mixed case quoted SQL identifiers as
387      * case sensitive and as a result store them in mixed case?
388      *
389      * A JDBC-Compliant driver will always return true.
390      *
391      * @return true if so
392      */

393     public boolean supportsMixedCaseQuotedIdentifiers() {
394         return true;
395     }
396
397     /**
398      * Does the database treat mixed case quoted SQL identifiers as
399      * case insensitive and store them in upper case?
400      *
401      * @return true if so
402      */

403     public boolean storesUpperCaseQuotedIdentifiers() {
404         return false;
405     }
406
407     /**
408      * Does the database treat mixed case quoted SQL identifiers as
409      * case insensitive and store them in lower case?
410      *
411      * @return true if so
412      */

413     public boolean storesLowerCaseQuotedIdentifiers() {
414         return false;
415     }
416
417     /**
418      * Does the database treat mixed case quoted SQL identifiers as
419      * case insensitive and store them in mixed case?
420      *
421      * @return true if so
422      */

423     public boolean storesMixedCaseQuotedIdentifiers() {
424         return true;
425     }
426
427     /**
428      * What's the string used to quote SQL identifiers?
429      * This returns a space " " if identifier quoting isn't supported.
430      *
431      * A JDBC-Compliant driver always uses a double quote character.
432      *
433      * @return the quoting string
434      */

435     public String JavaDoc getIdentifierQuoteString() {
436         return "\"";
437     }
438
439     /**
440      * Get a comma separated list of all a database's SQL keywords
441      * that are NOT also SQL92 keywords.
442     includes reserved and non-reserved keywords.
443
444      * @return the list
445      */

446     public String JavaDoc getSQLKeywords() {
447         return "ALIAS,BIGINT,BOOLEAN,CALL,CLASS,COPY,DB2J_DEBUG,EXECUTE,EXPLAIN,FILE,FILTER,"
448             + "GETCURRENTCONNECTION,INDEX,INSTANCEOF,METHOD,NEW,OFF,PROPERTIES,PUBLICATION,RECOMPILE,"
449             + "REFRESH,RENAME,RUNTIMESTATISTICS,STATEMENT,STATISTICS,TIMING,WAIT";
450     }
451
452     /**
453      * Get a comma separated list of JDBC escaped numeric functions.
454      * Must be a complete or sub set of functions in appendix C.1
455      * @return the list
456      */

457     public String JavaDoc getNumericFunctions() {
458         return "ABS,ACOS,ASIN,ATAN,CEILING,COS,DEGREES,EXP,FLOOR,LOG,LOG10,MOD,PI,RADIANS,SIN,SQRT,TAN";
459     }
460
461     /**
462      * Get a comma separated list of JDBC escaped string functions.
463      * Must be a complete or sub set of functions in appendix C.2
464      * of JDBC 3.0 specification.
465      * @return the list
466      */

467     public String JavaDoc getStringFunctions() {
468         return "CONCAT,LENGTH,LCASE,LOCATE,LTRIM,RTRIM,SUBSTRING,UCASE";
469     }
470
471     /**
472      * Get a comma separated list of JDBC escaped system functions.
473      * Must be a complete or sub set of functions in appendix C.4
474      * of JDBC 3.0 specification.
475      * @return the list
476      */

477     public String JavaDoc getSystemFunctions() {
478         return "USER";
479     }
480
481     /**
482      * Get a comma separated list of JDBC escaped time date functions.
483      * Must be a complete or sub set of functions in appendix C.3
484      * of JDBC 3.0 specification.
485       * @return the list
486      */

487     public String JavaDoc getTimeDateFunctions() {
488         return "CURDATE,CURTIME,HOUR,MINUTE,MONTH,SECOND,TIMESTAMPADD,TIMESTAMPDIFF,YEAR";
489     }
490
491     /**
492      * This is the string that can be used to escape '_' or '%' in
493      * the string pattern style catalog search parameters.
494         we have no default escape value, so = is the end of the next line
495      * <P>The '_' character represents any single character.
496      * <P>The '%' character represents any sequence of zero or
497      * more characters.
498      * @return the string used to escape wildcard characters
499      */

500     public String JavaDoc getSearchStringEscape() {
501         return "";
502     }
503
504     /**
505      * Get all the "extra" characters that can be used in unquoted
506      * identifier names (those beyond a-z, A-Z, 0-9 and _).
507      *
508      * @return the string containing the extra characters
509      */

510     public String JavaDoc getExtraNameCharacters() {
511         return "";
512     }
513
514     //--------------------------------------------------------------------
515
// Functions describing which features are supported.
516

517     /**
518      * Is "ALTER TABLE" with add column supported?
519      *
520      * @return true if so
521      */

522     public boolean supportsAlterTableWithAddColumn() {
523         return true;
524     }
525
526     /**
527      * Is "ALTER TABLE" with drop column supported?
528      *
529      * @return true if so
530      */

531     public boolean supportsAlterTableWithDropColumn() {
532         return true;
533     }
534
535     /**
536      * Is column aliasing supported?
537      *
538      * <P>If so, the SQL AS clause can be used to provide names for
539      * computed columns or to provide alias names for columns as
540      * required.
541      *
542      * A JDBC-Compliant driver always returns true.
543      *
544      * @return true if so
545      */

546     public boolean supportsColumnAliasing() {
547         return true;
548     }
549
550     /**
551      * Are concatenations between NULL and non-NULL values NULL?
552      *
553      * A JDBC-Compliant driver always returns true.
554      *
555      * @return true if so
556      */

557     public boolean nullPlusNonNullIsNull() {
558         return true;
559     }
560
561     /**
562      * Is the CONVERT function between SQL types supported?
563      *
564      * @return true if so
565      */

566     public boolean supportsConvert() {
567         return true;
568     }
569
570     /**
571      * Is CONVERT between the given SQL types supported?
572      *
573      * @param fromType the type to convert from
574      * @param toType the type to convert to
575      * @return true if so
576      * @see Types
577      */

578     public boolean supportsConvert(int fromType, int toType) {
579         /*
580          * at the moment we don't support CONVERT at all, so we take the easy
581          * way out. Eventually we need to figure out how to handle this
582          * cleanly.
583          */

584         return false;
585     }
586
587     /**
588      * Are table correlation names supported?
589      *
590      * A JDBC-Compliant driver always returns true.
591      *
592      * @return true if so
593      */

594     public boolean supportsTableCorrelationNames() {
595         return true;
596     }
597
598     /**
599      * If table correlation names are supported, are they restricted
600      * to be different from the names of the tables?
601      *
602      * @return true if so
603      */

604     public boolean supportsDifferentTableCorrelationNames() {
605         return true;
606     }
607
608     /**
609      * Are expressions in "ORDER BY" lists supported?
610      *
611      * @return true if so
612      */

613     public boolean supportsExpressionsInOrderBy() {
614         return false;
615     }
616
617     /**
618      * Can an "ORDER BY" clause use columns not in the SELECT?
619      *
620      * @return true if so
621      */

622     public boolean supportsOrderByUnrelated() {
623         return false;
624     }
625
626     /**
627      * Is some form of "GROUP BY" clause supported?
628      *
629      * @return true if so
630      */

631     public boolean supportsGroupBy() {
632         return true;
633     }
634
635     /**
636      * Can a "GROUP BY" clause use columns not in the SELECT?
637      *
638      * @return true if so
639      */

640     public boolean supportsGroupByUnrelated() {
641         return true;
642     }
643
644     /**
645      * Can a "GROUP BY" clause add columns not in the SELECT
646      * provided it specifies all the columns in the SELECT?
647      *
648      * @return true if so
649      */

650     public boolean supportsGroupByBeyondSelect() {
651         return true;
652     }
653
654     /**
655      * Is the escape character in "LIKE" clauses supported?
656      *
657      * A JDBC-Compliant driver always returns true.
658      *
659      * @return true if so
660      */

661     public boolean supportsLikeEscapeClause() {
662         return true;
663     }
664
665     /**
666      * Are multiple ResultSets from a single execute supported?
667      *
668      * @return true if so
669      */

670     public boolean supportsMultipleResultSets() {
671         return true;
672     }
673
674     /**
675      * Can we have multiple transactions open at once (on different
676      * connections)?
677      *
678      * @return true if so
679      */

680     public boolean supportsMultipleTransactions() {
681         return true;
682     }
683
684     /**
685      * Can columns be defined as non-nullable?
686      *
687      * A JDBC-Compliant driver always returns true.
688      *
689      * @return true if so
690      */

691     public boolean supportsNonNullableColumns() {
692         return true;
693     }
694
695     /**
696      * Is the ODBC Minimum SQL grammar supported?
697      *
698      * All JDBC-Compliant drivers must return true.
699      *
700      * @return true if so
701      */

702     public boolean supportsMinimumSQLGrammar() {
703         return true;
704     }
705
706     /**
707      * Is the ODBC Core SQL grammar supported?
708      *
709      * @return true if so
710      */

711     public boolean supportsCoreSQLGrammar() {
712         return false;
713     }
714
715     /**
716      * Is the ODBC Extended SQL grammar supported?
717      *
718      * @return true if so
719      */

720     public boolean supportsExtendedSQLGrammar() {
721         return false;
722     }
723
724     /**
725      * Is the ANSI92 entry level SQL grammar supported?
726      *
727      * All JDBC-Compliant drivers must return true.
728      *
729      * @return true if so
730      */

731     public boolean supportsANSI92EntryLevelSQL() {
732         return false;
733     }
734
735     /**
736      * Is the ANSI92 intermediate SQL grammar supported?
737      *
738      * @return true if so
739      *
740      */

741     public boolean supportsANSI92IntermediateSQL() {
742         return false;
743     }
744
745     /**
746      * Is the ANSI92 full SQL grammar supported?
747      *
748      * @return true if so
749      *
750      */

751     public boolean supportsANSI92FullSQL() {
752         return false;
753     }
754
755     /**
756      * Is the SQL Integrity Enhancement Facility supported?
757      *
758      * @return true if so
759      *
760      */

761     public boolean supportsIntegrityEnhancementFacility() {
762         return false;
763     }
764
765     /**
766      * Is some form of outer join supported?
767      *
768      * @return true if so
769      *
770      */

771     public boolean supportsOuterJoins() {
772         return true;
773     }
774
775     /**
776      * Are full nested outer joins supported?
777      *
778      * @return true if so
779      *
780      */

781     public boolean supportsFullOuterJoins() {
782         return false;
783     }
784
785     /**
786      * Is there limited support for outer joins? (This will be true
787      * if supportFullOuterJoins is true.)
788      *
789      * @return true if so
790      *
791      */

792     public boolean supportsLimitedOuterJoins() {
793         return true;
794     }
795
796     /**
797      * What's the database vendor's preferred term for "schema"?
798      *
799      * @return the vendor term
800      *
801      */

802     public String JavaDoc getSchemaTerm() {
803         return "SCHEMA";
804     }
805
806     /**
807      * What's the database vendor's preferred term for "procedure"?
808      *
809      * @return the vendor term
810      *
811      */

812     public String JavaDoc getProcedureTerm() {
813         return "PROCEDURE";
814     }
815
816     /**
817      * What's the database vendor's preferred term for "catalog"?
818      *
819      * @return the vendor term
820      *
821      */

822     public String JavaDoc getCatalogTerm() {
823         return "CATALOG";
824     }
825
826     /**
827      * Does a catalog appear at the start of a qualified table name?
828      * (Otherwise it appears at the end)
829      *
830      * @return true if it appears at the start
831      *
832      */

833     public boolean isCatalogAtStart() {
834         return false;
835     }
836
837     /**
838      * What's the separator between catalog and table name?
839      *
840      * @return the separator string
841      *
842      */

843     public String JavaDoc getCatalogSeparator() {
844         return "";
845     }
846
847     /**
848      * Can a schema name be used in a data manipulation statement?
849      *
850      * @return true if so
851      *
852      */

853     public boolean supportsSchemasInDataManipulation() {
854         return true;
855     }
856
857     /**
858      * Can a schema name be used in a procedure call statement?
859      *
860      * @return true if so
861      *
862      */

863     public boolean supportsSchemasInProcedureCalls() {
864         return true;
865     }
866
867     /**
868      * Can a schema name be used in a table definition statement?
869      *
870      * @return true if so
871      *
872      */

873     public boolean supportsSchemasInTableDefinitions() {
874         return true;
875     }
876
877     /**
878      * Can a schema name be used in an index definition statement?
879      *
880      * @return true if so
881      */

882     public boolean supportsSchemasInIndexDefinitions() {
883         return true;
884     }
885
886     /**
887      * Can a schema name be used in a privilege definition statement?
888      *
889      * @return true if so
890      *
891      */

892     public boolean supportsSchemasInPrivilegeDefinitions() {
893         return true;
894     }
895
896     /**
897      * Can a catalog name be used in a data manipulation statement?
898      *
899      * @return true if so
900      *
901      */

902     public boolean supportsCatalogsInDataManipulation() {
903         return false;
904     }
905
906     /**
907      * Can a catalog name be used in a procedure call statement?
908      *
909      * @return true if so
910      *
911      */

912     public boolean supportsCatalogsInProcedureCalls() {
913         return false;
914     }
915
916     /**
917      * Can a catalog name be used in a table definition statement?
918      *
919      * @return true if so
920      *
921      */

922     public boolean supportsCatalogsInTableDefinitions() {
923         return false;
924     }
925
926     /**
927      * Can a catalog name be used in an index definition statement?
928      *
929      * @return true if so
930      */

931     public boolean supportsCatalogsInIndexDefinitions() {
932         return false;
933     }
934
935     /**
936      * Can a catalog name be used in a privilege definition statement?
937      *
938      * @return true if so
939      */

940     public boolean supportsCatalogsInPrivilegeDefinitions() {
941         return false;
942     }
943
944
945     /**
946      * Is positioned DELETE supported?
947      *
948      * @return true if so
949      */

950     public boolean supportsPositionedDelete() {
951         return true;
952     }
953
954     /**
955      * Is positioned UPDATE supported?
956      *
957      * @return true if so
958      */

959     public boolean supportsPositionedUpdate() {
960         return true;
961     }
962
963     /**
964      * Is SELECT for UPDATE supported?
965      *
966      * @return true if so
967      */

968     public boolean supportsSelectForUpdate() {
969         return true;
970     }
971
972     /**
973      * Are stored procedure calls using the stored procedure escape
974      * syntax supported?
975      *
976      * @return true if so
977      */

978     public boolean supportsStoredProcedures() {
979         return true;
980     }
981
982     /**
983      * Are subqueries in comparison expressions supported?
984      *
985      * A JDBC-Compliant driver always returns true.
986      *
987      * @return true if so
988      */

989     public boolean supportsSubqueriesInComparisons() {
990         return true;
991     }
992
993     /**
994      * Are subqueries in 'exists' expressions supported?
995      *
996      * A JDBC-Compliant driver always returns true.
997      *
998      * @return true if so
999      */

1000    public boolean supportsSubqueriesInExists() {
1001        return true;
1002    }
1003
1004    /**
1005     * Are subqueries in 'in' statements supported?
1006     *
1007     * A JDBC-Compliant driver always returns true.
1008     *
1009     * @return true if so
1010     */

1011    public boolean supportsSubqueriesInIns() {
1012        return true;
1013    }
1014
1015    /**
1016     * Are subqueries in quantified expressions supported?
1017     *
1018     * A JDBC-Compliant driver always returns true.
1019     *
1020     * @return true if so
1021     */

1022    public boolean supportsSubqueriesInQuantifieds() {
1023        return true;
1024    }
1025
1026    /**
1027     * Are correlated subqueries supported?
1028     *
1029     * A JDBC-Compliant driver always returns true.
1030     *
1031     * @return true if so
1032     */

1033    public boolean supportsCorrelatedSubqueries() {
1034        return true;
1035    }
1036
1037    /**
1038     * Is SQL UNION supported?
1039     *
1040     * @return true if so
1041     */

1042    public boolean supportsUnion() {
1043        return true;
1044    }
1045
1046    /**
1047     * Is SQL UNION ALL supported?
1048     *
1049     * @return true if so
1050     */

1051    public boolean supportsUnionAll() {
1052        return true;
1053    }
1054
1055    /**
1056     * Can cursors remain open across commits?
1057     *
1058     * @return true if cursors always remain open; false if they might not remain open
1059     */

1060    //returns false because Derby does not support cursors that are open across commits for XA transactions.
1061
public boolean supportsOpenCursorsAcrossCommit() {
1062        return false;
1063    }
1064
1065    /**
1066     * Can cursors remain open across rollbacks?
1067     *
1068     * @return true if cursors always remain open; false if they might not remain open
1069     */

1070    public boolean supportsOpenCursorsAcrossRollback() {
1071        return false;
1072    }
1073
1074    /**
1075     * Can statements remain open across commits?
1076     *
1077     * @return true if statements always remain open; false if they might not remain open
1078     */

1079    public boolean supportsOpenStatementsAcrossCommit() {
1080        return true;
1081    }
1082
1083    /**
1084     * Can statements remain open across rollbacks?
1085     *
1086     * @return true if statements always remain open; false if they might not remain open
1087     */

1088    public boolean supportsOpenStatementsAcrossRollback() {
1089        return false;
1090    }
1091
1092
1093
1094    //----------------------------------------------------------------------
1095
// The following group of methods exposes various limitations
1096
// based on the target database with the current driver.
1097
// Unless otherwise specified, a result of zero means there is no
1098
// limit, or the limit is not known.
1099

1100    /**
1101     * How many hex characters can you have in an inline binary literal?
1102     *
1103     * @return max literal length
1104     */

1105    public int getMaxBinaryLiteralLength() {
1106        return 0;
1107    }
1108
1109    /**
1110     * What's the max length for a character literal?
1111     *
1112     * @return max literal length
1113     */

1114    public int getMaxCharLiteralLength() {
1115        return 0;
1116    }
1117
1118    /**
1119     * What's the limit on column name length?
1120     *
1121     * @return max literal length
1122     */

1123    public int getMaxColumnNameLength() {
1124        return Limits.MAX_IDENTIFIER_LENGTH;
1125    }
1126
1127    /**
1128     * What's the maximum number of columns in a "GROUP BY" clause?
1129     *
1130     * @return max number of columns
1131     */

1132    public int getMaxColumnsInGroupBy() {
1133        return 0;
1134    }
1135
1136    /**
1137     * What's the maximum number of columns allowed in an index?
1138     *
1139     * @return max columns
1140     */

1141    public int getMaxColumnsInIndex() {
1142        return 0;
1143    }
1144
1145    /**
1146     * What's the maximum number of columns in an "ORDER BY" clause?
1147     *
1148     * @return max columns
1149     */

1150    public int getMaxColumnsInOrderBy() {
1151        return 0;
1152    }
1153
1154    /**
1155     * What's the maximum number of columns in a "SELECT" list?
1156     *
1157     * we don't have a limit...
1158     *
1159     * @return max columns
1160     */

1161    public int getMaxColumnsInSelect() {
1162        return 0;
1163    }
1164
1165    /**
1166     * What's the maximum number of columns in a table?
1167     *
1168     * @return max columns
1169     */

1170    public int getMaxColumnsInTable() {
1171        return 0;
1172    }
1173
1174    /**
1175     * How many active connections can we have at a time to this database?
1176     *
1177     * @return max connections
1178     */

1179    public int getMaxConnections() {
1180        return 0;
1181    }
1182
1183    /**
1184     * What's the maximum cursor name length?
1185     *
1186     * @return max cursor name length in bytes
1187     */

1188    public int getMaxCursorNameLength() {
1189        return Limits.MAX_IDENTIFIER_LENGTH;
1190    }
1191
1192    /**
1193     * What's the maximum length of an index (in bytes)?
1194     *
1195     * @return max index length in bytes
1196     */

1197    public int getMaxIndexLength() {
1198        return 0;
1199    }
1200
1201    /**
1202     * What's the maximum length allowed for a schema name?
1203     *
1204     * @return max name length in bytes
1205     */

1206    public int getMaxSchemaNameLength() {
1207        return Limits.MAX_IDENTIFIER_LENGTH;
1208    }
1209
1210    /**
1211     * What's the maximum length of a procedure name?
1212     *
1213     * @return max name length in bytes
1214     */

1215    public int getMaxProcedureNameLength() {
1216        return Limits.MAX_IDENTIFIER_LENGTH;
1217    }
1218
1219    /**
1220     * What's the maximum length of a catalog name?
1221     *
1222     * @return max name length in bytes
1223     */

1224    public int getMaxCatalogNameLength() {
1225        return 0;
1226    }
1227
1228    /**
1229     * What's the maximum length of a single row?
1230     *
1231     * @return max row size in bytes
1232     */

1233    public int getMaxRowSize() {
1234        return 0;
1235    }
1236
1237    /**
1238     * Did getMaxRowSize() include LONGVARCHAR and LONGVARBINARY
1239     * blobs?
1240     *
1241     * @return true if so
1242     */

1243    public boolean doesMaxRowSizeIncludeBlobs() {
1244        return true;
1245    }
1246
1247    /**
1248     * What's the maximum length of a SQL statement?
1249     *
1250     * @return max length in bytes
1251     */

1252    public int getMaxStatementLength() {
1253        return 0;
1254    }
1255
1256    /**
1257     * How many active statements can we have open at one time to this
1258     * database?
1259     *
1260     * @return the maximum
1261     */

1262    public int getMaxStatements() {
1263        return 0;
1264    }
1265
1266    /**
1267     * What's the maximum length of a table name?
1268     *
1269     * @return max name length in bytes
1270     */

1271    public int getMaxTableNameLength() {
1272        return Limits.MAX_IDENTIFIER_LENGTH;
1273    }
1274
1275    /**
1276     * What's the maximum number of tables in a SELECT?
1277     *
1278     * @return the maximum
1279     */

1280    public int getMaxTablesInSelect() {
1281        return 0;
1282    }
1283
1284    /**
1285     * What's the maximum length of a user name?
1286     *
1287     * @return max name length in bytes
1288     */

1289    public int getMaxUserNameLength() {
1290        return Limits.DB2_MAX_USERID_LENGTH;
1291    }
1292
1293    //----------------------------------------------------------------------
1294

1295    /**
1296     * What's the database's default transaction isolation level? The
1297     * values are defined in java.sql.Connection.
1298     *
1299     * @return the default isolation level
1300     * @see Connection
1301     */

1302    public int getDefaultTransactionIsolation() {
1303        return java.sql.Connection.TRANSACTION_READ_COMMITTED;
1304    }
1305
1306    /**
1307     * Are transactions supported? If not, commit is a noop and the
1308     * isolation level is TRANSACTION_NONE.
1309     *
1310     * @return true if transactions are supported
1311     */

1312    public boolean supportsTransactions() {
1313        return true;
1314    }
1315
1316    /**
1317     * Does the database support the given transaction isolation level?
1318     *
1319     * DatabaseMetaData.supportsTransactionIsolation() should return false for
1320     * isolation levels that are not supported even if a higher level can be
1321     * substituted.
1322     *
1323     * @param level the values are defined in java.sql.Connection
1324     * @return true if so
1325     * @see Connection
1326        */

1327    public boolean supportsTransactionIsolationLevel(int level)
1328                             {
1329        // REMIND: This is hard-coded for the moment because it doesn't nicely
1330
// fit within the framework we've set up for the rest of these values.
1331
// Part of the reason is that it has a parameter, so it's not just a
1332
// simple value look-up. Some ideas for the future on how to make this
1333
// not hard-coded:
1334
// - code it as a query: "select true from <something> where ? in
1335
// (a,b,c)" where a,b,c are the supported isolation levels. The
1336
// parameter would be set to "level". This seems awfully awkward.
1337
// - somehow what you'd really like is to enable the instructions
1338
// file to contain the list, or set, of supported isolation
1339
// levels. Something like:
1340
// supportsTr...ionLevel=SERIALIZABLE | REPEATABLE_READ | ...
1341
// That would take some more code that doesn't seem worthwhile at
1342
// the moment for this one case.
1343

1344        /*
1345            REMIND: this could be moved into a query that is e.g.
1346            VALUES ( ? in (8,...) )
1347            so that database could control the list of supported
1348            isolations. For now, it's hard coded, and just the one.
1349         */

1350
1351        return (level == Connection.TRANSACTION_SERIALIZABLE ||
1352                level == Connection.TRANSACTION_REPEATABLE_READ ||
1353                level == Connection.TRANSACTION_READ_COMMITTED ||
1354                level == Connection.TRANSACTION_READ_UNCOMMITTED);
1355    }
1356
1357    /**
1358     * Are both data definition and data manipulation statements
1359     * within a transaction supported?
1360     *
1361     * @return true if so
1362     */

1363    public boolean supportsDataDefinitionAndDataManipulationTransactions() {
1364             return true;
1365    }
1366    /**
1367     * Are only data manipulation statements within a transaction
1368     * supported?
1369     *
1370     * @return true if so
1371     */

1372    public boolean supportsDataManipulationTransactionsOnly()
1373    {
1374             return false;
1375    }
1376    /**
1377     * Does a data definition statement within a transaction force the
1378     * transaction to commit?
1379     *
1380     * @return true if so
1381     *
1382     */

1383    public boolean dataDefinitionCausesTransactionCommit() {
1384        return false;
1385    }
1386    /**
1387     * Is a data definition statement within a transaction ignored?
1388     *
1389     * @return true if so
1390     *
1391     */

1392    public boolean dataDefinitionIgnoredInTransactions(){
1393        return false;
1394    }
1395
1396
1397    /**
1398     * Get a description of stored procedures available in a
1399     * catalog.
1400     *
1401     * <P>Only procedure descriptions matching the schema and
1402     * procedure name criteria are returned. They are ordered by
1403     * PROCEDURE_SCHEM, and PROCEDURE_NAME.
1404     *
1405     * <P>Each procedure description has the the following columns:
1406     * <OL>
1407     * <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)
1408     * <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)
1409     * <LI><B>PROCEDURE_NAME</B> String => procedure name
1410     * <LI> reserved for future use
1411     * <LI> reserved for future use
1412     * <LI> reserved for future use
1413     * <LI><B>REMARKS</B> String => explanatory comment on the procedure
1414     * <LI><B>PROCEDURE_TYPE</B> short => kind of procedure:
1415     * <UL>
1416     * <LI> procedureResultUnknown - May return a result
1417     * <LI> procedureNoResult - Does not return a result
1418     * <LI> procedureReturnsResult - Returns a result
1419     * </UL>
1420     * <LI><B>SPECIFIC_NAME</B> String => The name which uniquely
1421     * identifies this procedure within its schema (since JDBC 4.0)
1422     * </OL>
1423     *
1424     * @param catalog a catalog name; "" retrieves those without a
1425     * catalog; null means drop catalog name from the selection criteria
1426     * @param schemaPattern a schema name pattern; "" retrieves those
1427     * without a schema
1428     * @param procedureNamePattern a procedure name pattern
1429     * @return ResultSet - each row is a procedure description
1430     * @see #getSearchStringEscape
1431     * @exception SQLException thrown on failure.
1432     */

1433    public ResultSet JavaDoc getProcedures(String JavaDoc catalog, String JavaDoc schemaPattern,
1434            String JavaDoc procedureNamePattern) throws SQLException JavaDoc {
1435
1436        // Using the new JDBC 4.0 version of the query here. The query
1437
// was given a new name to allow the old query to
1438
// be used by ODBCMetaDataGenerator.
1439
return doGetProcs(catalog, schemaPattern,
1440            procedureNamePattern, "getProcedures40");
1441    }
1442
1443    /**
1444     * Get a description of stored procedures available in a
1445     * catalog. Same as getProcedures() above, except that
1446     * the result set will conform to ODBC specifications.
1447     */

1448    public ResultSet JavaDoc getProceduresForODBC(String JavaDoc catalog, String JavaDoc schemaPattern,
1449            String JavaDoc procedureNamePattern) throws SQLException JavaDoc {
1450
1451        // For ODBC we still use the transformed version of the JDBC
1452
// 3.0 query, (may change in the future).
1453
return doGetProcs(catalog, schemaPattern,
1454            procedureNamePattern, "odbc_getProcedures");
1455    }
1456    
1457    /**
1458     * Implements DatabaseMetaData.getFunctions() for an embedded
1459     * database. Queries the database to get information about
1460     * functions (procedures returning values). Executes the
1461     * 'getFunctions' query from metadata.properties to obtain the
1462     * ResultSet to return.<p> Compatibility: This is a new method in
1463     * the API which is only available with with Derby versions > 10.1 and
1464     * JDK versions >= 1.6 <p>Upgrade: Since this is a new query it
1465     * does not have an SPS, and will be available as soon as any
1466     * database, new or old, is booted with the new version of Derby,
1467     * (in <b>soft and hard</b> upgrade).
1468     * @param catalog limit the search to functions in this catalog
1469     * (not used)
1470     * @param schemaPattern limit the search to functions in schemas
1471     * matching this pattern
1472     * @param functionNamePattern limit the search to functions
1473     * matching this pattern
1474     * @return a ResultSet with metadata information
1475     * @throws SQLException if any of the underlying jdbc methods fail
1476     */

1477    public ResultSet JavaDoc getFunctions(java.lang.String JavaDoc catalog,
1478                                  java.lang.String JavaDoc schemaPattern,
1479                                  java.lang.String JavaDoc functionNamePattern)
1480        throws SQLException JavaDoc
1481    {
1482        return doGetProcs(catalog, schemaPattern,
1483                   functionNamePattern, "getFunctions");
1484    }
1485
1486    /**
1487     * Does the actual work for the getProcedures and getFunctions
1488     * metadata calls. See getProcedures() method above for parameter
1489     * descriptions.
1490     * @param queryName Name of the query to execute; is used
1491     * to determine whether the result set should conform to
1492     * JDBC or ODBC specifications.
1493     */

1494    private ResultSet JavaDoc doGetProcs(String JavaDoc catalog, String JavaDoc schemaPattern,
1495        String JavaDoc procedureNamePattern, String JavaDoc queryName)
1496        throws SQLException JavaDoc {
1497
1498        PreparedStatement JavaDoc s = getPreparedQuery(queryName);
1499        s.setString(1, swapNull(catalog));
1500        s.setString(2, swapNull(schemaPattern));
1501        s.setString(3, swapNull(procedureNamePattern));
1502        return s.executeQuery();
1503    }
1504
1505    /**
1506     * Get a description of a catalog's stored procedure parameters
1507     * and result columns.
1508     *
1509     * <P>Only descriptions matching the schema, procedure and
1510     * parameter name criteria are returned. They are ordered by
1511     * PROCEDURE_SCHEM and PROCEDURE_NAME. Within this, the return value,
1512     * if any, is first. Next are the parameter descriptions in call
1513     * order. The column descriptions follow in column number order.
1514     *
1515     * <P>Each row in the ResultSet is a parameter description or
1516     * column description with the following fields:
1517     * <OL>
1518     * <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)
1519     * <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)
1520     * <LI><B>PROCEDURE_NAME</B> String => procedure name
1521     * <LI><B>COLUMN_NAME</B> String => column/parameter name
1522     * <LI><B>COLUMN_TYPE</B> Short => kind of column/parameter:
1523     * <UL>
1524     * <LI> procedureColumnUnknown - nobody knows
1525     * <LI> procedureColumnIn - IN parameter
1526     * <LI> procedureColumnInOut - INOUT parameter
1527     * <LI> procedureColumnOut - OUT parameter
1528     * <LI> procedureColumnReturn - procedure return value
1529     * <LI> procedureColumnResult - result column in ResultSet
1530     * </UL>
1531     * <LI><B>DATA_TYPE</B> int => SQL type from java.sql.Types
1532     * <LI><B>TYPE_NAME</B> String => SQL type name
1533     * <LI><B>PRECISION</B> int => precision
1534     * <LI><B>LENGTH</B> int => length in bytes of data
1535     * <LI><B>SCALE</B> short => scale
1536     * <LI><B>RADIX</B> short => radix
1537     * <LI><B>NULLABLE</B> short => can it contain NULL?
1538     * <UL>
1539     * <LI> procedureNoNulls - does not allow NULL values
1540     * <LI> procedureNullable - allows NULL values
1541     * <LI> procedureNullableUnknown - nullability unknown
1542     * </UL>
1543     * <LI><B>REMARKS</B> String => comment describing parameter/column
1544     * <LI><B>COLUMN_DEF</B> String
1545     * <LI><B>SQL_DATA_TYPE</B> int
1546     * <LI><B>SQL_DATETIME_SUB</B> int
1547     * <LI><B>CHAR_OCTET_LENGTH</B> int
1548     * <LI><B>ORDINAL_POSITION</B> int
1549     * <LI><B>IS_NULLABLE</B> String
1550     * <LI><B>SPECIFIC_NAME</B> String
1551     * </OL>
1552     *
1553     * <P><B>Note:</B> Some databases may not return the column
1554     * descriptions for a procedure. Additional columns beyond
1555     * SPECIFIC_NAME can be defined by the database.
1556     *
1557     * @param catalog a catalog name; "" retrieves those without a
1558     * catalog; null means drop catalog name from the selection criteria
1559     * @param schemaPattern a schema name pattern; "" retrieves those
1560     * without a schema
1561     * @param procedureNamePattern a procedure name pattern
1562     * @param columnNamePattern a column name pattern
1563     * @return ResultSet - each row is a stored procedure parameter or
1564     * column description
1565     * @see #getSearchStringEscape
1566     * @exception SQLException thrown on failure.
1567     */

1568    public ResultSet JavaDoc getProcedureColumns(String JavaDoc catalog,
1569            String JavaDoc schemaPattern,
1570            String JavaDoc procedureNamePattern,
1571            String JavaDoc columnNamePattern) throws SQLException JavaDoc {
1572
1573        // Using the new JDBC 4.0 version of the query here. The query
1574
// was given a new name to allow the old query to
1575
// be used by ODBCMetaDataGenerator.
1576
return doGetProcCols(catalog, schemaPattern,
1577            procedureNamePattern, columnNamePattern,
1578            "getProcedureColumns40");
1579    }
1580
1581    /**
1582     * Get a description of a catalog's stored procedure parameters
1583     * and result columns. Same as getProcedureColumns() above,
1584     * except that the result set will conform to ODBC specifications.
1585     */

1586    public ResultSet JavaDoc getProcedureColumnsForODBC(String JavaDoc catalog,
1587            String JavaDoc schemaPattern, String JavaDoc procedureNamePattern,
1588            String JavaDoc columnNamePattern) throws SQLException JavaDoc {
1589
1590        // For ODBC we still use the transformed version of the JDBC
1591
// 3.0 query, (may change in the future).
1592
return doGetProcCols(catalog, schemaPattern,
1593            procedureNamePattern, columnNamePattern,
1594            "odbc_getProcedureColumns");
1595    }
1596
1597    /**
1598     * Implements DatabaseMetaData.getFunctionColumns() for an embedded
1599     * database. Queries the database to get information about
1600     * function parameters. Executes the
1601     * 'getFunctionColumns' query from metadata.properties to obtain the
1602     * ResultSet.<p> Compatibility: This is a new method in
1603     * the API which is only available with with Derby versions > 10.1 and
1604     * JDK versions >= 1.6 <p>Upgrade: Since this is a new query it
1605     * does not have an SPS, and will be available as soon as any
1606     * database, new or old, is booted with the new version of Derby,
1607     * (in <b>soft and hard</b> upgrade).
1608     * @param catalog limit the search to functions in this catalog
1609     * (not used)
1610     * @param schemaPattern limit the search to functions in schemas
1611     * matching this pattern
1612     * @param functionNamePattern limit the search to functions
1613     * matching this pattern
1614     * @param parameterNamePattern limit the search parameters
1615     * matching this pattern
1616     * @return a ResultSet with metadata information
1617     * @throws SQLException if a database error occurs
1618     */

1619    public ResultSet JavaDoc getFunctionColumns(String JavaDoc catalog,
1620                                           String JavaDoc schemaPattern,
1621                                           String JavaDoc functionNamePattern,
1622                                           String JavaDoc parameterNamePattern)
1623        throws SQLException JavaDoc {
1624        PreparedStatement JavaDoc s = getPreparedQuery("getFunctionColumns");
1625
1626        // Cannot use doGetProcCols() because our query requires
1627
// parameterNamePattern twice, because both LIKE and = is
1628
// required to select parameters with an empty parameter
1629
// name. That is, WHERE paramName LIKE ? will not match an
1630
// empty paramName, but WHERE paramName LIKE ? OR paramName =
1631
// ? will.
1632
s.setString(1, swapNull(schemaPattern));
1633        s.setString(2, swapNull(functionNamePattern));
1634        s.setString(3, swapNull(parameterNamePattern));
1635        s.setString(4, swapNull(parameterNamePattern));
1636        return s.executeQuery();
1637    }
1638
1639    /**
1640     * Does the actual work for the getProcedureColumns metadata
1641     * calls. See getProcedureColumns() method above for parameter
1642     * descriptions.
1643     * @param queryName Name of the query to execute; is used
1644     * to determine whether the result set should conform to
1645     * JDBC or ODBC specifications.
1646     */

1647    private ResultSet JavaDoc doGetProcCols(String JavaDoc catalog, String JavaDoc schemaPattern,
1648            String JavaDoc procedureNamePattern, String JavaDoc columnNamePattern,
1649            String JavaDoc queryName) throws SQLException JavaDoc {
1650
1651        PreparedStatement JavaDoc s = getPreparedQuery(queryName);
1652        //
1653
// catalog is not part of the query
1654
//
1655
s.setString(1, swapNull(schemaPattern));
1656        s.setString(2, swapNull(procedureNamePattern));
1657        s.setString(3, swapNull(columnNamePattern));
1658        return s.executeQuery();
1659    }
1660
1661    /**
1662     * Get a description of tables available in a catalog.
1663     *
1664     * <P>Only table descriptions matching the catalog, schema, table
1665     * name and type criteria are returned. They are ordered by
1666     * TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.
1667     *
1668     * <P>Each table description has the following columns:
1669     * <OL>
1670     * <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1671     * <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1672     * <LI><B>TABLE_NAME</B> String => table name
1673     * <LI><B>TABLE_TYPE</B> String => table type. Typical types are "TABLE",
1674     * "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
1675     * "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
1676     * <LI><B>REMARKS</B> String => explanatory comment on the table
1677     * <LI><B>TYPE_CAT</B> String => the types catalog (may be
1678     * <code>null</code>)
1679     * <LI><B>TYPE_SCHEM</B> String => the types schema (may be
1680     * <code>null</code>)
1681     * <LI><B>TYPE_NAME</B> String => type name (may be
1682     * <code>null</code>)
1683     * <LI><B>SELF_REFERENCING_COL_NAME</B> String => name of the
1684     * designated "identifier" column of a typed table (may
1685     * be <code>null</code>)
1686     * <LI><B>REF_GENERATION</B> String => specifies how values in
1687     * SELF_REFERENCING_COL_NAME are created. Values are
1688     * "SYSTEM", "USER", "DERIVED". (may be
1689     * <code>null</code>)
1690     * </OL>
1691     *
1692     * <P><B>Note:</B> Some databases may not return information for
1693     * all tables.
1694     *
1695     * @param catalog a catalog name; "" retrieves those without a
1696     * catalog; null means drop catalog name from the selection criteria
1697     * @param schemaPattern a schema name pattern; "" retrieves those
1698     * without a schema
1699     * @param tableNamePattern a table name pattern
1700     * @param types a list of table types to include; null returns all types
1701     * @return ResultSet - each row is a table description
1702     * @see #getSearchStringEscape
1703     * @exception SQLException thrown on failure.
1704     */

1705    public ResultSet JavaDoc getTables(String JavaDoc catalog, String JavaDoc schemaPattern,
1706        String JavaDoc tableNamePattern, String JavaDoc types[]) throws SQLException JavaDoc {
1707        synchronized (getConnectionSynchronization()) {
1708                        setupContextStack();
1709            ResultSet JavaDoc rs = null;
1710            try {
1711            
1712            String JavaDoc queryText =
1713                getQueryDescriptions(false).getProperty("getTables");
1714
1715            /*
1716             * The query text is assumed to end with a "where" clause, so
1717             * that we can safely append
1718             * "and table_Type in ('xxx','yyy','zzz', ...)" and
1719             * have it become part of the where clause.
1720             *
1721             * Let's assume for now that the table type first char corresponds
1722             * to JBMS table type identifiers.
1723             */

1724            StringBuffer JavaDoc whereClauseTail = new StringBuffer JavaDoc(queryText);
1725
1726            if (types != null && types.length >= 1) {
1727                whereClauseTail.append(" AND TABLETYPE IN ('");
1728                whereClauseTail.append(types[0].substring(0, 1));
1729
1730                for (int i=1; i<types.length; i++) {
1731                    whereClauseTail.append("','");
1732                    whereClauseTail.append(types[i].substring(0, 1));
1733                }
1734                whereClauseTail.append("')");
1735            }
1736            // Add the order by clause after the 'in' list.
1737
whereClauseTail.append(
1738                " ORDER BY TABLE_TYPE, TABLE_SCHEM, TABLE_NAME");
1739
1740            PreparedStatement JavaDoc s =
1741                getEmbedConnection().prepareMetaDataStatement(whereClauseTail.toString());
1742
1743            s.setString(1, swapNull(catalog));
1744            s.setString(2, swapNull(schemaPattern));
1745            s.setString(3, swapNull(tableNamePattern));
1746
1747            rs = s.executeQuery();
1748            } catch (Throwable JavaDoc t) {
1749                throw handleException(t);
1750            } finally {
1751                restoreContextStack();
1752            }
1753
1754            return rs;
1755        }
1756    }
1757
1758    /**
1759     * Get the schema names available in this database. The results
1760     * are ordered by schema name.
1761     *
1762     * <P>The schema columns are:
1763     * <OL>
1764     * <li><strong>TABLE_SCHEM</strong> String =&gt; schema name</li>
1765     * <li><strong>TABLE_CATALOG</strong> String =&gt; catalog name
1766     * (may be <code>null</code>)</li>
1767     * </OL>
1768     *
1769     * @return ResultSet - each row is a schema description
1770     * @exception SQLException thrown on failure.
1771     */

1772    public ResultSet JavaDoc getSchemas() throws SQLException JavaDoc {
1773        return getSchemas(null, null);
1774    }
1775
1776    /**
1777     * Get the catalog names available in this database. The results
1778     * are ordered by catalog name.
1779     *
1780     * <P>The catalog column is:
1781     * <OL>
1782     * <LI><B>TABLE_CAT</B> String => catalog name
1783     * </OL>
1784     *
1785     * @return ResultSet - each row has a single String column that is a
1786     * catalog name
1787     * @exception SQLException thrown on failure.
1788     */

1789    public ResultSet JavaDoc getCatalogs() throws SQLException JavaDoc {
1790        return getSimpleQuery("getCatalogs");
1791    }
1792
1793    /**
1794     * Get the table types available in this database. The results
1795     * are ordered by table type.
1796     *
1797     * <P>The table type is:
1798     * <OL>
1799     * <LI><B>TABLE_TYPE</B> String => table type. Typical types are "TABLE",
1800     * "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
1801     * "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
1802     * </OL>
1803     *
1804     * @return ResultSet - each row has a single String column that is a
1805     * table type
1806     * @exception SQLException thrown on failure.
1807     */

1808    public ResultSet JavaDoc getTableTypes() throws SQLException JavaDoc {
1809        return getSimpleQuery("getTableTypes");
1810    }
1811
1812    /**
1813     * Get a description of table columns available in a catalog.
1814     *
1815     * <P>Only column descriptions matching the catalog, schema, table
1816     * and column name criteria are returned. They are ordered by
1817     * TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.
1818     *
1819     * <P>Each column description has the following columns:
1820     * <OL>
1821     * <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1822     * <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1823     * <LI><B>TABLE_NAME</B> String => table name
1824     * <LI><B>COLUMN_NAME</B> String => column name
1825     * <LI><B>DATA_TYPE</B> int => SQL type from java.sql.Types
1826     * <LI><B>TYPE_NAME</B> String => Data source dependent type name
1827     * <LI><B>COLUMN_SIZE</B> int => column size. For char or date
1828     * types this is the maximum number of characters, for numeric or
1829     * decimal types this is precision.
1830     * <LI><B>BUFFER_LENGTH</B> is not used.
1831     * <LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits
1832     * <LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)
1833     * <LI><B>NULLABLE</B> int => is NULL allowed?
1834     * <UL>
1835     * <LI> columnNoNulls - might not allow NULL values
1836     * <LI> columnNullable - definitely allows NULL values
1837     * <LI> columnNullableUnknown - nullability unknown
1838     * </UL>
1839     * <LI><B>REMARKS</B> String => comment describing column (may be null)
1840     * <LI><B>COLUMN_DEF</B> String => default value (may be null)
1841     * <LI><B>SQL_DATA_TYPE</B> int => unused
1842     * <LI><B>SQL_DATETIME_SUB</B> int => unused
1843     * <LI><B>CHAR_OCTET_LENGTH</B> int => for char types the
1844     * maximum number of bytes in the column
1845     * <LI><B>ORDINAL_POSITION</B> int => index of column in table
1846     * (starting at 1)
1847     * <LI><B>IS_NULLABLE</B> String => "NO" means column definitely
1848     * does not allow NULL values; "YES" means the column might
1849     * allow NULL values. An empty string means nobody knows.
1850     * <LI><B>SCOPE_CATLOG</B> String => catalog of table that is the
1851     * scope of a reference attribute (<code>null</code> if DATA_TYPE
1852     * isn't REF)
1853     * <LI><B>SCOPE_SCHEMA</B> String => schema of table that is the
1854     * scope of a reference attribute (<code>null</code> if the
1855     * DATA_TYPE isn't REF)
1856     * <LI><B>SCOPE_TABLE</B> String => table name that this the
1857     * scope of a reference attribure (<code>null</code> if the
1858     * DATA_TYPE isn't REF)
1859     * <LI><B>SOURCE_DATA_TYPE</B> short => source type of a distinct
1860     * type or user-generated Ref type, SQL type from java.sql.Types
1861     * (<code>null</code> if DATA_TYPE isn't DISTINCT or
1862     * user-generated REF)
1863     * <LI><B>IS_AUTOINCREMENT</B> String => Indicates whether this
1864     * column is auto incremented
1865     * <UL>
1866     * <LI> YES --- if the column is auto incremented
1867     * <LI> NO --- if the column is not auto incremented
1868     * <LI> empty string --- if it cannot be determined whether the
1869     * column is auto incremented parameter is unknown
1870     * </UL>
1871     * </OL>
1872     *
1873     * @param catalog a catalog name; "" retrieves those without a
1874     * catalog; null means drop catalog name from the selection criteria
1875     * @param schemaPattern a schema name pattern; "" retrieves those
1876     * without a schema
1877     * @param tableNamePattern a table name pattern
1878     * @param columnNamePattern a column name pattern
1879     * @return ResultSet - each row is a column description
1880     * @see #getSearchStringEscape
1881     * @exception SQLException thrown on failure.
1882     */

1883    public ResultSet JavaDoc getColumns(String JavaDoc catalog, String JavaDoc schemaPattern,
1884        String JavaDoc tableNamePattern, String JavaDoc columnNamePattern)
1885                    throws SQLException JavaDoc {
1886
1887        return doGetCols(catalog, schemaPattern, tableNamePattern,
1888            columnNamePattern, "getColumns");
1889    }
1890
1891    /**
1892     * Get a description of table columns available in a catalog.
1893     * Same as getColumns() above, except that the result set
1894     * will conform to ODBC specifications.
1895     */

1896    public ResultSet JavaDoc getColumnsForODBC(String JavaDoc catalog, String JavaDoc schemaPattern,
1897        String JavaDoc tableNamePattern, String JavaDoc columnNamePattern)
1898        throws SQLException JavaDoc {
1899
1900        return doGetCols(catalog, schemaPattern, tableNamePattern,
1901            columnNamePattern, "odbc_getColumns");
1902    }
1903
1904    /**
1905     * Does the actual work for the getColumns metadata calls.
1906     * See getColumns() method above for parameter descriptions.
1907     * @param queryName Name of the query to execute; is used
1908     * to determine whether the result set should conform to
1909     * JDBC or ODBC specifications.
1910     */

1911    private ResultSet JavaDoc doGetCols(String JavaDoc catalog, String JavaDoc schemaPattern,
1912        String JavaDoc tableNamePattern, String JavaDoc columnNamePattern,
1913        String JavaDoc queryName) throws SQLException JavaDoc {
1914
1915        PreparedStatement JavaDoc s = getPreparedQuery(queryName);
1916        s.setString(1, swapNull(catalog));
1917        s.setString(2, swapNull(schemaPattern));
1918        s.setString(3, swapNull(tableNamePattern));
1919        s.setString(4, swapNull(columnNamePattern));
1920        return s.executeQuery();
1921    }
1922
1923    /**
1924     * Get a description of the access rights for a table's columns.
1925     *
1926     * <P>Only privileges matching the column name criteria are
1927     * returned. They are ordered by COLUMN_NAME and PRIVILEGE.
1928     *
1929     * <P>Each privilige description has the following columns:
1930     * <OL>
1931     * <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1932     * <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1933     * <LI><B>TABLE_NAME</B> String => table name
1934     * <LI><B>COLUMN_NAME</B> String => column name
1935     * <LI><B>GRANTOR</B> => grantor of access (may be null)
1936     * <LI><B>GRANTEE</B> String => grantee of access
1937     * <LI><B>PRIVILEGE</B> String => name of access (SELECT,
1938     * INSERT, UPDATE, REFRENCES, ...)
1939     * <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
1940     * to grant to others; "NO" if not; null if unknown
1941     * </OL>
1942     *
1943     * @param catalog a catalog name; "" retrieves those without a
1944     * catalog; null means drop catalog name from the selection criteria
1945     * @param schema a schema name; "" retrieves those without a schema
1946     * @param table a table name
1947     * @param columnNamePattern a column name pattern
1948     * @return ResultSet - each row is a column privilege description
1949     * @see #getSearchStringEscape
1950     * @exception SQLException thrown on failure.
1951     */

1952    public ResultSet JavaDoc getColumnPrivileges(String JavaDoc catalog, String JavaDoc schema,
1953        String JavaDoc table, String JavaDoc columnNamePattern) throws SQLException JavaDoc {
1954        PreparedStatement JavaDoc s = getPreparedQuery("getColumnPrivileges");
1955        s.setString(1, swapNull(catalog));
1956        s.setString(2, swapNull(schema));
1957        s.setString(3, swapNull(table));
1958        s.setString(4, swapNull(columnNamePattern));
1959        return s.executeQuery();
1960    }
1961
1962    /**
1963     * Get a description of the access rights for each table available
1964     * in a catalog. Note that a table privilege applies to one or
1965     * more columns in the table. It would be wrong to assume that
1966     * this priviledge applies to all columns (this may be true for
1967     * some systems but is not true for all.)
1968     *
1969     * <P>Only privileges matching the schema and table name
1970     * criteria are returned. They are ordered by TABLE_SCHEM,
1971     * TABLE_NAME, and PRIVILEGE.
1972     *
1973     * <P>Each privilige description has the following columns:
1974     * <OL>
1975     * <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1976     * <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1977     * <LI><B>TABLE_NAME</B> String => table name
1978     * <LI><B>GRANTOR</B> => grantor of access (may be null)
1979     * <LI><B>GRANTEE</B> String => grantee of access
1980     * <LI><B>PRIVILEGE</B> String => name of access (SELECT,
1981     * INSERT, UPDATE, REFRENCES, ...)
1982     * <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
1983     * to grant to others; "NO" if not; null if unknown
1984     * </OL>
1985     *
1986     * @param catalog a catalog name; "" retrieves those without a
1987     * catalog; null means drop catalog name from the selection criteria
1988     * @param schemaPattern a schema name pattern; "" retrieves those
1989     * without a schema
1990     * @param tableNamePattern a table name pattern
1991     * @return ResultSet - each row is a table privilege description
1992     * @see #getSearchStringEscape
1993     * @exception SQLException thrown on failure.
1994     */

1995    public ResultSet JavaDoc getTablePrivileges(String JavaDoc catalog, String JavaDoc schemaPattern,
1996                String JavaDoc tableNamePattern) throws SQLException JavaDoc {
1997        PreparedStatement JavaDoc s = getPreparedQuery("getTablePrivileges");
1998        s.setString(1, swapNull(catalog));
1999        s.setString(2, swapNull(schemaPattern));
2000        s.setString(3, swapNull(tableNamePattern));
2001        return s.executeQuery();
2002    }
2003
2004    /**
2005     * Get a description of a table's optimal set of columns that
2006     * uniquely identifies a row. They are ordered by SCOPE.
2007     *
2008     * <P>Each column description has the following columns:
2009     * <OL>
2010     * <LI><B>SCOPE</B> short => actual scope of result
2011     * <UL>
2012     * <LI> bestRowTemporary - very temporary, while using row
2013     * <LI> bestRowTransaction - valid for remainder of current transaction
2014     * <LI> bestRowSession - valid for remainder of current session
2015     * </UL>
2016     * <LI><B>COLUMN_NAME</B> String => column name
2017     * <LI><B>DATA_TYPE</B> int => SQL data type from java.sql.Types
2018     * <LI><B>TYPE_NAME</B> String => Data source dependent type name
2019     * <LI><B>COLUMN_SIZE</B> int => precision
2020     * <LI><B>BUFFER_LENGTH</B> int => not used
2021     * <LI><B>DECIMAL_DIGITS</B> short => scale
2022     * <LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column
2023     * like an Oracle ROWID
2024     * <UL>
2025     * <LI> bestRowUnknown - may or may not be pseudo column
2026     * <LI> bestRowNotPseudo - is NOT a pseudo column
2027     * <LI> bestRowPseudo - is a pseudo column
2028     * </UL>
2029     * </OL>
2030     *
2031     * @param catalogPattern a catalog name; "" retrieves those without a
2032     * catalog; null means drop catalog name from the selection criteria
2033     * @param schemaPattern a schema name; "" retrieves those without a schema
2034     * @param tablePattern a table name
2035     * @param scope the scope of interest; use same values as SCOPE
2036     * @param nullable include columns that are nullable?
2037     * @return ResultSet - each row is a column description
2038     * @exception SQLException thrown on failure.
2039     */

2040    public ResultSet JavaDoc getBestRowIdentifier
2041    (
2042        String JavaDoc catalogPattern,
2043        String JavaDoc schemaPattern,
2044        String JavaDoc tablePattern,
2045        int scope,
2046        boolean nullable
2047    ) throws SQLException JavaDoc
2048    {
2049        return doGetBestRowId(catalogPattern, schemaPattern, tablePattern,
2050            scope, nullable, "");
2051    }
2052
2053    /**
2054     * Get a description of a table's optimal set of columns that
2055     * uniquely identifies a row. They are ordered by SCOPE.
2056     * Same as getBestRowIdentifier() above, except that the result
2057     * set will conform to ODBC specifications.
2058     */

2059    public ResultSet JavaDoc getBestRowIdentifierForODBC(String JavaDoc catalogPattern,
2060        String JavaDoc schemaPattern, String JavaDoc tablePattern, int scope,
2061        boolean nullable) throws SQLException JavaDoc {
2062
2063        return doGetBestRowId(catalogPattern, schemaPattern, tablePattern,
2064            scope, nullable, "odbc_");
2065    }
2066
2067    /**
2068     * Does the actual work for the getBestRowIdentifier metadata
2069     * calls. See getBestRowIdentifier() method above for parameter
2070     * descriptions.
2071     * @param queryPrefix Prefix to be appended to the names of
2072     * the queries used in this method. This is used
2073     * to determine whether the result set should conform to
2074     * JDBC or ODBC specifications.
2075     */

2076    private ResultSet JavaDoc doGetBestRowId(String JavaDoc catalogPattern,
2077        String JavaDoc schemaPattern, String JavaDoc tablePattern, int scope,
2078        boolean nullable, String JavaDoc queryPrefix) throws SQLException JavaDoc {
2079
2080        int nullableInIntForm = 0;
2081        if (nullable)
2082            nullableInIntForm = 1;
2083      
2084        if (catalogPattern == null)
2085        {
2086            catalogPattern = "%";
2087        }
2088        if (schemaPattern == null)
2089        {
2090            schemaPattern = "%";
2091        }
2092        if (tablePattern == null)
2093        {
2094            tablePattern = "%";
2095        }
2096
2097            PreparedStatement JavaDoc ps;
2098            boolean done;
2099    
2100            // scope value is bad, return an empty result
2101
if (scope < 0 || scope > 2) {
2102                ps = getPreparedQuery("getBestRowIdentifierEmpty");
2103                return ps.executeQuery();
2104            }
2105    
2106            // see if there is a primary key, use it.
2107
ps = getPreparedQuery("getBestRowIdentifierPrimaryKey");
2108            ps.setString(1,catalogPattern);
2109            ps.setString(2,schemaPattern);
2110            ps.setString(3,tablePattern);
2111    
2112            ResultSet JavaDoc rs = ps.executeQuery();
2113            done = rs.next();
2114            String JavaDoc constraintId = "";
2115            if (done) {
2116                constraintId = rs.getString(1);
2117            }
2118    
2119            rs.close();
2120            ps.close();
2121    
2122            if (done)
2123            {
2124                // this one's it, do the real thing and return it.
2125
// we don't need to check catalog, schema, table name
2126
// or scope again.
2127
ps = getPreparedQuery(queryPrefix + "getBestRowIdentifierPrimaryKeyColumns");
2128                ps.setString(1,constraintId);
2129                ps.setString(2,constraintId);
2130                // note, primary key columns aren't nullable,
2131
// so we skip the nullOk parameter.
2132
return ps.executeQuery();
2133            }
2134    
2135            // get the unique constraint with the fewest columns.
2136
ps = getPreparedQuery("getBestRowIdentifierUniqueConstraint");
2137            ps.setString(1,catalogPattern);
2138            ps.setString(2,schemaPattern);
2139            ps.setString(3,tablePattern);
2140    
2141            rs = ps.executeQuery();
2142            done = rs.next();
2143            if (done) {
2144                constraintId = rs.getString(1);
2145            }
2146            // REMIND: we need to actually check for null columns
2147
// and toss out constraints with null columns if they aren't
2148
// desired... recode this as a WHILE returning at the
2149
// first match or falling off the end.
2150

2151            rs.close();
2152            ps.close();
2153            if (done)
2154            {
2155                // this one's it, do the real thing and return it.
2156
ps = getPreparedQuery(queryPrefix + "getBestRowIdentifierUniqueKeyColumns");
2157                ps.setString(1,constraintId);
2158                ps.setString(2,constraintId);
2159                ps.setInt(3,nullableInIntForm);
2160                return ps.executeQuery();
2161            }
2162    
2163    
2164            // second-to last try -- unique index with minimal # columns
2165
// (only non null columns if so required)
2166
ps = getPreparedQuery("getBestRowIdentifierUniqueIndex");
2167            ps.setString(1,catalogPattern);
2168            ps.setString(2,schemaPattern);
2169            ps.setString(3,tablePattern);
2170    
2171            rs = ps.executeQuery();
2172            done = rs.next();
2173            long indexNum = 0;
2174            if (done) {
2175                indexNum = rs.getLong(1);
2176            }
2177            // REMIND: we need to actually check for null columns
2178
// and toss out constraints with null columns if they aren't
2179
// desired... recode this as a WHILE returning at the
2180
// first match or falling off the end.
2181

2182            rs.close();
2183            ps.close();
2184            if (done) {
2185                // this one's it, do the real thing and return it.
2186
ps = getPreparedQuery(queryPrefix + "getBestRowIdentifierUniqueIndexColumns");
2187                ps.setLong(1,indexNum);
2188                ps.setInt(2,nullableInIntForm);
2189                return ps.executeQuery();
2190            }
2191
2192            // last try -- just return all columns of the table
2193
// the not null ones if that restriction is upon us.
2194
ps = getPreparedQuery(queryPrefix + "getBestRowIdentifierAllColumns");
2195            ps.setString(1,catalogPattern);
2196            ps.setString(2,schemaPattern);
2197            ps.setString(3,tablePattern);
2198            ps.setInt(4,scope);
2199            ps.setInt(5,nullableInIntForm);
2200            return ps.executeQuery();
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.
2207     *
2208     * <P>Each column description has the following columns:
2209     * <OL>
2210     * <LI><B>SCOPE</B> short => is not used
2211     * <LI><B>COLUMN_NAME</B> String => column name
2212     * <LI><B>DATA_TYPE</B> int => SQL data type from java.sql.Types
2213     * <LI><B>TYPE_NAME</B> String => Data source dependent type name
2214     * <LI><B>COLUMN_SIZE</B> int => precision
2215     * <LI><B>BUFFER_LENGTH</B> int => length of column value in bytes
2216     * <LI><B>DECIMAL_DIGITS</B> short => scale
2217     * <LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column
2218     * like an Oracle ROWID
2219     * <UL>
2220     * <LI> versionColumnUnknown - may or may not be pseudo column
2221     * <LI> versionColumnNotPseudo - is NOT a pseudo column
2222     * <LI> versionColumnPseudo - is a pseudo column
2223     * </UL>
2224     * </OL>
2225     *
2226     * @param catalog a catalog name; "" retrieves those without a
2227     * catalog; null means drop catalog name from the selection criteria
2228     * @param schema a schema name; "" retrieves those without a schema
2229     * @param table a table name
2230     * @return ResultSet - each row is a column description
2231     * @exception SQLException thrown on failure.
2232     */

2233    public ResultSet JavaDoc getVersionColumns(String JavaDoc catalog, String JavaDoc schema,
2234                String JavaDoc table) throws SQLException JavaDoc {
2235        return doGetVersionCols(catalog, schema, table, "getVersionColumns");
2236    }
2237
2238    /**
2239     * Get a description of a table's columns that are automatically
2240     * updated when any value in a row is updated. They are
2241     * unordered. Same as getVersionColumns() above, except that
2242     * the result set will conform to ODBC specifications.
2243     */

2244    public ResultSet JavaDoc getVersionColumnsForODBC(String JavaDoc catalog, String JavaDoc schema,
2245                String JavaDoc table) throws SQLException JavaDoc {
2246        return doGetVersionCols(catalog, schema, table, "odbc_getVersionColumns");
2247    }
2248
2249    /**
2250     * Does the actual work for the getVersionColumns metadata
2251     * calls. See getVersionColumns() method above for parameter
2252     * descriptions.
2253     * @param queryName Name of the query to execute; is used
2254     * to determine whether the result set should conform to
2255     * JDBC or ODBC specifications.
2256     */

2257    private ResultSet JavaDoc doGetVersionCols(String JavaDoc catalog, String JavaDoc schema,
2258        String JavaDoc table, String JavaDoc queryName) throws SQLException JavaDoc {
2259
2260        PreparedStatement JavaDoc s = getPreparedQuery(queryName);
2261        s.setString(1, swapNull(catalog));
2262        s.setString(2, swapNull(schema));
2263        s.setString(3, swapNull(table));
2264        return s.executeQuery();
2265    }
2266
2267    /**
2268     * check if the dictionary is at the same version as the engine. If not,
2269     * then that means stored versions of the JDBC database metadata queries
2270     * may not be compatible with this version of the software.
2271     * This can happen if we are in soft upgrade mode. Since in soft upgrade
2272     * mode, we can't change these stored metadata queries in a backward
2273     * incompatible way, engine needs to read the metadata sql from
2274     * metadata.properties or metadata_net.properties file rather than
2275     * rely on system tables.
2276     *
2277     * @return true if we are not in soft upgrade mode
2278     * @throws SQLException
2279     */

2280    private boolean notInSoftUpgradeMode()
2281        throws SQLException JavaDoc {
2282        if ( getEmbedConnection().isClosed())
2283            throw Util.noCurrentConnection();
2284
2285        boolean notInSoftUpgradeMode;
2286        try {
2287            notInSoftUpgradeMode =
2288                getLanguageConnectionContext().getDataDictionary().checkVersion(
2289                        DataDictionary.DD_VERSION_CURRENT,null);
2290        } catch (Throwable JavaDoc t) {
2291            throw handleException(t);
2292        }
2293        return notInSoftUpgradeMode;
2294    }
2295    
2296    
2297    /**
2298     * Get a description of a table's primary key columns. They
2299     * are ordered by COLUMN_NAME.
2300     *
2301     * <P>Each primary key column description has the following columns:
2302     * <OL>
2303     * <LI><B>TABLE_CAT</B> String => table catalog (may be null)
2304     * <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
2305     * <LI><B>TABLE_NAME</B> String => table name
2306     * <LI><B>COLUMN_NAME</B> String => column name
2307     * <LI><B>KEY_SEQ</B> short => sequence number within primary key
2308     * <LI><B>PK_NAME</B> String => primary key name (may be null)
2309     * </OL>
2310     *
2311     * @param catalog a catalog name; "" retrieves those without a
2312     * catalog; null means drop catalog name from the selection criteria
2313     * @param schema a schema name pattern; "" retrieves those
2314     * without a schema
2315     * @param table a table name
2316     * @return ResultSet - each row is a primary key column description
2317     * @exception SQLException thrown on failure.
2318     */

2319    public ResultSet JavaDoc getPrimaryKeys(String JavaDoc catalog, String JavaDoc schema,
2320            String JavaDoc table) throws SQLException JavaDoc {
2321        PreparedStatement JavaDoc s = getPreparedQuery("getPrimaryKeys");
2322        s.setString(1, swapNull(catalog));
2323        s.setString(2, swapNull(schema));
2324        s.setString(3, swapNull(table));
2325        return s.executeQuery();
2326    }
2327
2328    /**
2329     * Get a description of the primary key columns that are
2330     * referenced by a table's foreign key columns (the primary keys
2331     * imported by a table). They are ordered by PKTABLE_CAT,
2332     * PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ.
2333     *
2334     * <P>Each primary key column description has the following columns:
2335     * <OL>
2336     * <LI><B>PKTABLE_CAT</B> String => primary key table catalog
2337     * being imported (may be null)
2338     * <LI><B>PKTABLE_SCHEM</B> String => primary key table schema
2339     * being imported (may be null)
2340     * <LI><B>PKTABLE_NAME</B> String => primary key table name
2341     * being imported
2342     * <LI><B>PKCOLUMN_NAME</B> String => primary key column name
2343     * being imported
2344     * <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
2345     * <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
2346     * <LI><B>FKTABLE_NAME</B> String => foreign key table name
2347     * <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
2348     * <LI><B>KEY_SEQ</B> short => sequence number within foreign key
2349     * <LI><B>UPDATE_RULE</B> short => What happens to
2350     * foreign key when primary is updated:
2351     * <UL>
2352     * <LI> importedNoAction - do not allow update of primary
2353     * key if it has been imported
2354     * <LI> importedKeyCascade - change imported key to agree
2355     * with primary key update
2356     * <LI> importedKeySetNull - change imported key to NULL if
2357     * its primary key has been updated
2358     * <LI> importedKeySetDefault - change imported key to default values
2359     * if its primary key has been updated
2360     * <LI> importedKeyRestrict - same as importedKeyNoAction
2361     * (for ODBC 2.x compatibility)
2362     * </UL>
2363     * <LI><B>DELETE_RULE</B> short => What happens to
2364     * the foreign key when primary is deleted.
2365     * <UL>
2366     * <LI> importedKeyNoAction - do not allow delete of primary
2367     * key if it has been imported
2368     * <LI> importedKeyCascade - delete rows that import a deleted key
2369     * <LI> importedKeySetNull - change imported key to NULL if
2370     * its primary key has been deleted
2371     * <LI> importedKeyRestrict - same as importedKeyNoAction
2372     * (for ODBC 2.x compatibility)
2373     * <LI> importedKeySetDefault - change imported key to default if
2374     * its primary key has been deleted
2375     * </UL>
2376     * <LI><B>FK_NAME</B> String => foreign key name (may be null)
2377     * <LI><B>PK_NAME</B> String => primary key name (may be null)
2378     * <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
2379     * constraints be deferred until commit
2380     * <UL>
2381     * <LI> importedKeyInitiallyDeferred - see SQL92 for definition
2382     * <LI> importedKeyInitiallyImmediate - see SQL92 for definition
2383     * <LI> importedKeyNotDeferrable - see SQL92 for definition
2384     * </UL>
2385     * </OL>
2386     *
2387     * @param catalog a catalog name; "" retrieves those without a
2388     * catalog; null means drop catalog name from the selection criteria
2389     * @param schema a schema name pattern; "" retrieves those
2390     * without a schema
2391     * @param table a table name
2392     * @return ResultSet - each row is a primary key column description
2393     * @see #getExportedKeys
2394     * @exception SQLException thrown on failure.
2395     */

2396    public ResultSet JavaDoc getImportedKeys(String JavaDoc catalog, String JavaDoc schema,
2397                String JavaDoc table) throws SQLException JavaDoc {
2398        PreparedStatement JavaDoc s = getPreparedQuery("getImportedKeys");
2399        s.setString(1, swapNull(catalog));
2400        s.setString(2, swapNull(schema));
2401        s.setString(3, swapNull(table));
2402        return s.executeQuery();
2403    }
2404
2405
2406    /**
2407     * Get a description of the foreign key columns that reference a
2408     * table's primary key columns (the foreign keys exported by a
2409     * table). They are ordered by FKTABLE_CAT, FKTABLE_SCHEM,
2410     * FKTABLE_NAME, and KEY_SEQ.
2411     *
2412     * <P>Each foreign key column description has the following columns:
2413     * <OL>
2414     * <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)
2415     * <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)
2416     * <LI><B>PKTABLE_NAME</B> String => primary key table name
2417     * <LI><B>PKCOLUMN_NAME</B> String => primary key column name
2418     * <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
2419     * being exported (may be null)
2420     * <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
2421     * being exported (may be null)
2422     * <LI><B>FKTABLE_NAME</B> String => foreign key table name
2423     * being exported
2424     * <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
2425     * being exported
2426     * <LI><B>KEY_SEQ</B> short => sequence number within foreign key
2427     * <LI><B>UPDATE_RULE</B> short => What happens to
2428     * foreign key when primary is updated:
2429     * <UL>
2430     * <LI> importedNoAction - do not allow update of primary
2431     * key if it has been imported
2432     * <LI> importedKeyCascade - change imported key to agree
2433     * with primary key update
2434     * <LI> importedKeySetNull - change imported key to NULL if
2435     * its primary key has been updated
2436     * <LI> importedKeySetDefault - change imported key to default values
2437     * if its primary key has been updated
2438     * <LI> importedKeyRestrict - same as importedKeyNoAction
2439     * (for ODBC 2.x compatibility)
2440     * </UL>
2441     * <LI><B>DELETE_RULE</B> short => What happens to
2442     * the foreign key when primary is deleted.
2443     * <UL>
2444     * <LI> importedKeyNoAction - do not allow delete of primary
2445     * key if it has been imported
2446     * <LI> importedKeyCascade - delete rows that import a deleted key
2447     * <LI> importedKeySetNull - change imported key to NULL if
2448     * its primary key has been deleted
2449     * <LI> importedKeyRestrict - same as importedKeyNoAction
2450     * (for ODBC 2.x compatibility)
2451     * <LI> importedKeySetDefault - change imported key to default if
2452     * its primary key has been deleted
2453     * </UL>
2454     * <LI><B>FK_NAME</B> String => foreign key name (may be null)
2455     * <LI><B>PK_NAME</B> String => primary key name (may be null)
2456     * <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
2457     * constraints be deferred until commit
2458     * <UL>
2459     * <LI> importedKeyInitiallyDeferred - see SQL92 for definition
2460     * <LI> importedKeyInitiallyImmediate - see SQL92 for definition
2461     * <LI> importedKeyNotDeferrable - see SQL92 for definition
2462     * </UL>
2463     * </OL>
2464     *
2465     * @param catalog a catalog name; "" retrieves those without a
2466     * catalog; null means drop catalog name from the selection criteria
2467     * @param schema a schema name pattern; "" retrieves those
2468     * without a schema
2469     * @param table a table name
2470     * @return ResultSet - each row is a foreign key column description
2471     * @see #getImportedKeys
2472     * @exception SQLException thrown on failure.
2473     */

2474    public ResultSet JavaDoc getExportedKeys(String JavaDoc catalog, String JavaDoc schema,
2475                String JavaDoc table) throws SQLException JavaDoc {
2476        PreparedStatement JavaDoc s = getPreparedQuery("getCrossReference");
2477        s.setString(1, swapNull(catalog));
2478        s.setString(2, swapNull(schema));
2479        s.setString(3, swapNull(table));
2480        s.setString(4, swapNull(null));
2481        s.setString(5, swapNull(null));
2482        s.setString(6, swapNull(null));
2483        return s.executeQuery();
2484    }
2485
2486    /**
2487     * Get a description of the foreign key columns in the foreign key
2488     * table that reference the primary key columns of the primary key
2489     * table (describe how one table imports another's key.) This
2490     * should normally return a single foreign key/primary key pair
2491     * (most tables only import a foreign key from a table once.) They
2492     * are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and
2493     * KEY_SEQ.
2494     *
2495     * <P>Each foreign key column description has the following columns:
2496     * <OL>
2497     * <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)
2498     * <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)
2499     * <LI><B>PKTABLE_NAME</B> String => primary key table name
2500     * <LI><B>PKCOLUMN_NAME</B> String => primary key column name
2501     * <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
2502     * being exported (may be null)
2503     * <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
2504     * being exported (may be null)
2505     * <LI><B>FKTABLE_NAME</B> String => foreign key table name
2506     * being exported
2507     * <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
2508     * being exported
2509     * <LI><B>KEY_SEQ</B> short => sequence number within foreign key
2510     * <LI><B>UPDATE_RULE</B> short => What happens to
2511     * foreign key when primary is updated:
2512     * <UL>
2513     * <LI> importedNoAction - do not allow update of primary
2514     * key if it has been imported
2515     * <LI> importedKeyCascade - change imported key to agree
2516     * with primary key update
2517     * <LI> importedKeySetNull - change imported key to NULL if
2518     * its primary key has been updated
2519     * <LI> importedKeySetDefault - change imported key to default values
2520     * if its primary key has been updated
2521     * <LI> importedKeyRestrict - same as importedKeyNoAction
2522     * (for ODBC 2.x compatibility)
2523     * </UL>
2524     * <LI><B>DELETE_RULE</B> short => What happens to
2525     * the foreign key when primary is deleted.
2526     * <UL>
2527     * <LI> importedKeyNoAction - do not allow delete of primary
2528     * key if it has been imported
2529     * <LI> importedKeyCascade - delete rows that import a deleted key
2530     * <LI> importedKeySetNull - change imported key to NULL if
2531     * its primary key has been deleted
2532     * <LI> importedKeyRestrict - same as importedKeyNoAction
2533     * (for ODBC 2.x compatibility)
2534     * <LI> importedKeySetDefault - change imported key to default if
2535     * its primary key has been deleted
2536     * </UL>
2537     * <LI><B>FK_NAME</B> String => foreign key name (may be null)
2538     * <LI><B>PK_NAME</B> String => primary key name (may be null)
2539     * <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
2540     * constraints be deferred until commit
2541     * <UL>
2542     * <LI> importedKeyInitiallyDeferred - see SQL92 for definition
2543     * <LI> importedKeyInitiallyImmediate - see SQL92 for definition
2544     * <LI> importedKeyNotDeferrable - see SQL92 for definition
2545     * </UL>
2546     * </OL>
2547     *
2548     * @param primaryCatalog a catalog name; "" retrieves those without a
2549     * catalog; null means drop catalog name from the selection criteria
2550     * @param primarySchema a schema name pattern; "" retrieves those
2551     * without a schema
2552     * @param primaryTable the table name that exports the key
2553     * @param foreignCatalog a catalog name; "" retrieves those without a
2554     * catalog; null means drop catalog name from the selection criteria
2555     * @param foreignSchema a schema name pattern; "" retrieves those
2556     * without a schema
2557     * @param foreignTable the table name that imports the key
2558     * @return ResultSet - each row is a foreign key column description
2559     * @see #getImportedKeys
2560     * @exception SQLException thrown on failure.
2561     */

2562    public ResultSet JavaDoc getCrossReference(
2563        String JavaDoc primaryCatalog, String JavaDoc primarySchema, String JavaDoc primaryTable,
2564        String JavaDoc foreignCatalog, String JavaDoc foreignSchema, String JavaDoc foreignTable
2565        ) throws SQLException JavaDoc {
2566        PreparedStatement JavaDoc s = getPreparedQuery("getCrossReference");
2567        s.setString(1, swapNull(primaryCatalog));
2568        s.setString(2, swapNull(primarySchema));
2569        s.setString(3, swapNull(primaryTable));
2570        s.setString(4, swapNull(foreignCatalog));
2571        s.setString(5, swapNull(foreignSchema));
2572        s.setString(6, swapNull(foreignTable));
2573        return s.executeQuery();
2574    }
2575
2576    /**
2577     * Get a description of all the standard SQL types supported by
2578     * this database. They are ordered by DATA_TYPE and then by how
2579     * closely the data type maps to the corresponding JDBC SQL type.
2580     *
2581     * <P>Each type description has the following columns:
2582     * <OL>
2583     * <LI><B>TYPE_NAME</B> String => Type name
2584     * <LI><B>DATA_TYPE</B> int => SQL data type from java.sql.Types
2585     * <LI><B>PRECISION</B> int => maximum precision
2586     * <LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal
2587     * (may be null)
2588     * <LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal
2589            (may be null)
2590     * <LI><B>CREATE_PARAMS</B> String => parameters used in creating
2591     * the type (may be null)
2592     * <LI><B>NULLABLE</B> short => can you use NULL for this type?
2593     * <UL>
2594     * <LI> typeNoNulls - does not allow NULL values
2595     * <LI> typeNullable - allows NULL values
2596     * <LI> typeNullableUnknown - nullability unknown
2597     * </UL>
2598     * <LI><B>CASE_SENSITIVE</B> boolean=> is it case sensitive?
2599     * <LI><B>SEARCHABLE</B> short => can you use "WHERE" based on this type:
2600     * <UL>
2601     * <LI> typePredNone - No support
2602     * <LI> typePredChar - Only supported with WHERE .. LIKE
2603     * <LI> typePredBasic - Supported except for WHERE .. LIKE
2604     * <LI> typeSearchable - Supported for all WHERE ..
2605     * </UL>
2606     * <LI><B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned?
2607     * <LI><B>FIXED_PREC_SCALE</B> boolean => can it be a money value?
2608     * <LI><B>AUTO_INCREMENT</B> boolean => can it be used for an
2609     * auto-increment value?
2610     * <LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name
2611     * (may be null)
2612     * <LI><B>MINIMUM_SCALE</B> short => minimum scale supported
2613     * <LI><B>MAXIMUM_SCALE</B> short => maximum scale supported
2614     * <LI><B>SQL_DATA_TYPE</B> int => unused
2615     * <LI><B>SQL_DATETIME_SUB</B> int => unused
2616     * <LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10
2617     * </OL>
2618     *
2619     * @return ResultSet - each row is a SQL type description
2620     * @exception SQLException thrown on failure.
2621     */

2622    public ResultSet JavaDoc getTypeInfo() throws SQLException JavaDoc {
2623        return getSimpleQuery("getTypeInfo");
2624    }
2625
2626    /**
2627     * Get a description of all the standard SQL types supported by
2628     * this database. They are ordered by DATA_TYPE and then by how
2629     * closely the data type maps to the corresponding JDBC SQL type.
2630     * Same as getTypeInfo above, except that the result set will
2631     * conform to ODBC specifications.
2632     */

2633    public ResultSet JavaDoc getTypeInfoForODBC() throws SQLException JavaDoc {
2634        return getSimpleQuery("odbc_getTypeInfo");
2635    }
2636
2637    /**
2638     * Get a description of a table's indices and statistics. They are
2639     * ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.
2640     *
2641     * <P>Each index column description has the following columns:
2642     * <OL>
2643     * <LI><B>TABLE_CAT</B> String => table catalog (may be null)
2644     * <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
2645     * <LI><B>TABLE_NAME</B> String => table name
2646     * <LI><B>NON_UNIQUE</B> boolean => Can index values be non-unique?
2647     * false when TYPE is tableIndexStatistic
2648     * <LI><B>INDEX_QUALIFIER</B> String => index catalog (may be null);
2649     * null when TYPE is tableIndexStatistic
2650     * <LI><B>INDEX_NAME</B> String => index name; null when TYPE is
2651     * tableIndexStatistic
2652     * <LI><B>TYPE</B> short => index type:
2653     * <UL>
2654     * <LI> tableIndexStatistic - this identifies table statistics that are
2655     * returned in conjuction with a table's index descriptions
2656     * <LI> tableIndexClustered - this is a clustered index
2657     * <LI> tableIndexHashed - this is a hashed index
2658     * <LI> tableIndexOther - this is some other style of index
2659     * </UL>
2660     * <LI><B>ORDINAL_POSITION</B> short => column sequence number
2661     * within index; zero when TYPE is tableIndexStatistic
2662     * <LI><B>COLUMN_NAME</B> String => column name; null when TYPE is
2663     * tableIndexStatistic
2664     * <LI><B>ASC_OR_DESC</B> String => column sort sequence, "A" => ascending,
2665     * "D" => descending, may be null if sort sequence is not supported;
2666     * null when TYPE is tableIndexStatistic
2667     * <LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatistic, then
2668     * this is the number of rows in the table; otherwise, it is the
2669     * number of unique values in the index.
2670     * <LI><B>PAGES</B> int => When TYPE is tableIndexStatisic then
2671     * this is the number of pages used for the table, otherwise it
2672     * is the number of pages used for the current index.
2673     * <LI><B>FILTER_CONDITION</B> String => Filter condition, if any.
2674     * (may be null)
2675     * </OL>
2676     *
2677     * @param catalog a catalog name; "" retrieves those without a
2678     * catalog; null means drop catalog name from the selection criteria
2679     * @param schema a schema name pattern; "" retrieves those without a schema
2680     * @param table a table name
2681     * @param unique when true, return only indices for unique values;
2682     * when false, return indices regardless of whether unique or not
2683     * @param approximate when true, result is allowed to reflect approximate
2684     * or out of data values; when false, results are requested to be
2685     * accurate
2686     * @return ResultSet - each row is an index column description
2687     * @exception SQLException thrown on failure.
2688     */

2689    public ResultSet JavaDoc getIndexInfo(String JavaDoc catalog, String JavaDoc schema, String JavaDoc table,
2690            boolean unique, boolean approximate)
2691                    throws SQLException JavaDoc {
2692        return doGetIndexInfo(catalog, schema, table, unique, approximate, "getIndexInfo");
2693    }
2694
2695    /**
2696     * Get a description of a table's indices and statistics. They are
2697     * ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.
2698     * Same as getIndexInfo above, except that the result set will
2699     * conform to ODBC specifications.
2700     */

2701    public ResultSet JavaDoc getIndexInfoForODBC(String JavaDoc catalog, String JavaDoc schema, String JavaDoc table,
2702        boolean unique, boolean approximate) throws SQLException JavaDoc
2703    {
2704        return doGetIndexInfo(catalog, schema, table, unique, approximate, "odbc_getIndexInfo");
2705    }
2706
2707    /**
2708     * Does the actual work for the getIndexInfo metadata
2709     * calls. See getIndexInfo() method above for parameter
2710     * descriptions.
2711     * @param queryName Name of the query to execute; is used
2712     * to determine whether the result set should conform to
2713     * JDBC or ODBC specifications.
2714     */

2715    private ResultSet JavaDoc doGetIndexInfo(String JavaDoc catalog, String JavaDoc schema, String JavaDoc table,
2716        boolean unique, boolean approximate, String JavaDoc queryName)
2717        throws SQLException JavaDoc {
2718
2719        int approximateInInt = 0;
2720        if (approximate) approximateInInt = 1;
2721        PreparedStatement JavaDoc s = getPreparedQuery(queryName);
2722        s.setString(1, swapNull(catalog));
2723        s.setString(2, swapNull(schema));
2724        s.setString(3, swapNull(table));
2725        s.setBoolean(4, unique);
2726        s.setInt(5, approximateInInt);
2727        return s.executeQuery();
2728    }
2729
2730    /////////////////////////////////////////////////////////////////////////
2731
//
2732
// JDBC 2.0 - New public methods
2733
//
2734
/////////////////////////////////////////////////////////////////////////
2735

2736    /**
2737     * JDBC 2.0
2738     *
2739     * Does the database support the given result set type?
2740     *
2741     * @param type defined in java.sql.ResultSet
2742     * @return true if so
2743     * @see Connection
2744     */

2745    public boolean supportsResultSetType(int type) {
2746        if ((type == JDBC20Translation.TYPE_FORWARD_ONLY) ||
2747            (type == JDBC20Translation.TYPE_SCROLL_INSENSITIVE)) {
2748            return true;
2749        }
2750    //we don't support TYPE_SCROLL_SENSITIVE yet.
2751
return false;
2752    }
2753
2754    /**
2755     * JDBC 2.0
2756     *
2757     * Does the database support the concurrency type in combination
2758     * with the given result set type?
2759     *
2760     * @param type defined in java.sql.ResultSet
2761     * @param concurrency type defined in java.sql.ResultSet
2762     * @return true if so
2763     * @see Connection
2764     */

2765    public boolean supportsResultSetConcurrency(int type, int concurrency) {
2766        if (type == JDBC20Translation.TYPE_SCROLL_SENSITIVE) {
2767            // (TYPE_SCROLL_SENSITIVE, *)
2768
return false;
2769        } else {
2770            // (FORWARD_ONLY, CONCUR_UPDATABLE)
2771
// (FORWARD_ONLY, CONCUR_READ_ONLY)
2772
// (TYPE_SCROLL_INSENSITIVE, CONCUR_UPDATABLE)
2773
// (TYPE_SCROLL_INSENSITIVE, READ_ONLY)
2774
return true;
2775        }
2776    }
2777
2778    /**
2779     * JDBC 2.0
2780     *
2781     * Determine whether a result set's updates are visible.
2782     *
2783     * @param type result set type, i.e. ResultSet.TYPE_XXX
2784     * @return true if updates are visible for the result set type
2785     */

2786    public boolean ownUpdatesAreVisible(int type) {
2787        if (type == JDBC20Translation.TYPE_SCROLL_INSENSITIVE) {
2788            return true;
2789        } else {
2790            return false;
2791        }
2792    }
2793 
2794    /**
2795     * JDBC 2.0
2796     *
2797     * Determine whether a result set's deletes are visible.
2798     *
2799     * @param type result set type, i.e. ResultSet.TYPE_XXX
2800     * @return true if deletes are visible for the result set type
2801     */

2802    public boolean ownDeletesAreVisible(int type) {
2803        if (type == JDBC20Translation.TYPE_SCROLL_INSENSITIVE) {
2804            return true;
2805        } else {
2806            return false;
2807        }
2808    }
2809 
2810     /**
2811      * JDBC 2.0
2812      *
2813      * Determine whether a result set's inserts are visible.
2814      *
2815      * @param type result set type, i.e. ResultSet.TYPE_XXX
2816      * @return true if inserts are visible for the result set type
2817      */

2818     public boolean ownInsertsAreVisible(int type) {
2819        return false;
2820    }
2821
2822      // Since Derby materializes a forward only ResultSet incrementally, it is
2823
// possible to see changes made by others and hence following 3 metadata
2824
// calls will return true for forward only ResultSets.
2825

2826      /**
2827       * JDBC 2.0
2828       *
2829       * Determine whether updates made by others are visible.
2830       *
2831       * @param type result set type, i.e. ResultSet.TYPE_XXX
2832       * @return true if updates are visible for the result set type
2833       */

2834    public boolean othersUpdatesAreVisible(int type) {
2835        if (type == JDBC20Translation.TYPE_FORWARD_ONLY)
2836            return true;
2837        return false;
2838    }
2839
2840    /**
2841     * JDBC 2.0
2842     *
2843     * Determine whether deletes made by others are visible.
2844     *
2845     * @param type result set type, i.e. ResultSet.TYPE_XXX
2846     * @return true if deletes are visible for the result set type
2847     */

2848    public boolean othersDeletesAreVisible(int type) {
2849        if (type == JDBC20Translation.TYPE_FORWARD_ONLY)
2850            return true;
2851        return false;
2852    }
2853
2854    /**
2855     * JDBC 2.0
2856     *
2857     * Determine whether inserts made by others are visible.
2858     *
2859     * @param type result set type, i.e. ResultSet.TYPE_XXX
2860     * @return true if inserts are visible for the result set type
2861     */

2862    public boolean othersInsertsAreVisible(int type) {
2863        if (type == JDBC20Translation.TYPE_FORWARD_ONLY)
2864            return true;
2865        return false;
2866    }
2867
2868    /**
2869     * JDBC 2.0
2870     *
2871     * Determine whether or not a visible row update can be detected by
2872     * calling ResultSet.rowUpdated().
2873     *
2874     * @param type result set type, i.e. ResultSet.TYPE_XXX
2875     * @return true if updates are detected by the resultset type
2876     */

2877    public boolean updatesAreDetected(int type) {
2878        if (type == JDBC20Translation.TYPE_SCROLL_INSENSITIVE) {
2879            return true;
2880        } else {
2881            // For forward only resultsets, we move to before the next
2882
// row after a update and that is why updatesAreDetected
2883
// returns false.
2884
return false;
2885        }
2886    }
2887
2888    /**
2889     * JDBC 2.0
2890     *
2891     * Determine whether or not a visible row delete can be detected by
2892     * calling ResultSet.rowDeleted(). If deletesAreDetected()
2893     * returns false, then deleted rows are removed from the result set.
2894     *
2895     * @param type result set type, i.e. ResultSet.TYPE_XXX
2896     * @return true if deletes are detected by the resultset type
2897     */

2898    public boolean deletesAreDetected(int type) {
2899        if (type == JDBC20Translation.TYPE_SCROLL_INSENSITIVE) {
2900            return true;
2901        } else {
2902            // For forward only resultsets, we move to before the next
2903
// row after a delete and that is why deletesAreDetected
2904
// returns false
2905
return false;
2906        }
2907    }
2908
2909    /**
2910     * JDBC 2.0
2911     *
2912     * Determine whether or not a visible row insert can be detected
2913     * by calling ResultSet.rowInserted().
2914     *
2915     * @param type result set type, i.e. ResultSet.TYPE_XXX
2916     * @return true if inserts are detected by the resultset type
2917     */

2918    public boolean insertsAreDetected(int type) {
2919          return false;
2920    }
2921
2922    /**
2923     * JDBC 2.0
2924     *
2925     * Return true if the driver supports batch updates, else return false.
2926     *
2927     */

2928    public boolean supportsBatchUpdates() {
2929          return true;
2930    }
2931
2932    /**
2933     * JDBC 2.0
2934     *
2935     * Get a description of the user-defined types defined in a particular
2936     * schema. Schema specific UDTs may have type JAVA_OBJECT, STRUCT,
2937     * or DISTINCT.
2938     *
2939     * <P>Only types matching the catalog, schema, type name and type
2940     * criteria are returned. They are ordered by DATA_TYPE, TYPE_SCHEM
2941     * and TYPE_NAME. The type name parameter may be a fully qualified
2942     * name. In this case, the catalog and schemaPattern parameters are
2943     * ignored.
2944     *
2945     * <P>Each type description has the following columns:
2946     * <OL>
2947     * <LI><B>TYPE_CAT</B> String => the type's catalog (may be null)
2948     * <LI><B>TYPE_SCHEM</B> String => type's schema (may be null)
2949     * <LI><B>TYPE_NAME</B> String => type name
2950     * <LI><B>CLASS_NAME</B> String => Java class name
2951     * <LI><B>DATA_TYPE</B> String => type value defined in java.sql.Types.
2952     * One of JAVA_OBJECT, STRUCT, or DISTINCT
2953     * <LI><B>REMARKS</B> String => explanatory comment on the type
2954     * <LI><B>BASE_TYPE</B> short => type code of the source type of
2955     * a DISTINCT type or the type that implements the user-generated
2956     * reference type of the SELF_REFERENCING_COLUMN of a structured
2957     * type as defined in java.sql.Types (<code>null</code> if
2958     * DATA_TYPE is not DISTINCT or not STRUCT with
2959     * REFERENCE_GENERATION = USER_DEFINED)
2960     * </OL>
2961     *
2962     * <P><B>Note:</B> If the driver does not support UDTs then an empty
2963     * result set is returned.
2964     *
2965     * @param catalog a catalog name; "" retrieves those without a
2966     * catalog; null means drop catalog name from the selection criteria
2967     * @param schemaPattern a schema name pattern; "" retrieves those
2968     * without a schema
2969     * @param typeNamePattern a type name pattern; may be a fully qualified
2970     * name
2971     * @param types a list of user-named types to include (JAVA_OBJECT,
2972     * STRUCT, or DISTINCT); null returns all types
2973     * @return ResultSet - each row is a type description
2974     * @exception SQLException if a database-access error occurs.
2975     */

2976    public ResultSet JavaDoc getUDTs(String JavaDoc catalog, String JavaDoc schemaPattern,
2977              String JavaDoc typeNamePattern, int[] types)
2978      throws SQLException JavaDoc {
2979      //we don't have support for catalog names
2980
//we don't have java class types per schema, instead it's per database and hence
2981
//we ignore schemapattern.
2982
//the only type of user-named types we support are JAVA_OBJECT
2983
synchronized (getConnectionSynchronization()) {
2984      setupContextStack();
2985      ResultSet JavaDoc rs = null;
2986      int getClassTypes = 0;
2987      try {
2988        String JavaDoc queryText = getQueryDescriptions(false).getProperty("getUDTs");
2989
2990        if (types != null && types.length >= 1) {
2991          for (int i=0; i<types.length; i++){
2992            if (types[i] == java.sql.Types.JAVA_OBJECT)
2993              getClassTypes = 1;
2994          }
2995        } else
2996          getClassTypes = 1;
2997
2998        PreparedStatement JavaDoc s =
2999          getEmbedConnection().prepareMetaDataStatement(queryText);
3000
3001        s.setInt(1, java.sql.Types.JAVA_OBJECT);
3002        s.setString(2, catalog);
3003        s.setString(3, schemaPattern);
3004        s.setString(4, swapNull(typeNamePattern));
3005        s.setInt(5, getClassTypes);
3006
3007        rs = s.executeQuery();
3008      } finally {
3009        restoreContextStack();
3010      }
3011      return rs;
3012    }
3013    }
3014
3015    /**
3016     * JDBC 2.0
3017     *
3018     * Return the connection that produced this metadata object.
3019     *
3020     */

3021    public Connection JavaDoc getConnection() {
3022          return getEmbedConnection().getApplicationConnection();
3023    }
3024
3025    /**
3026    Following methods are for the new JDBC 3.0 methods in java.sql.DatabaseMetaData
3027    (see the JDBC 3.0 spec). We have the JDBC 3.0 methods in Local20
3028    package, so we don't have to have a new class in Local30.
3029    The new JDBC 3.0 methods don't make use of any new JDBC3.0 classes and
3030    so this will work fine in jdbc2.0 configuration.
3031    */

3032
3033    /////////////////////////////////////////////////////////////////////////
3034
//
3035
// JDBC 3.0 - New public methods
3036
//
3037
/////////////////////////////////////////////////////////////////////////
3038

3039    /**
3040    * JDBC 3.0
3041    *
3042    * Retrieves whether this database supports statement pooling.
3043    *
3044    * @return true if statement pooling is supported; false otherwise
3045    */

3046    public boolean supportsStatementPooling()
3047    {
3048        return false;
3049    }
3050
3051    /**
3052    * JDBC 3.0
3053    *
3054    * Retrieves whether this database supports savepoints.
3055    *
3056    * @return true if savepoints are supported; false otherwise
3057    */

3058    public boolean supportsSavepoints()
3059    {
3060        return true;
3061    }
3062
3063    /**
3064    * JDBC 3.0
3065    *
3066    * Retrieves whether this database supports named parameters to callable statements.
3067    *
3068    * @return true if named parameters are supported; false otherwise
3069    */

3070    public boolean supportsNamedParameters()
3071    {
3072        return false;
3073    }
3074
3075    /**
3076    * JDBC 3.0
3077    *
3078    * Retrieves whether it is possible to have multiple ResultSet objects returned from a
3079    * CallableStatement object simultaneously.
3080    *
3081    * @return true if a CallableStatement object can return multiple ResultSet objects
3082    * simultaneously; false otherwise
3083    */

3084    public boolean supportsMultipleOpenResults()
3085    {
3086        return true;
3087    }
3088
3089    /**
3090    * JDBC 3.0
3091    *
3092    * Retrieves whether auto-generated keys can be retrieved after a statement
3093    * has been executed.
3094    *
3095    * @return true if auto-generated keys can be retrieved after a statement has
3096    * executed; false otherwise
3097    */

3098    public boolean supportsGetGeneratedKeys()
3099    {
3100               /*
3101                * Currently reverting the returned value to false until there
3102                * is more support for autogenerated keys in Derby.
3103                * (such as support for specifying the returned columns for
3104                * the autogenerated key)
3105                */

3106        return false;
3107    }
3108
3109    /**
3110    * JDBC 3.0
3111    *
3112    * Retrieves whether this database supports the given result set holdability.
3113    *
3114    * @param holdability - one of the following constants:
3115    * ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT
3116    * @return true if so; false otherwise
3117    * executed; false otherwise
3118    */

3119    public boolean supportsResultSetHoldability(int holdability)
3120    {
3121        return true;
3122    }
3123
3124    /**
3125    * JDBC 3.0
3126    *
3127    * Retrieves the default holdability of this ResultSet object.
3128    *
3129    * @return the default holdability which is ResultSet.HOLD_CURSORS_OVER_COMMIT
3130    */

3131    public int getResultSetHoldability()
3132  {
3133        return JDBC30Translation.HOLD_CURSORS_OVER_COMMIT;
3134    }
3135
3136    /**
3137    * JDBC 3.0
3138    *
3139    * Retrieves the major version number of the underlying database.
3140    *
3141    * @return the underlying database's major version
3142    */

3143    public int getDatabaseMajorVersion()
3144    {
3145        ProductVersionHolder pvh = Monitor.getMonitor().getEngineVersion();
3146        if (pvh == null)
3147        {
3148          return -1;
3149        }
3150        return pvh.getMajorVersion();
3151    }
3152
3153    /**
3154    * JDBC 3.0
3155    *
3156    * Retrieves the minor version number of the underlying database.
3157    *
3158    * @return the underlying database's minor version
3159    */

3160    public int getDatabaseMinorVersion()
3161    {
3162        ProductVersionHolder pvh = Monitor.getMonitor().getEngineVersion();
3163        if (pvh == null)
3164        {
3165          return -1;
3166        }
3167        return pvh.getMinorVersion();
3168    }
3169
3170    /**
3171    * JDBC 3.0
3172    *
3173    * Retrieves the major JDBC version number for this driver.
3174    *
3175    * @return JDBC version major number
3176    */

3177    public int getJDBCMajorVersion()
3178    {
3179        return 3;
3180    }
3181
3182    /**
3183    * JDBC 3.0
3184    *
3185    * Retrieves the minor JDBC version number for this driver.
3186    *
3187    * @return JDBC version minor number
3188    */

3189    public int getJDBCMinorVersion()
3190    {
3191        return 0;
3192    }
3193
3194    /**
3195    * JDBC 3.0
3196    *
3197    * Indicates whether the SQLSTATEs returned by SQLException.getSQLState
3198    * is X/Open (now known as Open Group) SQL CLI or SQL99.
3199    *
3200    * @return the type of SQLSTATEs, one of: sqlStateXOpen or sqlStateSQL99
3201    */

3202    public int getSQLStateType()
3203    {
3204        return JDBC30Translation.SQL_STATE_SQL99;
3205    }
3206
3207    /**
3208    * JDBC 3.0
3209    *
3210    * Indicates whether updates made to a LOB are made on a copy or
3211    * directly to the LOB.
3212    *
3213    * @return true if updates are made to a copy of the LOB; false if
3214    * updates are made directly to the LOB
3215    * @exception SQLException Feature not implemented for now.
3216    */

3217    public boolean locatorsUpdateCopy()
3218    throws SQLException JavaDoc
3219    {
3220        return false;
3221    }
3222
3223    /**
3224    * JDBC 3.0
3225    *
3226    * Retrieves a description of the user-defined type (UDT) hierarchies defined
3227    * in a particular schema in this database. Only the immediate super type/ sub type
3228    * relationship is modeled.
3229    *
3230    * @param catalog - a catalog name; "" retrieves those without a catalog;
3231    * null means drop catalog name from the selection criteria
3232    * @param schemaPattern - a schema name pattern; "" retrieves those without a schema
3233    * @param typeNamePattern - a UDT name pattern; may be a fully-qualified name
3234    * @return a ResultSet object in which a row gives information about the designated UDT
3235    * @exception SQLException Feature not implemented for now.
3236    */

3237    public ResultSet JavaDoc getSuperTypes(String JavaDoc catalog, String JavaDoc schemaPattern, String JavaDoc typeNamePattern)
3238    throws SQLException JavaDoc
3239    {
3240        return getSimpleQuery("getSuperTypes");
3241    }
3242
3243    /**
3244    * JDBC 3.0
3245    *
3246    * Retrieves a description of the table hierarchies defined in a particular
3247    * schema in this database.
3248    *
3249    * @param catalog - a catalog name; "" retrieves those without a catalog;
3250    * null means drop catalog name from the selection criteria
3251    * @param schemaPattern - a schema name pattern; "" retrieves those without a schema
3252    * @param typeNamePattern - a UDT name pattern; may be a fully-qualified name
3253    * @return a ResultSet object in which each row is a type description
3254    * @exception SQLException if a database access error occurs
3255    */

3256    public ResultSet JavaDoc getSuperTables(String JavaDoc catalog, String JavaDoc schemaPattern, String JavaDoc typeNamePattern)
3257    throws SQLException JavaDoc
3258    {
3259        return getSimpleQuery("getSuperTables");
3260    }
3261
3262    /**
3263    * JDBC 3.0
3264    *
3265    * Retrieves a description of the given attribute of the given type for a
3266    * user-defined type (UDT) that is available in the given schema and catalog.
3267    *
3268    * @param catalog - a catalog name; must match the catalog name as it is
3269    * stored in the database; "" retrieves those without a catalog; null means that
3270    * the catalog name should not be used to narrow the search
3271    * @param schemaPattern - a schema name pattern; "" retrieves those without a schema;
3272    * null means that the schema name should not be used to narrow the search
3273    * @param typeNamePattern - a type name pattern; must match the type name as it is
3274    * stored in the database
3275    * @param attributeNamePattern - an attribute name pattern; must match the attribute
3276    * name as it is declared in the database
3277    * @return a ResultSet object in which each row is a type description
3278    * @exception SQLException if a database access error occurs.
3279    */

3280    public ResultSet JavaDoc getAttributes(String JavaDoc catalog, String JavaDoc schemaPattern,
3281  String JavaDoc typeNamePattern, String JavaDoc attributeNamePattern)
3282    throws SQLException JavaDoc
3283    {
3284        return getSimpleQuery("getAttributes");
3285    }
3286    
3287    /////////////////////////////////////////////////////////////////////////
3288
//
3289
// JDBC 4.0 - New public methods
3290
//
3291
/////////////////////////////////////////////////////////////////////////
3292

3293    /**
3294     * JDBC 4.0
3295     *
3296     * <p>Returns a list of the client info properties supported by
3297     * the driver. The result set contains the following columns:
3298     *
3299     * <p>
3300     * <ol>
3301     * <li>NAME String=&gt; The name of the client info property.</li>
3302     * <li>MAX_LEN int=&gt; The maximum length of the value for the
3303     * property.</li>
3304     * <li>DEFAULT_VALUE String=&gt; The default value of the property.</li>
3305     * <li>DESCRIPTION String=&gt; A description of the property.</li>
3306     * </ol>
3307     *
3308     * <p>The <code>ResultSet</code> is sorted by the NAME column.
3309     *
3310     * @return A <code>ResultSet</code> object; each row is a
3311     * supported client info property
3312     * @exception SQLException if an error occurs
3313     */

3314    public ResultSet JavaDoc getClientInfoProperties() throws SQLException JavaDoc {
3315        return getSimpleQuery("getClientInfoProperties");
3316    }
3317
3318    /**
3319     * JDBC 4.0
3320     *
3321     * <p>Get the schema names available in this database. The results
3322     * are ordered by schema name.
3323     *
3324     * <p>The schema columns are:
3325     * <ol>
3326     * <li><strong>TABLE_SCHEM</strong> String =&gt; schema name</li>
3327     * <li><strong>TABLE_CATALOG</strong> String =&gt; catalog name
3328     * (may be <code>null</code>)</li>
3329     * </ol>
3330     *
3331     * @param catalog catalog name used to narrow down the search; ""
3332     * means no catalog, <code>null</code> means any catalog
3333     * @param schemaPattern schema name used to narrow down the
3334     * search, <code>null</code> means schema name should not be used
3335     * to narrow down search
3336     * @return a <code>ResultSet</code> object in which each row is a
3337     * schema description
3338     * @exception SQLException if a database error occurs
3339     */

3340    public ResultSet JavaDoc getSchemas(String JavaDoc catalog, String JavaDoc schemaPattern)
3341        throws SQLException JavaDoc
3342    {
3343        PreparedStatement JavaDoc s = getPreparedQuery("getSchemas");
3344        s.setString(1, swapNull(catalog));
3345        s.setString(2, swapNull(schemaPattern));
3346        return s.executeQuery();
3347    }
3348
3349    //////////////////////////////////////////////////////////////
3350
//
3351
// MISC
3352
//
3353
//////////////////////////////////////////////////////////////
3354

3355    /**
3356     * Get metadata that the client driver will cache. The metadata is
3357     * fetched using SYSIBM.METADATA (found in metadata_net.properties).
3358     *
3359     * @return the result set returned by SYSIBM.METADATA
3360     * @exception SQLException if a database error occurs
3361     */

3362    public ResultSet JavaDoc getClientCachedMetaData() throws SQLException JavaDoc {
3363        return getSimpleQuery("METADATA", true);
3364    }
3365
3366    /*
3367     * utility helper routines:
3368     */

3369
3370    /**
3371     * Execute a query in metadata.properties (or SPS in the SYS
3372     * schema) or metadata_net.properties (or SPS in the SYSIBM
3373     * schema).
3374     *
3375     * @param nameKey the name of the query
3376     * @param net if <code>true</code>, execute a query in
3377     * metadata_net.properties; otherwise, execute a query in
3378     * metadata.properties
3379     * @return a <code>ResultSet</code> value
3380     * @exception SQLException if a database error occurs
3381     */

3382    private ResultSet JavaDoc getSimpleQuery(String JavaDoc nameKey, boolean net)
3383        throws SQLException JavaDoc
3384    {
3385        PreparedStatement JavaDoc ps = getPreparedQuery(nameKey, net);
3386        if (ps == null)
3387            return null;
3388    
3389        return ps.executeQuery();
3390    }
3391
3392    /**
3393     * Execute a query in metadata.properties, or an SPS in the SYS
3394     * schema.
3395     *
3396     * @param nameKey the name of the query
3397     * @return a <code>ResultSet</code> value
3398     * @exception SQLException if a database error occurs
3399     */

3400    protected ResultSet JavaDoc getSimpleQuery(String JavaDoc nameKey) throws SQLException JavaDoc {
3401        return getSimpleQuery(nameKey, false);
3402    }
3403
3404    /**
3405     * Get a stored prepared statement from the system tables.
3406     *
3407     * @param nameKey the name of the query
3408     * @param net if <code>true</code>, find query in SYSIBM schema;
3409     * otherwise, find query in SYS schema
3410     * @return a <code>PreparedStatement</code> value
3411     * @exception SQLException if a database error occurs
3412     */

3413    private PreparedStatement JavaDoc getPreparedQueryUsingSystemTables(String JavaDoc nameKey,
3414                                                                boolean net)
3415        throws SQLException JavaDoc
3416    {
3417        synchronized (getConnectionSynchronization())
3418        {
3419            setupContextStack();
3420            PreparedStatement JavaDoc ps = null;
3421
3422            try
3423            {
3424                String JavaDoc queryText =
3425                    getQueryDescriptions(net).getProperty(nameKey);
3426                if (queryText == null)
3427                {
3428                    throw Util.notImplemented(nameKey);
3429                }
3430                
3431                ps = prepareSPS(nameKey, queryText, net);
3432            }
3433
3434            catch (Throwable JavaDoc t)
3435            {
3436                throw handleException(t);
3437            }
3438
3439            finally
3440            {
3441                restoreContextStack();
3442            }
3443            return ps;
3444        }
3445    }
3446
3447    /**
3448     * Either get the prepared query for the metadata call from the
3449     * system tables, or from the metadata.properties or
3450     * metadata_net.properties file.
3451     * In soft upgrade mode, the queries stored in the system tables
3452     * might not be upto date with the Derby engine release because
3453     * system tables can't be modified in backward incompatible way in
3454     * soft upgrade mode. Because of this, if the database is in
3455     * soft upgrade mode, get the queries from metadata.properties
3456     * file rather than from the system tables.
3457     *
3458     * Getting queries from metadata(_net).properties might cause problems
3459     * if system catalogs have been changed between versions either by
3460     * addition of columns or have new catalogs. To continue
3461     * to support soft upgrade from older versions of database, find
3462     * query that most closely matches database dictionary version.
3463     *
3464     * @param queryName Name of the metadata query for which we need
3465     * a prepared statement
3466     * @param net if <code>true</code>, use metadata_net.properties
3467     * instead of metadata.properties
3468     * @return PreparedStatement
3469     * @exception SQLException if a database error occurs
3470     */

3471    private PreparedStatement JavaDoc getPreparedQuery(String JavaDoc queryName,
3472                                               boolean net)
3473            throws SQLException JavaDoc {
3474        PreparedStatement JavaDoc s;
3475        //We can safely goto system table since we are not in soft upgrade
3476
//mode and hence metadata sql in system tables are uptodate
3477
//with this Derby release.
3478
if (notInSoftUpgradeMode())
3479            s = getPreparedQueryUsingSystemTables(queryName, net);
3480        else {
3481            try {
3482                //Can't use stored prepared statements because we are in soft upgrade
3483
//mode and hence need to get metadata sql from metadata.properties file
3484
//or metadata_net.properties
3485
String JavaDoc queryText = getQueryFromDescription(queryName, net);
3486                s = getEmbedConnection().prepareMetaDataStatement(queryText);
3487            } catch (Throwable JavaDoc t) {
3488                throw handleException(t);
3489            }
3490        }
3491        return s;
3492    }
3493
3494    /**
3495     * Get a prepared query from system tables or metadata.properties.
3496     *
3497     * @param queryName name of the query
3498     * @return a <code>PreparedStatement</code> value
3499     * @exception SQLException if a database error occurs
3500     */

3501    protected PreparedStatement JavaDoc getPreparedQuery(String JavaDoc queryName)
3502        throws SQLException JavaDoc
3503    {
3504        return getPreparedQuery(queryName, false);
3505    }
3506
3507    /**
3508     * Given a queryName, find closest match in queryDescriptions. This method
3509     * should be called in soft-upgrade mode only, where current software version
3510     * doesn't match dictionary version. For these cases, there may be
3511     * multiple entries in queryDescriptions for given queryName. Find a
3512     * version of the query that closely matches dictionary version.
3513     *
3514     * This method is currently coded to handle two specific queries,
3515     * getColumnPrivileges and getTablePrivileges. Derby databases that are 10.1
3516     * or earlier will not have new system tables added for 10.2 for privileges.
3517     *
3518     * It should be possible to automate finding closest match by generating
3519     * all Major_Minor versions between software version and dictionary version
3520     * and try each one from Dictionary version to current version. Since only
3521     * needed for two queries, overhead may not be worth it yet.
3522     *
3523     * @param queryName name of the query
3524     * @param net if <code>true</code>, get the query from
3525     * metadata_net.properties instead of metadata.properties
3526     * @return the query text
3527     * @exception StandardException if an error occurs
3528     */

3529    private String JavaDoc getQueryFromDescription(String JavaDoc queryName, boolean net)
3530        throws StandardException
3531    {
3532        DataDictionary dd = getLanguageConnectionContext().getDataDictionary();
3533
3534        // If dictionary version is below 10.2, special case
3535
// getColumnPrivileges and getTablePrivileges since new system tables
3536
// for privileges wouldn't be present.
3537
if (!dd.checkVersion(DataDictionary.DD_VERSION_DERBY_10_2, null))
3538        {
3539            if (queryName.equals("getColumnPrivileges"))
3540                queryName = "getColumnPrivileges_10_1";
3541
3542            if (queryName.equals("getTablePrivileges"))
3543                queryName = "getTablePrivileges_10_1";
3544        }
3545
3546        return getQueryDescriptions(net).getProperty(queryName);
3547    }
3548
3549    /*
3550    ** Given a SPS name and a query text it returns a
3551    ** java.sql.PreparedStatement for the SPS. If the SPS
3552    ** doeesn't exist is created.
3553    **
3554    */

3555    private PreparedStatement JavaDoc prepareSPS(String JavaDoc spsName,
3556                                         String JavaDoc spsText,
3557                                         boolean net)
3558        throws StandardException, SQLException JavaDoc
3559    {
3560
3561        LanguageConnectionContext lcc = getLanguageConnectionContext();
3562
3563        /* We now need to do this in sub transaction because we could possibly recompile SPS
3564         * later, and the recompile is in a sub transaction, and will update the SYSSTATEMENTS
3565         * entry. Don't want to block.
3566         */

3567        lcc.beginNestedTransaction(true);
3568
3569        DataDictionary dd = getLanguageConnectionContext().getDataDictionary();
3570        SPSDescriptor spsd = dd.getSPSDescriptor(
3571                                        spsName,
3572                                        net ? dd.getSysIBMSchemaDescriptor() :
3573                                        dd.getSystemSchemaDescriptor());
3574        lcc.commitNestedTransaction();
3575
3576        if (spsd == null)
3577        {
3578            throw Util.notImplemented(spsName);
3579        }
3580
3581        /* manish:
3582           There should be a nicer way of getting a
3583           java.sql.PreparedStatement from an SPS descriptor!
3584        */

3585        /*
3586        ** It is unnecessarily expensive to get the
3587        ** the statement, and then send an EXECUTE
3588        ** statement, but we have no (easy) way of turning
3589        ** the statement into a java.sql.PreparedStatement.
3590        */

3591        String JavaDoc queryText =
3592            "EXECUTE STATEMENT " + (net ? "SYSIBM" : "SYS") +
3593            ".\"" + spsName + "\"";
3594        return getEmbedConnection().prepareMetaDataStatement(queryText);
3595
3596    }
3597
3598    static final protected String JavaDoc swapNull(String JavaDoc s) {
3599        return (s == null ? "%" : s);
3600    }
3601
3602    /**
3603      * Gets the constant action factory
3604      *
3605      * @return the constant action factory.
3606      *
3607      * @exception StandardException Thrown on failur4e
3608      */

3609    private GenericConstantActionFactory getGenericConstantActionFactory()
3610        throws StandardException
3611    {
3612        if ( constantActionFactory == null )
3613        {
3614            GenericExecutionFactory execFactory = (GenericExecutionFactory)
3615                getLanguageConnectionContext().getLanguageConnectionFactory().getExecutionFactory();
3616            constantActionFactory = execFactory.getConstantActionFactory();
3617        }
3618
3619        return constantActionFactory;
3620    }
3621
3622    /**
3623      * Gets the LanguageConnectionContext for this connection.
3624      *
3625      * @return the lcc for this connection
3626      *
3627      */

3628    private LanguageConnectionContext getLanguageConnectionContext()
3629    {
3630        return getEmbedConnection().getLanguageConnection();
3631    }
3632
3633    /*
3634    ** Priv block code, moved out of the old Java2 version.
3635    */

3636
3637    /**
3638     * Loads the query descriptions from metadata.properties and
3639     * metadata_net.properties into <code>queryDescriptions</code> and
3640     * <code>queryDescriptions_net</code>.
3641     */

3642    private void loadQueryDescriptions() {
3643        java.security.AccessController.doPrivileged(this);
3644    }
3645
3646    /**
3647     * Performs a privileged action. Reads the query descriptions.
3648     *
3649     * @return <code>null</code>
3650     */

3651    public final Object JavaDoc run() {
3652        // SECURITY PERMISSION - IP3
3653
PBloadQueryDescriptions();
3654        return null;
3655    }
3656
3657}
3658
Popular Tags