Source code: org/apache/derby/impl/jdbc/EmbedDatabaseMetaData.java
1 /*
2
3 Derby - Class org.apache.derby.impl.jdbc.EmbedDatabaseMetaData
4
5 Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable.
6
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
10
11 http://www.apache.org/licenses/LICENSE-2.0
12
13 Unless required by applicable law or agreed to in writing, software
14 distributed under the License is distributed on an "AS IS" BASIS,
15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18
19 */
20
21 package org.apache.derby.impl.jdbc;
22
23 import org.apache.derby.iapi.services.info.ProductVersionHolder;
24
25 import org.apache.derby.iapi.services.monitor.Monitor;
26
27 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
28
29 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
30 import org.apache.derby.iapi.sql.dictionary.SPSDescriptor;
31
32 import org.apache.derby.iapi.error.StandardException;
33
34 import org.apache.derby.impl.sql.execute.GenericConstantActionFactory;
35 import org.apache.derby.impl.sql.execute.GenericExecutionFactory;
36
37 import org.apache.derby.iapi.reference.Limits;
38 import org.apache.derby.iapi.reference.JDBC20Translation;
39 import org.apache.derby.iapi.reference.JDBC30Translation;
40
41 import java.util.Properties;
42
43 import java.sql.DatabaseMetaData;
44 import java.sql.Connection;
45 import java.sql.PreparedStatement;
46 import java.sql.SQLException;
47 import java.sql.ResultSet;
48 import java.sql.Types;
49
50 import java.io.IOException;
51 import java.io.InputStream;
52
53 /**
54 * This class provides information about the database as a whole.
55 *
56 * <P>Many of the methods here return lists of information in ResultSets.
57 * You can use the normal ResultSet methods such as getString and getInt
58 * to retrieve the data from these ResultSets. If a given form of
59 * metadata is not available, these methods should throw a SQLException.
60 *
61 * <P>Some of these methods take arguments that are String patterns. These
62 * arguments all have names such as fooPattern. Within a pattern String, "%"
63 * means match any substring of 0 or more characters, and "_" means match
64 * any one character. Only metadata entries matching the search pattern
65 * are returned. If a search pattern argument is set to a null ref, it means
66 * that argument's criteria should be dropped from the search.
67 *
68 * <P>A SQLException will be thrown if a driver does not support a meta
69 * data method. In the case of methods that return a ResultSet,
70 * either a ResultSet (which may be empty) is returned or a
71 * SQLException is thrown.
72 * <p>
73 * This implementation gets instructions from the Database for how to satisfy
74 * most requests for information. Each instruction is either a simple string
75 * containing the desired information, or the text of a query that may be
76 * executed on the database connection to gather the information. We get the
77 * instructions via an "InstructionReader," which requires the database
78 * Connection for initialization.
79 * <p>
80 * Those few pieces of metadata that are related to the driver, rather than the
81 * database, come from a separate InstructionReader. Note that in that case it
82 * probably doesn't make sense to allow an instruction to specify a query.
83 *
84 * @author ames
85 */
86 public class EmbedDatabaseMetaData extends ConnectionChild
87 implements DatabaseMetaData, java.security.PrivilegedAction {
88
89 /*
90 ** Property and values related to using
91 ** stored prepared statements for metatdata.
92 */
93
94 private final String url;
95
96 /*
97 ** Set to true if metadata is off
98 */
99
100 private GenericConstantActionFactory constantActionFactory;
101
102 //////////////////////////////////////////////////////////////
103 //
104 // CONSTRUCTORS
105 //
106 //////////////////////////////////////////////////////////////
107 /**
108 @exception SQLException on error
109 */
110 public EmbedDatabaseMetaData (EmbedConnection connection, String url)
111 throws SQLException {
112
113 super(connection);
114 this.url = url;
115
116 }
117
118 private static Properties queryDescriptions;
119 protected final Properties getQueryDescriptions() {
120 Properties p = EmbedDatabaseMetaData.queryDescriptions;
121 if (p != null)
122 return p;
123
124 return (EmbedDatabaseMetaData.queryDescriptions = loadQueryDescriptions());
125 }
126
127 private Properties PBloadQueryDescriptions() {
128 Properties p = new Properties();
129 try {
130
131 // SECURITY PERMISSION - IP3
132 InputStream is = getClass().getResourceAsStream("metadata.properties");
133
134 p.load(is);
135 is.close();
136 } catch (IOException ioe) {
137 }
138 return p;
139 }
140
141 //////////////////////////////////////////////////////////////
142 //
143 // DatabaseMetaData interface
144 //
145 //////////////////////////////////////////////////////////////
146
147 //----------------------------------------------------------------------
148 // First, a variety of minor information about the target database.
149
150 /**
151 * Can all the procedures returned by getProcedures be called by the
152 * current user?
153 *
154 * @return true if so
155 */
156 public boolean allProceduresAreCallable() {
157 return true;
158 }
159
160 /**
161 * Can all the tables returned by getTable be SELECTed by the
162 * current user?
163 *
164 * @return true if so
165 */
166 public boolean allTablesAreSelectable() {
167 return true;
168 }
169
170 /**
171 * What's the url for this database?
172 *
173 * @return the url or null if it can't be generated
174 */
175 public final String getURL() {
176
177 if (url == null)
178 return url;
179 int attributeStart = url.indexOf(';');
180 if (attributeStart == -1)
181 return url;
182 else
183 return url.substring(0,attributeStart);
184 }
185
186 /**
187 * What's our user name as known to the database?
188 *
189 * @return our database user name
190 */
191 public String getUserName() {
192 return (getEmbedConnection().getTR().getUserName());
193 }
194
195 /**
196 * Is the database in read-only mode?
197 *
198 * @return true if so
199 */
200 public boolean isReadOnly() {
201 return getLanguageConnectionContext().getDatabase().isReadOnly();
202 }
203
204 /**
205 * Are NULL values sorted high?
206 *
207 * @return true if so
208 */
209 public boolean nullsAreSortedHigh() {
210 return true;
211 }
212
213 /**
214 * Are NULL values sorted low?
215 *
216 * @return true if so
217 */
218 public boolean nullsAreSortedLow() {
219 return false;
220 }
221
222 /**
223 * Are NULL values sorted at the start regardless of sort order?
224 *
225 * @return true if so
226 */
227 public boolean nullsAreSortedAtStart() {
228 return false;
229 }
230
231 /**
232 * Are NULL values sorted at the end regardless of sort order?
233 *
234 * @return true if so
235 */
236 public boolean nullsAreSortedAtEnd() {
237 return false;
238 }
239
240 /**
241 * What's the name of this database product?
242 *
243 * @return database product name
244 */
245 public String getDatabaseProductName() {
246 return Monitor.getMonitor().getEngineVersion().getProductName();
247 }
248
249 /**
250 * What's the version of this database product?
251 *
252 * @return database version
253 */
254 public String getDatabaseProductVersion() {
255 ProductVersionHolder myPVH = Monitor.getMonitor().getEngineVersion();
256
257 return myPVH.getVersionBuildString(false);
258 }
259
260 /**
261 * What's the name of this JDBC driver?
262 *
263 * @return JDBC driver name
264 */
265 public String getDriverName() {
266 return "Apache Derby Embedded JDBC Driver";
267 }
268
269 /**
270 * What's the version of this JDBC driver?
271 *
272 * @return JDBC driver version
273 */
274 public String getDriverVersion() {
275 return getDatabaseProductVersion();
276 }
277
278 /**
279 * What's this JDBC driver's major version number?
280 *
281 * @return JDBC driver major version
282 */
283 public int getDriverMajorVersion() {
284 return getEmbedConnection().getLocalDriver().getMajorVersion();
285 }
286
287 /**
288 * What's this JDBC driver's minor version number?
289 *
290 * @return JDBC driver minor version number
291 */
292 public int getDriverMinorVersion() {
293 return getEmbedConnection().getLocalDriver().getMinorVersion();
294 }
295
296 /**
297 * Does the database store tables in a local file?
298 *
299 * @return true if so
300 */
301 public boolean usesLocalFiles() {
302 return true;
303 }
304
305 /**
306 * Does the database use a file for each table?
307 *
308 * @return true if the database uses a local file for each table
309 */
310 public boolean usesLocalFilePerTable() {
311 return true;
312 }
313
314 /**
315 * Does the database treat mixed case unquoted SQL identifiers as
316 * case sensitive and as a result store them in mixed case?
317 *
318 * A JDBC-Compliant driver will always return false.
319 *
320 * @return true if so
321 */
322 public boolean supportsMixedCaseIdentifiers() {
323 return false;
324 }
325
326 /**
327 * Does the database treat mixed case unquoted SQL identifiers as
328 * case insensitive and store them in upper case?
329 *
330 * @return true if so
331 */
332 public boolean storesUpperCaseIdentifiers() {
333 return true;
334 }
335
336 /**
337 * Does the database treat mixed case unquoted SQL identifiers as
338 * case insensitive and store them in lower case?
339 *
340 * @return true if so
341 */
342 public boolean storesLowerCaseIdentifiers() {
343 return false;
344 }
345
346 /**
347 * Does the database treat mixed case unquoted SQL identifiers as
348 * case insensitive and store them in mixed case?
349 *
350 * @return true if so
351 */
352 public boolean storesMixedCaseIdentifiers() {
353 return false;
354 }
355
356 /**
357 * Does the database treat mixed case quoted SQL identifiers as
358 * case sensitive and as a result store them in mixed case?
359 *
360 * A JDBC-Compliant driver will always return true.
361 *
362 * @return true if so
363 */
364 public boolean supportsMixedCaseQuotedIdentifiers() {
365 return true;
366 }
367
368 /**
369 * Does the database treat mixed case quoted SQL identifiers as
370 * case insensitive and store them in upper case?
371 *
372 * @return true if so
373 */
374 public boolean storesUpperCaseQuotedIdentifiers() {
375 return false;
376 }
377
378 /**
379 * Does the database treat mixed case quoted SQL identifiers as
380 * case insensitive and store them in lower case?
381 *
382 * @return true if so
383 */
384 public boolean storesLowerCaseQuotedIdentifiers() {
385 return false;
386 }
387
388 /**
389 * Does the database treat mixed case quoted SQL identifiers as
390 * case insensitive and store them in mixed case?
391 *
392 * @return true if so
393 */
394 public boolean storesMixedCaseQuotedIdentifiers() {
395 return true;
396 }
397
398 /**
399 * What's the string used to quote SQL identifiers?
400 * This returns a space " " if identifier quoting isn't supported.
401 *
402 * A JDBC-Compliant driver always uses a double quote character.
403 *
404 * @return the quoting string
405 */
406 public String getIdentifierQuoteString() {
407 return "\"";
408 }
409
410 /**
411 * Get a comma separated list of all a database's SQL keywords
412 * that are NOT also SQL92 keywords.
413 includes reserved and non-reserved keywords.
414
415 * @return the list
416 */
417 public String getSQLKeywords() {
418 return "ALIAS,BIGINT,BOOLEAN,CALL,CLASS,COPY,DB2J_DEBUG,EXECUTE,EXPLAIN,FILE,FILTER,"
419 + "GETCURRENTCONNECTION,INDEX,INSTANCEOF,METHOD,NEW,OFF,PROPERTIES,PUBLICATION,RECOMPILE,"
420 + "REFRESH,RENAME,RUNTIMESTATISTICS,STATEMENT,STATISTICS,TIMING,WAIT";
421 }
422
423 /**
424 * Get a comma separated list of math functions.
425 getNumericFunctions lists "math functions" -- so built-in operators and
426 things like EXTRACT are not included.
427 FIXME: find a way to reference method aliases known to be "numeric"
428 *
429 * @return the list
430 */
431 public String getNumericFunctions() {
432 return "ABS,SQRT";
433 }
434
435 /**
436 * Get a comma separated list of string functions.
437 REMIND, when they show up, something like this might appear here:
438 FIXME: find a way to reference method aliases known to be "string"
439 * @return the list
440 */
441 public String getStringFunctions() {
442 return "LENGTH,LOWER,LTRIM,RTRIM,SUBSTR,SUBSTRING,UPPER";
443 }
444
445 /**
446 * Get a comma separated list of system functions.
447 FIXME: find a way to reference system functions on Database when/if
448 they are registered as aliases or include the Database object too.
449 * @return the list
450 */
451 public String getSystemFunctions() {
452 return "CURRENT_USER,getCurrentConnection,runTimeStatistics,SESSION_USER,USER,CURRENT SCHEMA";
453 }
454
455 /**
456 * Get a comma separated list of time and date functions.
457 not sure if this includes these built-ins or not, but here they are.
458 FIXME: find a way to reference method aliases known to be "date/time"
459 * @return the list
460 */
461 public String getTimeDateFunctions() {
462 return "CURDATE,CURTIME,CURRENT_DATE,CURRENT_TIME,CURRENT_TIMESTAMP,EXTRACT";
463 }
464
465 /**
466 * This is the string that can be used to escape '_' or '%' in
467 * the string pattern style catalog search parameters.
468 we have no default escape value, so = is the end of the next line
469 * <P>The '_' character represents any single character.
470 * <P>The '%' character represents any sequence of zero or
471 * more characters.
472 * @return the string used to escape wildcard characters
473 */
474 public String getSearchStringEscape() {
475 return "";
476 }
477
478 /**
479 * Get all the "extra" characters that can be used in unquoted
480 * identifier names (those beyond a-z, A-Z, 0-9 and _).
481 *
482 * @return the string containing the extra characters
483 */
484 public String getExtraNameCharacters() {
485 return "";
486 }
487
488 //--------------------------------------------------------------------
489 // Functions describing which features are supported.
490
491 /**
492 * Is "ALTER TABLE" with add column supported?
493 *
494 * @return true if so
495 */
496 public boolean supportsAlterTableWithAddColumn() {
497 return true;
498 }
499
500 /**
501 * Is "ALTER TABLE" with drop column supported?
502 *
503 * @return true if so
504 */
505 public boolean supportsAlterTableWithDropColumn() {
506 return true;
507 }
508
509 /**
510 * Is column aliasing supported?
511 *
512 * <P>If so, the SQL AS clause can be used to provide names for
513 * computed columns or to provide alias names for columns as
514 * required.
515 *
516 * A JDBC-Compliant driver always returns true.
517 *
518 * @return true if so
519 */
520 public boolean supportsColumnAliasing() {
521 return true;
522 }
523
524 /**
525 * Are concatenations between NULL and non-NULL values NULL?
526 *
527 * A JDBC-Compliant driver always returns true.
528 *
529 * @return true if so
530 */
531 public boolean nullPlusNonNullIsNull() {
532 return true;
533 }
534
535 /**
536 * Is the CONVERT function between SQL types supported?
537 *
538 * @return true if so
539 */
540 public boolean supportsConvert() {
541 return true;
542 }
543
544 /**
545 * Is CONVERT between the given SQL types supported?
546 *
547 * @param fromType the type to convert from
548 * @param toType the type to convert to
549 * @return true if so
550 * @see Types
551 */
552 public boolean supportsConvert(int fromType, int toType) {
553 /*
554 * at the moment we don't support CONVERT at all, so we take the easy
555 * way out. Eventually we need to figure out how to handle this
556 * cleanly.
557 */
558 return false;
559 }
560
561 /**
562 * Are table correlation names supported?
563 *
564 * A JDBC-Compliant driver always returns true.
565 *
566 * @return true if so
567 */
568 public boolean supportsTableCorrelationNames() {
569 return true;
570 }
571
572 /**
573 * If table correlation names are supported, are they restricted
574 * to be different from the names of the tables?
575 *
576 * @return true if so
577 */
578 public boolean supportsDifferentTableCorrelationNames() {
579 return true;
580 }
581
582 /**
583 * Are expressions in "ORDER BY" lists supported?
584 *
585 * @return true if so
586 */
587 public boolean supportsExpressionsInOrderBy() {
588 return false;
589 }
590
591 /**
592 * Can an "ORDER BY" clause use columns not in the SELECT?
593 *
594 * @return true if so
595 */
596 public boolean supportsOrderByUnrelated() {
597 return false;
598 }
599
600 /**
601 * Is some form of "GROUP BY" clause supported?
602 *
603 * @return true if so
604 */
605 public boolean supportsGroupBy() {
606 return true;
607 }
608
609 /**
610 * Can a "GROUP BY" clause use columns not in the SELECT?
611 *
612 * @return true if so
613 */
614 public boolean supportsGroupByUnrelated() {
615 return true;
616 }
617
618 /**
619 * Can a "GROUP BY" clause add columns not in the SELECT
620 * provided it specifies all the columns in the SELECT?
621 *
622 * @return true if so
623 */
624 public boolean supportsGroupByBeyondSelect() {
625 return true;
626 }
627
628 /**
629 * Is the escape character in "LIKE" clauses supported?
630 *
631 * A JDBC-Compliant driver always returns true.
632 *
633 * @return true if so
634 */
635 public boolean supportsLikeEscapeClause() {
636 return true;
637 }
638
639 /**
640 * Are multiple ResultSets from a single execute supported?
641 *
642 * @return true if so
643 */
644 public boolean supportsMultipleResultSets() {
645 return true;
646 }
647
648 /**
649 * Can we have multiple transactions open at once (on different
650 * connections)?
651 *
652 * @return true if so
653 */
654 public boolean supportsMultipleTransactions() {
655 return true;
656 }
657
658 /**
659 * Can columns be defined as non-nullable?
660 *
661 * A JDBC-Compliant driver always returns true.
662 *
663 * @return true if so
664 */
665 public boolean supportsNonNullableColumns() {
666 return true;
667 }
668
669 /**
670 * Is the ODBC Minimum SQL grammar supported?
671 *
672 * All JDBC-Compliant drivers must return true.
673 *
674 * @return true if so
675 */
676 public boolean supportsMinimumSQLGrammar() {
677 return true;
678 }
679
680 /**
681 * Is the ODBC Core SQL grammar supported?
682 *
683 * @return true if so
684 */
685 public boolean supportsCoreSQLGrammar() {
686 return false;
687 }
688
689 /**
690 * Is the ODBC Extended SQL grammar supported?
691 *
692 * @return true if so
693 */
694 public boolean supportsExtendedSQLGrammar() {
695 return false;
696 }
697
698 /**
699 * Is the ANSI92 entry level SQL grammar supported?
700 *
701 * All JDBC-Compliant drivers must return true.
702 *
703 * @return true if so
704 */
705 public boolean supportsANSI92EntryLevelSQL() {
706 return false;
707 }
708
709 /**
710 * Is the ANSI92 intermediate SQL grammar supported?
711 *
712 * @return true if so
713 *
714 */
715 public boolean supportsANSI92IntermediateSQL() {
716 return false;
717 }
718
719 /**
720 * Is the ANSI92 full SQL grammar supported?
721 *
722 * @return true if so
723 *
724 */
725 public boolean supportsANSI92FullSQL() {
726 return false;
727 }
728
729 /**
730 * Is the SQL Integrity Enhancement Facility supported?
731 *
732 * @return true if so
733 *
734 */
735 public boolean supportsIntegrityEnhancementFacility() {
736 return false;
737 }
738
739 /**
740 * Is some form of outer join supported?
741 *
742 * @return true if so
743 *
744 */
745 public boolean supportsOuterJoins() {
746 return true;
747 }
748
749 /**
750 * Are full nested outer joins supported?
751 *
752 * @return true if so
753 *
754 */
755 public boolean supportsFullOuterJoins() {
756 return false;
757 }
758
759 /**
760 * Is there limited support for outer joins? (This will be true
761 * if supportFullOuterJoins is true.)
762 *
763 * @return true if so
764 *
765 */
766 public boolean supportsLimitedOuterJoins() {
767 return true;
768 }
769
770 /**
771 * What's the database vendor's preferred term for "schema"?
772 *
773 * @return the vendor term
774 *
775 */
776 public String getSchemaTerm() {
777 return "SCHEMA";
778 }
779
780 /**
781 * What's the database vendor's preferred term for "procedure"?
782 *
783 * @return the vendor term
784 *
785 */
786 public String getProcedureTerm() {
787 return "PROCEDURE";
788 }
789
790 /**
791 * What's the database vendor's preferred term for "catalog"?
792 *
793 * @return the vendor term
794 *
795 */
796 public String getCatalogTerm() {
797 return "CATALOG";
798 }
799
800 /**
801 * Does a catalog appear at the start of a qualified table name?
802 * (Otherwise it appears at the end)
803 *
804 * @return true if it appears at the start
805 *
806 */
807 public boolean isCatalogAtStart() {
808 return false;
809 }
810
811 /**
812 * What's the separator between catalog and table name?
813 *
814 * @return the separator string
815 *
816 */
817 public String getCatalogSeparator() {
818 return "";
819 }
820
821 /**
822 * Can a schema name be used in a data manipulation statement?
823 *
824 * @return true if so
825 *
826 */
827 public boolean supportsSchemasInDataManipulation() {
828 return true;
829 }
830
831 /**
832 * Can a schema name be used in a procedure call statement?
833 *
834 * @return true if so
835 *
836 */
837 public boolean supportsSchemasInProcedureCalls() {
838 return true;
839 }
840
841 /**
842 * Can a schema name be used in a table definition statement?
843 *
844 * @return true if so
845 *
846 */
847 public boolean supportsSchemasInTableDefinitions() {
848 return true;
849 }
850
851 /**
852 * Can a schema name be used in an index definition statement?
853 *
854 * @return true if so
855 */
856 public boolean supportsSchemasInIndexDefinitions() {
857 return true;
858 }
859
860 /**
861 * Can a schema name be used in a privilege definition statement?
862 *
863 * @return true if so
864 *
865 */
866 public boolean supportsSchemasInPrivilegeDefinitions() {
867 return true;
868 }
869
870 /**
871 * Can a catalog name be used in a data manipulation statement?
872 *
873 * @return true if so
874 *
875 */
876 public boolean supportsCatalogsInDataManipulation() {
877 return false;
878 }
879
880 /**
881 * Can a catalog name be used in a procedure call statement?
882 *
883 * @return true if so
884 *
885 */
886 public boolean supportsCatalogsInProcedureCalls() {
887 return false;
888 }
889
890 /**
891 * Can a catalog name be used in a table definition statement?
892 *
893 * @return true if so
894 *
895 */
896 public boolean supportsCatalogsInTableDefinitions() {
897 return false;
898 }
899
900 /**
901 * Can a catalog name be used in an index definition statement?
902 *
903 * @return true if so
904 */
905 public boolean supportsCatalogsInIndexDefinitions() {
906 return false;
907 }
908
909 /**
910 * Can a catalog name be used in a privilege definition statement?
911 *
912 * @return true if so
913 */
914 public boolean supportsCatalogsInPrivilegeDefinitions() {
915 return false;
916 }
917
918
919 /**
920 * Is positioned DELETE supported?
921 *
922 * @return true if so
923 */
924 public boolean supportsPositionedDelete() {
925 return true;
926 }
927
928 /**
929 * Is positioned UPDATE supported?
930 *
931 * @return true if so
932 */
933 public boolean supportsPositionedUpdate() {
934 return true;
935 }
936
937 /**
938 * Is SELECT for UPDATE supported?
939 *
940 * @return true if so
941 */
942 public boolean supportsSelectForUpdate() {
943 return true;
944 }
945
946 /**
947 * Are stored procedure calls using the stored procedure escape
948 * syntax supported?
949 *
950 * @return true if so
951 */
952 public boolean supportsStoredProcedures() {
953 return true;
954 }
955
956 /**
957 * Are subqueries in comparison expressions supported?
958 *
959 * A JDBC-Compliant driver always returns true.
960 *
961 * @return true if so
962 */
963 public boolean supportsSubqueriesInComparisons() {
964 return true;
965 }
966
967 /**
968 * Are subqueries in 'exists' expressions supported?
969 *
970 * A JDBC-Compliant driver always returns true.
971 *
972 * @return true if so
973 */
974 public boolean supportsSubqueriesInExists() {
975 return true;
976 }
977
978 /**
979 * Are subqueries in 'in' statements supported?
980 *
981 * A JDBC-Compliant driver always returns true.
982 *
983 * @return true if so
984 */
985 public boolean supportsSubqueriesInIns() {
986 return true;
987 }
988
989 /**
990 * Are subqueries in quantified expressions supported?
991 *
992 * A JDBC-Compliant driver always returns true.
993 *
994 * @return true if so
995 */
996 public boolean supportsSubqueriesInQuantifieds() {
997 return true;
998 }
999
1000 /**
1001 * Are correlated subqueries supported?
1002 *
1003 * A JDBC-Compliant driver always returns true.
1004 *
1005 * @return true if so
1006 */
1007 public boolean supportsCorrelatedSubqueries() {
1008 return true;
1009 }
1010
1011 /**
1012 * Is SQL UNION supported?
1013 *
1014 * @return true if so
1015 */
1016 public boolean supportsUnion() {
1017 return true;
1018 }
1019
1020 /**
1021 * Is SQL UNION ALL supported?
1022 *
1023 * @return true if so
1024 */
1025 public boolean supportsUnionAll() {
1026 return true;
1027 }
1028
1029 /**
1030 * Can cursors remain open across commits?
1031 *
1032 * @return true if cursors always remain open; false if they might not remain open
1033 */
1034 //returns false because Derby does not support cursors that are open across commits for XA transactions.
1035 public boolean supportsOpenCursorsAcrossCommit() {
1036 return false;
1037 }
1038
1039 /**
1040 * Can cursors remain open across rollbacks?
1041 *
1042 * @return true if cursors always remain open; false if they might not remain open
1043 */
1044 public boolean supportsOpenCursorsAcrossRollback() {
1045 return false;
1046 }
1047
1048 /**
1049 * Can statements remain open across commits?
1050 *
1051 * @return true if statements always remain open; false if they might not remain open
1052 */
1053 public boolean supportsOpenStatementsAcrossCommit() {
1054 return true;
1055 }
1056
1057 /**
1058 * Can statements remain open across rollbacks?
1059 *
1060 * @return true if statements always remain open; false if they might not remain open
1061 */
1062 public boolean supportsOpenStatementsAcrossRollback() {
1063 return false;
1064 }
1065
1066
1067
1068 //----------------------------------------------------------------------
1069 // The following group of methods exposes various limitations
1070 // based on the target database with the current driver.
1071 // Unless otherwise specified, a result of zero means there is no
1072 // limit, or the limit is not known.
1073
1074 /**
1075 * How many hex characters can you have in an inline binary literal?
1076 *
1077 * @return max literal length
1078 */
1079 public int getMaxBinaryLiteralLength() {
1080 return 0;
1081 }
1082
1083 /**
1084 * What's the max length for a character literal?
1085 *
1086 * @return max literal length
1087 */
1088 public int getMaxCharLiteralLength() {
1089 return 0;
1090 }
1091
1092 /**
1093 * What's the limit on column name length?
1094 *
1095 * @return max literal length
1096 */
1097 public int getMaxColumnNameLength() {
1098 return Limits.MAX_IDENTIFIER_LENGTH;
1099 }
1100
1101 /**
1102 * What's the maximum number of columns in a "GROUP BY" clause?
1103 *
1104 * @return max number of columns
1105 */
1106 public int getMaxColumnsInGroupBy() {
1107 return 0;
1108 }
1109
1110 /**
1111 * What's the maximum number of columns allowed in an index?
1112 *
1113 * @return max columns
1114 */
1115 public int getMaxColumnsInIndex() {
1116 return 0;
1117 }
1118
1119 /**
1120 * What's the maximum number of columns in an "ORDER BY" clause?
1121 *
1122 * @return max columns
1123 */
1124 public int getMaxColumnsInOrderBy() {
1125 return 0;
1126 }
1127
1128 /**
1129 * What's the maximum number of columns in a "SELECT" list?
1130 *
1131 * we don't have a limit...
1132 *
1133 * @return max columns
1134 */
1135 public int getMaxColumnsInSelect() {
1136 return 0;
1137 }
1138
1139 /**
1140 * What's the maximum number of columns in a table?
1141 *
1142 * @return max columns
1143 */
1144 public int getMaxColumnsInTable() {
1145 return 0;
1146 }
1147
1148 /**
1149 * How many active connections can we have at a time to this database?
1150 *
1151 * @return max connections
1152 */
1153 public int getMaxConnections() {
1154 return 0;
1155 }
1156
1157 /**
1158 * What's the maximum cursor name length?
1159 *
1160 * @return max cursor name length in bytes
1161 */
1162 public int getMaxCursorNameLength() {
1163 return Limits.MAX_IDENTIFIER_LENGTH;
1164 }
1165
1166 /**
1167 * What's the maximum length of an index (in bytes)?
1168 *
1169 * @return max index length in bytes
1170 */
1171 public int getMaxIndexLength() {
1172 return 0;
1173 }
1174
1175 /**
1176 * What's the maximum length allowed for a schema name?
1177 *
1178 * @return max name length in bytes
1179 */
1180 public int getMaxSchemaNameLength() {
1181 return Limits.MAX_IDENTIFIER_LENGTH;
1182 }
1183
1184 /**
1185 * What's the maximum length of a procedure name?
1186 *
1187 * @return max name length in bytes
1188 */
1189 public int getMaxProcedureNameLength() {
1190 return Limits.MAX_IDENTIFIER_LENGTH;
1191 }
1192
1193 /**
1194 * What's the maximum length of a catalog name?
1195 *
1196 * @return max name length in bytes
1197 */
1198 public int getMaxCatalogNameLength() {
1199 return 0;
1200 }
1201
1202 /**
1203 * What's the maximum length of a single row?
1204 *
1205 * @return max row size in bytes
1206 */
1207 public int getMaxRowSize() {
1208 return 0;
1209 }
1210
1211 /**
1212 * Did getMaxRowSize() include LONGVARCHAR and LONGVARBINARY
1213 * blobs?
1214 *
1215 * @return true if so
1216 */
1217 public boolean doesMaxRowSizeIncludeBlobs() {
1218 return true;
1219 }
1220
1221 /**
1222 * What's the maximum length of a SQL statement?
1223 *
1224 * @return max length in bytes
1225 */
1226 public int getMaxStatementLength() {
1227 return 0;
1228 }
1229
1230 /**
1231 * How many active statements can we have open at one time to this
1232 * database?
1233 *
1234 * @return the maximum
1235 */
1236 public int getMaxStatements() {
1237 return 0;
1238 }
1239
1240 /**
1241 * What's the maximum length of a table name?
1242 *
1243 * @return max name length in bytes
1244 */
1245 public int getMaxTableNameLength() {
1246 return Limits.MAX_IDENTIFIER_LENGTH;
1247 }
1248
1249 /**
1250 * What's the maximum number of tables in a SELECT?
1251 *
1252 * @return the maximum
1253 */
1254 public int getMaxTablesInSelect() {
1255 return 0;
1256 }
1257
1258 /**
1259 * What's the maximum length of a user name?
1260 *
1261 * @return max name length in bytes
1262 */
1263 public int getMaxUserNameLength() {
1264 return Limits.DB2_MAX_USERID_LENGTH;
1265 }
1266
1267 //----------------------------------------------------------------------
1268
1269 /**
1270 * What's the database's default transaction isolation level? The
1271 * values are defined in java.sql.Connection.
1272 *
1273 * @return the default isolation level
1274 * @see Connection
1275 */
1276 public int getDefaultTransactionIsolation() {
1277 return java.sql.Connection.TRANSACTION_READ_COMMITTED;
1278 }
1279
1280 /**
1281 * Are transactions supported? If not, commit is a noop and the
1282 * isolation level is TRANSACTION_NONE.
1283 *
1284 * @return true if transactions are supported
1285 */
1286 public boolean supportsTransactions() {
1287 return true;
1288 }
1289
1290 /**
1291 * Does the database support the given transaction isolation level?
1292 *
1293 * DatabaseMetaData.supportsTransactionIsolation() should return false for
1294 * isolation levels that are not supported even if a higher level can be
1295 * substituted.
1296 *
1297 * @param level the values are defined in java.sql.Connection
1298 * @return true if so
1299 * @see Connection
1300 */
1301 public boolean supportsTransactionIsolationLevel(int level)
1302 {
1303 // REMIND: This is hard-coded for the moment because it doesn't nicely
1304 // fit within the framework we've set up for the rest of these values.
1305 // Part of the reason is that it has a parameter, so it's not just a
1306 // simple value look-up. Some ideas for the future on how to make this
1307 // not hard-coded:
1308 // - code it as a query: "select true from <something> where ? in
1309 // (a,b,c)" where a,b,c are the supported isolation levels. The
1310 // parameter would be set to "level". This seems awfully awkward.
1311 // - somehow what you'd really like is to enable the instructions
1312 // file to contain the list, or set, of supported isolation
1313 // levels. Something like:
1314 // supportsTr...ionLevel=SERIALIZABLE | REPEATABLE_READ | ...
1315 // That would take some more code that doesn't seem worthwhile at
1316 // the moment for this one case.
1317
1318 /*
1319 REMIND: this could be moved into a query that is e.g.
1320 VALUES ( ? in (8,...) )
1321 so that database could control the list of supported
1322 isolations. For now, it's hard coded, and just the one.
1323 */
1324
1325 return (level == Connection.TRANSACTION_SERIALIZABLE ||
1326 level == Connection.TRANSACTION_REPEATABLE_READ ||
1327 level == Connection.TRANSACTION_READ_COMMITTED ||
1328 level == Connection.TRANSACTION_READ_UNCOMMITTED);
1329 }
1330
1331 /**
1332 * Are both data definition and data manipulation statements
1333 * within a transaction supported?
1334 *
1335 * @return true if so
1336 */
1337 public boolean supportsDataDefinitionAndDataManipulationTransactions() {
1338 return true;
1339 }
1340 /**
1341 * Are only data manipulation statements within a transaction
1342 * supported?
1343 *
1344 * @return true if so
1345 */
1346 public boolean supportsDataManipulationTransactionsOnly()
1347 {
1348 return false;
1349 }
1350 /**
1351 * Does a data definition statement within a transaction force the
1352 * transaction to commit?
1353 *
1354 * @return true if so
1355 *
1356 */
1357 public boolean dataDefinitionCausesTransactionCommit() {
1358 return false;
1359 }
1360 /**
1361 * Is a data definition statement within a transaction ignored?
1362 *
1363 * @return true if so
1364 *
1365 */
1366 public boolean dataDefinitionIgnoredInTransactions(){
1367 return false;
1368 }
1369
1370
1371 /**
1372 * Get a description of stored procedures available in a
1373 * catalog.
1374 *
1375 * <P>Only procedure descriptions matching the schema and
1376 * procedure name criteria are returned. They are ordered by
1377 * PROCEDURE_SCHEM, and PROCEDURE_NAME.
1378 *
1379 * <P>Each procedure description has the the following columns:
1380 * <OL>
1381 * <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)
1382 * <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)
1383 * <LI><B>PROCEDURE_NAME</B> String => procedure name
1384 * <LI> reserved for future use
1385 * <LI> reserved for future use
1386 * <LI> reserved for future use
1387 * <LI><B>REMARKS</B> String => explanatory comment on the procedure
1388 * <LI><B>PROCEDURE_TYPE</B> short => kind of procedure:
1389 * <UL>
1390 * <LI> procedureResultUnknown - May return a result
1391 * <LI> procedureNoResult - Does not return a result
1392 * <LI> procedureReturnsResult - Returns a result
1393 * </UL>
1394 * </OL>
1395 *
1396 * @param catalog a catalog name; "" retrieves those without a
1397 * catalog; null means drop catalog name from the selection criteria
1398 * @param schemaPattern a schema name pattern; "" retrieves those
1399 * without a schema
1400 * @param procedureNamePattern a procedure name pattern
1401 * @return ResultSet - each row is a procedure description
1402 * @see #getSearchStringEscape
1403 * @exception SQLException thrown on failure.
1404 */
1405 public ResultSet getProcedures(String catalog, String schemaPattern,
1406 String procedureNamePattern) throws SQLException {
1407
1408 return doGetProcs(catalog, schemaPattern,
1409 procedureNamePattern, "getProcedures");
1410 }
1411
1412 /**
1413 * Get a description of stored procedures available in a
1414 * catalog. Same as getProcedures() above, except that
1415 * the result set will conform to ODBC specifications.
1416 */
1417 public ResultSet getProceduresForODBC(String catalog, String schemaPattern,
1418 String procedureNamePattern) throws SQLException {
1419
1420 return doGetProcs(catalog, schemaPattern,
1421 procedureNamePattern, "odbc_getProcedures");
1422 }
1423
1424 /**
1425 * Does the actual work for the getProcedures metadata calls.
1426 * See getProcedures() method above for parameter descriptions.
1427 * @param queryName Name of the query to execute; is used
1428 * to determine whether the result set should conform to
1429 * JDBC or ODBC specifications.
1430 */
1431 private ResultSet doGetProcs(String catalog, String schemaPattern,
1432 String procedureNamePattern, String queryName)
1433 throws SQLException {
1434
1435 PreparedStatement s = getPreparedQuery(queryName);
1436 s.setString(1, swapNull(catalog));
1437 s.setString(2, swapNull(schemaPattern));
1438 s.setString(3, swapNull(procedureNamePattern));
1439 return s.executeQuery();
1440 }
1441
1442 /**
1443 * Get a description of a catalog's stored procedure parameters
1444 * and result columns.
1445 *
1446 * <P>Only descriptions matching the schema, procedure and
1447 * parameter name criteria are returned. They are ordered by
1448 * PROCEDURE_SCHEM and PROCEDURE_NAME. Within this, the return value,
1449 * if any, is first. Next are the parameter descriptions in call
1450 * order. The column descriptions follow in column number order.
1451 *
1452 * <P>Each row in the ResultSet is a parameter description or
1453 * column description with the following fields:
1454 * <OL>
1455 * <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)
1456 * <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)
1457 * <LI><B>PROCEDURE_NAME</B> String => procedure name
1458 * <LI><B>COLUMN_NAME</B> String => column/parameter name
1459 * <LI><B>COLUMN_TYPE</B> Short => kind of column/parameter:
1460 * <UL>
1461 * <LI> procedureColumnUnknown - nobody knows
1462 * <LI> procedureColumnIn - IN parameter
1463 * <LI> procedureColumnInOut - INOUT parameter
1464 * <LI> procedureColumnOut - OUT parameter
1465 * <LI> procedureColumnReturn - procedure return value
1466 * <LI> procedureColumnResult - result column in ResultSet
1467 * </UL>
1468 * <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types
1469 * <LI><B>TYPE_NAME</B> String => SQL type name
1470 * <LI><B>PRECISION</B> int => precision
1471 * <LI><B>LENGTH</B> int => length in bytes of data
1472 * <LI><B>SCALE</B> short => scale
1473 * <LI><B>RADIX</B> short => radix
1474 * <LI><B>NULLABLE</B> short => can it contain NULL?
1475 * <UL>
1476 * <LI> procedureNoNulls - does not allow NULL values
1477 * <LI> procedureNullable - allows NULL values
1478 * <LI> procedureNullableUnknown - nullability unknown
1479 * </UL>
1480 * <LI><B>REMARKS</B> String => comment describing parameter/column
1481 * </OL>
1482 *
1483 * <P><B>Note:</B> Some databases may not return the column
1484 * descriptions for a procedure. Additional columns beyond
1485 * REMARKS can be defined by the database.
1486 *
1487 * @param catalog a catalog name; "" retrieves those without a
1488 * catalog; null means drop catalog name from the selection criteria
1489 * @param schemaPattern a schema name pattern; "" retrieves those
1490 * without a schema
1491 * @param procedureNamePattern a procedure name pattern
1492 * @param columnNamePattern a column name pattern
1493 * @return ResultSet - each row is a stored procedure parameter or
1494 * column description
1495 * @see #getSearchStringEscape
1496 * @exception SQLException thrown on failure.
1497 */
1498 public ResultSet getProcedureColumns(String catalog,
1499 String schemaPattern,
1500 String procedureNamePattern,
1501 String columnNamePattern) throws SQLException {
1502
1503 return doGetProcCols(catalog, schemaPattern,
1504 procedureNamePattern, columnNamePattern,
1505 "getProcedureColumns");
1506 }
1507
1508 /**
1509 * Get a description of a catalog's stored procedure parameters
1510 * and result columns. Same as getProcedureColumns() above,
1511 * except that the result set will conform to ODBC specifications.
1512 */
1513 public ResultSet getProcedureColumnsForODBC(String catalog,
1514 String schemaPattern, String procedureNamePattern,
1515 String columnNamePattern) throws SQLException {
1516
1517 return doGetProcCols(catalog, schemaPattern,
1518 procedureNamePattern, columnNamePattern,
1519 "odbc_getProcedureColumns");
1520 }
1521
1522 /**
1523 * Does the actual work for the getProcedureColumns metadata
1524 * calls. See getProcedureColumns() method above for parameter
1525 * descriptions.
1526 * @param queryName Name of the query to execute; is used
1527 * to determine whether the result set should conform to
1528 * JDBC or ODBC specifications.
1529 */
1530 private ResultSet doGetProcCols(String catalog, String schemaPattern,
1531 String procedureNamePattern, String columnNamePattern,
1532 String queryName) throws SQLException {
1533
1534 PreparedStatement s = getPreparedQuery(queryName);
1535 //
1536 // catalog is not part of the query
1537 //
1538 s.setString(1, swapNull(schemaPattern));
1539 s.setString(2, swapNull(procedureNamePattern));
1540 s.setString(3, swapNull(columnNamePattern));
1541 return s.executeQuery();
1542 }
1543
1544 /**
1545 * Get a description of tables available in a catalog.
1546 *
1547 * <P>Only table descriptions matching the catalog, schema, table
1548 * name and type criteria are returned. They are ordered by
1549 * TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.
1550 *
1551 * <P>Each table description has the following columns:
1552 * <OL>
1553 * <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1554 * <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1555 * <LI><B>TABLE_NAME</B> String => table name
1556 * <LI><B>TABLE_TYPE</B> String => table type. Typical types are "TABLE",
1557 * "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
1558 * "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
1559 * <LI><B>REMARKS</B> String => explanatory comment on the table
1560 * </OL>
1561 *
1562 * <P><B>Note:</B> Some databases may not return information for
1563 * all tables.
1564 *
1565 * @param catalog a catalog name; "" retrieves those without a
1566 * catalog; null means drop catalog name from the selection criteria
1567 * @param schemaPattern a schema name pattern; "" retrieves those
1568 * without a schema
1569 * @param tableNamePattern a table name pattern
1570 * @param types a list of table types to include; null returns all types
1571 * @return ResultSet - each row is a table description
1572 * @see #getSearchStringEscape
1573 * @exception SQLException thrown on failure.
1574 */
1575 public ResultSet getTables(String catalog, String schemaPattern,
1576 String tableNamePattern, String types[]) throws SQLException {
1577 synchronized (getConnectionSynchronization()) {
1578 setupContextStack();
1579 ResultSet rs = null;
1580 try {
1581
1582 String queryText = getQueryDescriptions().getProperty("getTables");
1583
1584 /*
1585 * The query text is assumed to end with a "where" clause, so
1586 * that we can safely append
1587 * "and table_Type in ('xxx','yyy','zzz', ...)" and
1588 * have it become part of the where clause.
1589 *
1590 * Let's assume for now that the table type first char corresponds
1591 * to JBMS table type identifiers.
1592 */
1593 StringBuffer whereClauseTail = new StringBuffer(queryText);
1594
1595 if (types != null && types.length >= 1) {
1596 whereClauseTail.append(" AND TABLETYPE IN ('");
1597 whereClauseTail.append(types[0].substring(0, 1));
1598
1599 for (int i=1; i<types.length; i++) {
1600 whereClauseTail.append("','");
1601 whereClauseTail.append(types[i].substring(0, 1));
1602 }
1603 whereClauseTail.append("')");
1604 }
1605 // Add the order by clause after the 'in' list.
1606 whereClauseTail.append(
1607 " ORDER BY TABLE_TYPE, TABLE_SCHEM, TABLE_NAME");
1608
1609 PreparedStatement s =
1610 getEmbedConnection().prepareMetaDataStatement(whereClauseTail.toString());
1611
1612 s.setString(1, swapNull(catalog));
1613 s.setString(2, swapNull(schemaPattern));
1614 s.setString(3, swapNull(tableNamePattern));
1615
1616 rs = s.executeQuery();
1617 } catch (Throwable t) {
1618 throw handleException(t);
1619 } finally {
1620 restoreContextStack();
1621 }
1622
1623 return rs;
1624 }
1625 }
1626
1627 /**
1628 * Get the schema names available in this database. The results
1629 * are ordered by schema name.
1630 *
1631 * <P>The schema column is:
1632 * <OL>
1633 * <LI><B>TABLE_SCHEM</B> String => schema name
1634 * </OL>
1635 *
1636 * @return ResultSet - each row has a single String column that is a
1637 * schema name
1638 * @exception SQLException thrown on failure.
1639 */
1640 public ResultSet getSchemas() throws SQLException {
1641 return getSimpleQuery("getSchemas");
1642 }
1643
1644 /**
1645 * Get the catalog names available in this database. The results
1646 * are ordered by catalog name.
1647 *
1648 * <P>The catalog column is:
1649 * <OL>
1650 * <LI><B>TABLE_CAT</B> String => catalog name
1651 * </OL>
1652 *
1653 * @return ResultSet - each row has a single String column that is a
1654 * catalog name
1655 * @exception SQLException thrown on failure.
1656 */
1657 public ResultSet getCatalogs() throws SQLException {
1658 return getSimpleQuery("getCatalogs");
1659 }
1660
1661 /**
1662 * Get the table types available in this database. The results
1663 * are ordered by table type.
1664 *
1665 * <P>The table type is:
1666 * <OL>
1667 * <LI><B>TABLE_TYPE</B> String => table type. Typical types are "TABLE",
1668 * "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
1669 * "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
1670 * </OL>
1671 *
1672 * @return ResultSet - each row has a single String column that is a
1673 * table type
1674 * @exception SQLException thrown on failure.
1675 */
1676 public ResultSet getTableTypes() throws SQLException {
1677 return getSimpleQuery("getTableTypes");
1678 }
1679
1680 /**
1681 * Get a description of table columns available in a catalog.
1682 *
1683 * <P>Only column descriptions matching the catalog, schema, table
1684 * and column name criteria are returned. They are ordered by
1685 * TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.
1686 *
1687 * <P>Each column description has the following columns:
1688 * <OL>
1689 * <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1690 * <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1691 * <LI><B>TABLE_NAME</B> String => table name
1692 * <LI><B>COLUMN_NAME</B> String => column name
1693 * <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types
1694 * <LI><B>TYPE_NAME</B> String => Data source dependent type name
1695 * <LI><B>COLUMN_SIZE</B> int => column size. For char or date
1696 * types this is the maximum number of characters, for numeric or
1697 * decimal types this is precision.
1698 * <LI><B>BUFFER_LENGTH</B> is not used.
1699 * <LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits
1700 * <LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)
1701 * <LI><B>NULLABLE</B> int => is NULL allowed?
1702 * <UL>
1703 * <LI> columnNoNulls - might not allow NULL values
1704 * <LI> columnNullable - definitely allows NULL values
1705 * <LI> columnNullableUnknown - nullability unknown
1706 * </UL>
1707 * <LI><B>REMARKS</B> String => comment describing column (may be null)
1708 * <LI><B>COLUMN_DEF</B> String => default value (may be null)
1709 * <LI><B>SQL_DATA_TYPE</B> int => unused
1710 * <LI><B>SQL_DATETIME_SUB</B> int => unused
1711 * <LI><B>CHAR_OCTET_LENGTH</B> int => for char types the
1712 * maximum number of bytes in the column
1713 * <LI><B>ORDINAL_POSITION</B> int => index of column in table
1714 * (starting at 1)
1715 * <LI><B>IS_NULLABLE</B> String => "NO" means column definitely
1716 * does not allow NULL values; "YES" means the column might
1717 * allow NULL values. An empty string means nobody knows.
1718 * </OL>
1719 *
1720 * @param catalog a catalog name; "" retrieves those without a
1721 * catalog; null means drop catalog name from the selection criteria
1722 * @param schem