Source Code Cross Referenced for EmbedDatabaseMetaData.java in  » Database-DBMS » db-derby-10.2 » org » apache » derby » impl » jdbc » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » db derby 10.2 » org.apache.derby.impl.jdbc 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:
0003:           Derby - Class org.apache.derby.impl.jdbc.EmbedDatabaseMetaData
0004:
0005:           Licensed to the Apache Software Foundation (ASF) under one or more
0006:           contributor license agreements.  See the NOTICE file distributed with
0007:           this work for additional information regarding copyright ownership.
0008:           The ASF licenses this file to you under the Apache License, Version 2.0
0009:           (the "License"); you may not use this file except in compliance with
0010:           the License.  You may obtain a copy of the License at
0011:
0012:              http://www.apache.org/licenses/LICENSE-2.0
0013:
0014:           Unless required by applicable law or agreed to in writing, software
0015:           distributed under the License is distributed on an "AS IS" BASIS,
0016:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017:           See the License for the specific language governing permissions and
0018:           limitations under the License.
0019:
0020:         */
0021:
0022:        package org.apache.derby.impl.jdbc;
0023:
0024:        import org.apache.derby.iapi.services.info.ProductVersionHolder;
0025:
0026:        import org.apache.derby.iapi.services.monitor.Monitor;
0027:
0028:        import org.apache.derby.iapi.services.sanity.SanityManager;
0029:
0030:        import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
0031:
0032:        import org.apache.derby.iapi.sql.dictionary.DataDictionary;
0033:        import org.apache.derby.iapi.sql.dictionary.SPSDescriptor;
0034:
0035:        import org.apache.derby.iapi.error.StandardException;
0036:
0037:        import org.apache.derby.impl.sql.execute.GenericConstantActionFactory;
0038:        import org.apache.derby.impl.sql.execute.GenericExecutionFactory;
0039:
0040:        import org.apache.derby.iapi.reference.Limits;
0041:        import org.apache.derby.iapi.reference.JDBC20Translation;
0042:        import org.apache.derby.iapi.reference.JDBC30Translation;
0043:
0044:        import java.util.Properties;
0045:
0046:        import java.sql.DatabaseMetaData;
0047:        import java.sql.Connection;
0048:        import java.sql.PreparedStatement;
0049:        import java.sql.SQLException;
0050:        import java.sql.ResultSet;
0051:        import java.sql.Types;
0052:
0053:        import java.io.IOException;
0054:        import java.io.InputStream;
0055:
0056:        /**
0057:         * This class provides information about the database as a whole.
0058:         *
0059:         * <P>Many of the methods here return lists of information in ResultSets.
0060:         * You can use the normal ResultSet methods such as getString and getInt
0061:         * to retrieve the data from these ResultSets.  If a given form of
0062:         * metadata is not available, these methods should throw a SQLException.
0063:         *
0064:         * <P>Some of these methods take arguments that are String patterns.  These
0065:         * arguments all have names such as fooPattern.  Within a pattern String, "%"
0066:         * means match any substring of 0 or more characters, and "_" means match
0067:         * any one character. Only metadata entries matching the search pattern
0068:         * are returned. If a search pattern argument is set to a null ref, it means
0069:         * that argument's criteria should be dropped from the search.
0070:         *
0071:         * <P>A SQLException will be thrown if a driver does not support a meta
0072:         * data method.  In the case of methods that return a ResultSet,
0073:         * either a ResultSet (which may be empty) is returned or a
0074:         * SQLException is thrown.
0075:         * <p>
0076:         * This implementation gets instructions from the Database for how to satisfy
0077:         * most requests for information.  Each instruction is either a simple string
0078:         * containing the desired information, or the text of a query that may be
0079:         * executed on the database connection to gather the information.  We get the
0080:         * instructions via an "InstructionReader," which requires the database
0081:         * Connection for initialization.
0082:         * <p>
0083:         * Those few pieces of metadata that are related to the driver, rather than the
0084:         * database, come from a separate InstructionReader.  Note that in that case it
0085:         * probably doesn't make sense to allow an instruction to specify a query.
0086:         *
0087:         * @author ames
0088:         */
0089:        public class EmbedDatabaseMetaData extends ConnectionChild implements 
0090:                DatabaseMetaData, java.security.PrivilegedAction {
0091:
0092:            /*
0093:             ** Property and values related to using
0094:             ** stored prepared statements for metatdata.
0095:             */
0096:
0097:            private final String url;
0098:
0099:            /*
0100:             ** Set to true if metadata is off
0101:             */
0102:
0103:            private GenericConstantActionFactory constantActionFactory;
0104:
0105:            //////////////////////////////////////////////////////////////
0106:            //
0107:            // CONSTRUCTORS
0108:            //
0109:            //////////////////////////////////////////////////////////////
0110:            /**
0111:                @exception SQLException on error
0112:             */
0113:            public EmbedDatabaseMetaData(EmbedConnection connection, String url)
0114:                    throws SQLException {
0115:
0116:                super (connection);
0117:                this .url = url;
0118:
0119:            }
0120:
0121:            /** Cached query descriptions from metadata.properties. */
0122:            private static Properties queryDescriptions;
0123:            /** Cached query descriptions from metadata_net.properties. */
0124:            private static Properties queryDescriptions_net;
0125:
0126:            /**
0127:             * Return all queries found in either metadata.properties or
0128:             * metadata_net.properties.
0129:             *
0130:             * @param net if <code>true</code>, read metadata_net.properties;
0131:             * otherwise, read metadata.properties.
0132:             * @return a <code>Properties</code> value with the queries
0133:             */
0134:            private Properties getQueryDescriptions(boolean net) {
0135:                Properties p = net ? queryDescriptions_net : queryDescriptions;
0136:                if (p != null) {
0137:                    return p;
0138:                }
0139:                loadQueryDescriptions();
0140:                return net ? queryDescriptions_net : queryDescriptions;
0141:            }
0142:
0143:            /**
0144:             * Read the query descriptions from metadata.properties and
0145:             * metadata_net.properties. This method must be invoked from
0146:             * within a privileged block.
0147:             */
0148:            private void PBloadQueryDescriptions() {
0149:                String[] files = { "metadata.properties",
0150:                        "/org/apache/derby/impl/sql/catalog/metadata_net.properties" };
0151:                Properties[] props = new Properties[files.length];
0152:                for (int i = 0; i < files.length; ++i) {
0153:                    try {
0154:                        props[i] = new Properties();
0155:                        // SECURITY PERMISSION - IP3
0156:                        InputStream is = getClass().getResourceAsStream(
0157:                                files[i]);
0158:                        props[i].load(is);
0159:                        is.close();
0160:                    } catch (IOException ioe) {
0161:                        if (SanityManager.DEBUG) {
0162:                            SanityManager.THROWASSERT("Error reading "
0163:                                    + files[i], ioe);
0164:                        }
0165:                    }
0166:                }
0167:                queryDescriptions = props[0];
0168:                queryDescriptions_net = props[1];
0169:            }
0170:
0171:            //////////////////////////////////////////////////////////////
0172:            //
0173:            // DatabaseMetaData interface
0174:            //
0175:            //////////////////////////////////////////////////////////////
0176:
0177:            //----------------------------------------------------------------------
0178:            // First, a variety of minor information about the target database.
0179:
0180:            /**
0181:             * Can all the procedures returned by getProcedures be called by the
0182:             * current user?
0183:             *
0184:             * @return true if so
0185:             */
0186:            public boolean allProceduresAreCallable() {
0187:                return true;
0188:            }
0189:
0190:            /**
0191:             * Can all the tables returned by getTable be SELECTed by the
0192:             * current user?
0193:             *
0194:             * @return true if so
0195:             */
0196:            public boolean allTablesAreSelectable() {
0197:                return true;
0198:            }
0199:
0200:            /**
0201:             * What's the url for this database?
0202:             *
0203:             * @return the url or null if it can't be generated
0204:             */
0205:            public final String getURL() {
0206:
0207:                if (url == null)
0208:                    return url;
0209:                int attributeStart = url.indexOf(';');
0210:                if (attributeStart == -1)
0211:                    return url;
0212:                else
0213:                    return url.substring(0, attributeStart);
0214:            }
0215:
0216:            /**
0217:             * What's our user name as known to the database?
0218:             *
0219:             * @return our database user name
0220:             */
0221:            public String getUserName() {
0222:                return (getEmbedConnection().getTR().getUserName());
0223:            }
0224:
0225:            /**
0226:             * Is the database in read-only mode?
0227:             *
0228:             * @return true if so
0229:             */
0230:            public boolean isReadOnly() {
0231:                return getLanguageConnectionContext().getDatabase()
0232:                        .isReadOnly();
0233:            }
0234:
0235:            /**
0236:             * Are NULL values sorted high?
0237:             *
0238:             * @return true if so
0239:             */
0240:            public boolean nullsAreSortedHigh() {
0241:                return true;
0242:            }
0243:
0244:            /**
0245:             * Are NULL values sorted low?
0246:             *
0247:             * @return true if so
0248:             */
0249:            public boolean nullsAreSortedLow() {
0250:                return false;
0251:            }
0252:
0253:            /**
0254:             * Are NULL values sorted at the start regardless of sort order?
0255:             *
0256:             * @return true if so
0257:             */
0258:            public boolean nullsAreSortedAtStart() {
0259:                return false;
0260:            }
0261:
0262:            /**
0263:             * Are NULL values sorted at the end regardless of sort order?
0264:             *
0265:             * @return true if so
0266:             */
0267:            public boolean nullsAreSortedAtEnd() {
0268:                return false;
0269:            }
0270:
0271:            /**
0272:             * What's the name of this database product?
0273:             *
0274:             * @return database product name
0275:             */
0276:            public String getDatabaseProductName() {
0277:                return Monitor.getMonitor().getEngineVersion().getProductName();
0278:            }
0279:
0280:            /**
0281:             * What's the version of this database product?
0282:             *
0283:             * @return database version
0284:             */
0285:            public String getDatabaseProductVersion() {
0286:                ProductVersionHolder myPVH = Monitor.getMonitor()
0287:                        .getEngineVersion();
0288:
0289:                return myPVH.getVersionBuildString(true);
0290:            }
0291:
0292:            /**
0293:             * What's the name of this JDBC driver?
0294:             *
0295:             * @return JDBC driver name
0296:             */
0297:            public String getDriverName() {
0298:                return "Apache Derby Embedded JDBC Driver";
0299:            }
0300:
0301:            /**
0302:             * What's the version of this JDBC driver?
0303:             *
0304:             * @return JDBC driver version
0305:             */
0306:            public String getDriverVersion() {
0307:                return getDatabaseProductVersion();
0308:            }
0309:
0310:            /**
0311:             * What's this JDBC driver's major version number?
0312:             *
0313:             * @return JDBC driver major version
0314:             */
0315:            public int getDriverMajorVersion() {
0316:                return getEmbedConnection().getLocalDriver().getMajorVersion();
0317:            }
0318:
0319:            /**
0320:             * What's this JDBC driver's minor version number?
0321:             *
0322:             * @return JDBC driver minor version number
0323:             */
0324:            public int getDriverMinorVersion() {
0325:                return getEmbedConnection().getLocalDriver().getMinorVersion();
0326:            }
0327:
0328:            /**
0329:             * Does the database store tables in a local file?
0330:             *
0331:             * @return true if so
0332:             */
0333:            public boolean usesLocalFiles() {
0334:                return true;
0335:            }
0336:
0337:            /**
0338:             * Does the database use a file for each table?
0339:             *
0340:             * @return true if the database uses a local file for each table
0341:             */
0342:            public boolean usesLocalFilePerTable() {
0343:                return true;
0344:            }
0345:
0346:            /**
0347:             * Does the database treat mixed case unquoted SQL identifiers as
0348:             * case sensitive and as a result store them in mixed case?
0349:             *
0350:             * A JDBC-Compliant driver will always return false.
0351:             *
0352:             * @return true if so
0353:             */
0354:            public boolean supportsMixedCaseIdentifiers() {
0355:                return false;
0356:            }
0357:
0358:            /**
0359:             * Does the database treat mixed case unquoted SQL identifiers as
0360:             * case insensitive and store them in upper case?
0361:             *
0362:             * @return true if so
0363:             */
0364:            public boolean storesUpperCaseIdentifiers() {
0365:                return true;
0366:            }
0367:
0368:            /**
0369:             * Does the database treat mixed case unquoted SQL identifiers as
0370:             * case insensitive and store them in lower case?
0371:             *
0372:             * @return true if so
0373:             */
0374:            public boolean storesLowerCaseIdentifiers() {
0375:                return false;
0376:            }
0377:
0378:            /**
0379:             * Does the database treat mixed case unquoted SQL identifiers as
0380:             * case insensitive and store them in mixed case?
0381:             *
0382:             * @return true if so
0383:             */
0384:            public boolean storesMixedCaseIdentifiers() {
0385:                return false;
0386:            }
0387:
0388:            /**
0389:             * Does the database treat mixed case quoted SQL identifiers as
0390:             * case sensitive and as a result store them in mixed case?
0391:             *
0392:             * A JDBC-Compliant driver will always return true.
0393:             *
0394:             * @return true if so
0395:             */
0396:            public boolean supportsMixedCaseQuotedIdentifiers() {
0397:                return true;
0398:            }
0399:
0400:            /**
0401:             * Does the database treat mixed case quoted SQL identifiers as
0402:             * case insensitive and store them in upper case?
0403:             *
0404:             * @return true if so
0405:             */
0406:            public boolean storesUpperCaseQuotedIdentifiers() {
0407:                return false;
0408:            }
0409:
0410:            /**
0411:             * Does the database treat mixed case quoted SQL identifiers as
0412:             * case insensitive and store them in lower case?
0413:             *
0414:             * @return true if so
0415:             */
0416:            public boolean storesLowerCaseQuotedIdentifiers() {
0417:                return false;
0418:            }
0419:
0420:            /**
0421:             * Does the database treat mixed case quoted SQL identifiers as
0422:             * case insensitive and store them in mixed case?
0423:             *
0424:             * @return true if so
0425:             */
0426:            public boolean storesMixedCaseQuotedIdentifiers() {
0427:                return true;
0428:            }
0429:
0430:            /**
0431:             * What's the string used to quote SQL identifiers?
0432:             * This returns a space " " if identifier quoting isn't supported.
0433:             *
0434:             * A JDBC-Compliant driver always uses a double quote character.
0435:             *
0436:             * @return the quoting string
0437:             */
0438:            public String getIdentifierQuoteString() {
0439:                return "\"";
0440:            }
0441:
0442:            /**
0443:             * Get a comma separated list of all a database's SQL keywords
0444:             * that are NOT also SQL92 keywords.
0445:            includes reserved and non-reserved keywords.
0446:
0447:             * @return the list
0448:             */
0449:            public String getSQLKeywords() {
0450:                return "ALIAS,BIGINT,BOOLEAN,CALL,CLASS,COPY,DB2J_DEBUG,EXECUTE,EXPLAIN,FILE,FILTER,"
0451:                        + "GETCURRENTCONNECTION,INDEX,INSTANCEOF,METHOD,NEW,OFF,PROPERTIES,PUBLICATION,RECOMPILE,"
0452:                        + "REFRESH,RENAME,RUNTIMESTATISTICS,STATEMENT,STATISTICS,TIMING,WAIT";
0453:            }
0454:
0455:            /**
0456:             * Get a comma separated list of JDBC escaped numeric functions.
0457:             * Must be a complete or sub set of functions in appendix C.1
0458:             * @return the list
0459:             */
0460:            public String getNumericFunctions() {
0461:                return "ABS,ACOS,ASIN,ATAN,CEILING,COS,DEGREES,EXP,FLOOR,LOG,LOG10,MOD,PI,RADIANS,SIN,SQRT,TAN";
0462:            }
0463:
0464:            /**
0465:             * Get a comma separated list of JDBC escaped string functions.
0466:             * Must be a complete or sub set of functions in appendix C.2
0467:             * of JDBC 3.0 specification.
0468:             * @return the list
0469:             */
0470:            public String getStringFunctions() {
0471:                return "CONCAT,LENGTH,LCASE,LOCATE,LTRIM,RTRIM,SUBSTRING,UCASE";
0472:            }
0473:
0474:            /**
0475:             * Get a comma separated list of JDBC escaped system functions.
0476:             * Must be a complete or sub set of functions in appendix C.4
0477:             * of JDBC 3.0 specification.
0478:             * @return the list
0479:             */
0480:            public String getSystemFunctions() {
0481:                return "USER";
0482:            }
0483:
0484:            /**
0485:             * Get a comma separated list of JDBC escaped time date functions.
0486:             * Must be a complete or sub set of functions in appendix C.3
0487:             * of JDBC 3.0 specification.
0488:             * @return the list
0489:             */
0490:            public String getTimeDateFunctions() {
0491:                return "CURDATE,CURTIME,HOUR,MINUTE,MONTH,SECOND,TIMESTAMPADD,TIMESTAMPDIFF,YEAR";
0492:            }
0493:
0494:            /**
0495:             * This is the string that can be used to escape '_' or '%' in
0496:             * the string pattern style catalog search parameters.
0497:                we have no default escape value, so = is the end of the next line
0498:             * <P>The '_' character represents any single character.
0499:             * <P>The '%' character represents any sequence of zero or
0500:             * more characters.
0501:             * @return the string used to escape wildcard characters
0502:             */
0503:            public String getSearchStringEscape() {
0504:                return "";
0505:            }
0506:
0507:            /**
0508:             * Get all the "extra" characters that can be used in unquoted
0509:             * identifier names (those beyond a-z, A-Z, 0-9 and _).
0510:             *
0511:             * @return the string containing the extra characters
0512:             */
0513:            public String getExtraNameCharacters() {
0514:                return "";
0515:            }
0516:
0517:            //--------------------------------------------------------------------
0518:            // Functions describing which features are supported.
0519:
0520:            /**
0521:             * Is "ALTER TABLE" with add column supported?
0522:             *
0523:             * @return true if so
0524:             */
0525:            public boolean supportsAlterTableWithAddColumn() {
0526:                return true;
0527:            }
0528:
0529:            /**
0530:             * Is "ALTER TABLE" with drop column supported?
0531:             *
0532:             * @return true if so
0533:             */
0534:            public boolean supportsAlterTableWithDropColumn() {
0535:                return true;
0536:            }
0537:
0538:            /**
0539:             * Is column aliasing supported?
0540:             *
0541:             * <P>If so, the SQL AS clause can be used to provide names for
0542:             * computed columns or to provide alias names for columns as
0543:             * required.
0544:             *
0545:             * A JDBC-Compliant driver always returns true.
0546:             *
0547:             * @return true if so
0548:             */
0549:            public boolean supportsColumnAliasing() {
0550:                return true;
0551:            }
0552:
0553:            /**
0554:             * Are concatenations between NULL and non-NULL values NULL?
0555:             *
0556:             * A JDBC-Compliant driver always returns true.
0557:             *
0558:             * @return true if so
0559:             */
0560:            public boolean nullPlusNonNullIsNull() {
0561:                return true;
0562:            }
0563:
0564:            /**
0565:             * Is the CONVERT function between SQL types supported?
0566:             *
0567:             * @return true if so
0568:             */
0569:            public boolean supportsConvert() {
0570:                return true;
0571:            }
0572:
0573:            /**
0574:             * Is CONVERT between the given SQL types supported?
0575:             *
0576:             * @param fromType the type to convert from
0577:             * @param toType the type to convert to
0578:             * @return true if so
0579:             * @see Types
0580:             */
0581:            public boolean supportsConvert(int fromType, int toType) {
0582:                /*
0583:                 * at the moment we don't support CONVERT at all, so we take the easy
0584:                 * way out.  Eventually we need to figure out how to handle this
0585:                 * cleanly.
0586:                 */
0587:                return false;
0588:            }
0589:
0590:            /**
0591:             * Are table correlation names supported?
0592:             *
0593:             * A JDBC-Compliant driver always returns true.
0594:             *
0595:             * @return true if so
0596:             */
0597:            public boolean supportsTableCorrelationNames() {
0598:                return true;
0599:            }
0600:
0601:            /**
0602:             * If table correlation names are supported, are they restricted
0603:             * to be different from the names of the tables?
0604:             *
0605:             * @return true if so
0606:             */
0607:            public boolean supportsDifferentTableCorrelationNames() {
0608:                return true;
0609:            }
0610:
0611:            /**
0612:             * Are expressions in "ORDER BY" lists supported?
0613:             *
0614:             * @return true if so
0615:             */
0616:            public boolean supportsExpressionsInOrderBy() {
0617:                return false;
0618:            }
0619:
0620:            /**
0621:             * Can an "ORDER BY" clause use columns not in the SELECT?
0622:             *
0623:             * @return true if so
0624:             */
0625:            public boolean supportsOrderByUnrelated() {
0626:                return false;
0627:            }
0628:
0629:            /**
0630:             * Is some form of "GROUP BY" clause supported?
0631:             *
0632:             * @return true if so
0633:             */
0634:            public boolean supportsGroupBy() {
0635:                return true;
0636:            }
0637:
0638:            /**
0639:             * Can a "GROUP BY" clause use columns not in the SELECT?
0640:             *
0641:             * @return true if so
0642:             */
0643:            public boolean supportsGroupByUnrelated() {
0644:                return true;
0645:            }
0646:
0647:            /**
0648:             * Can a "GROUP BY" clause add columns not in the SELECT
0649:             * provided it specifies all the columns in the SELECT?
0650:             *
0651:             * @return true if so
0652:             */
0653:            public boolean supportsGroupByBeyondSelect() {
0654:                return true;
0655:            }
0656:
0657:            /**
0658:             * Is the escape character in "LIKE" clauses supported?
0659:             *
0660:             * A JDBC-Compliant driver always returns true.
0661:             *
0662:             * @return true if so
0663:             */
0664:            public boolean supportsLikeEscapeClause() {
0665:                return true;
0666:            }
0667:
0668:            /**
0669:             * Are multiple ResultSets from a single execute supported?
0670:             *
0671:             * @return true if so
0672:             */
0673:            public boolean supportsMultipleResultSets() {
0674:                return true;
0675:            }
0676:
0677:            /**
0678:             * Can we have multiple transactions open at once (on different
0679:             * connections)?
0680:             *
0681:             * @return true if so
0682:             */
0683:            public boolean supportsMultipleTransactions() {
0684:                return true;
0685:            }
0686:
0687:            /**
0688:             * Can columns be defined as non-nullable?
0689:             *
0690:             * A JDBC-Compliant driver always returns true.
0691:             *
0692:             * @return true if so
0693:             */
0694:            public boolean supportsNonNullableColumns() {
0695:                return true;
0696:            }
0697:
0698:            /**
0699:             * Is the ODBC Minimum SQL grammar supported?
0700:             *
0701:             * All JDBC-Compliant drivers must return true.
0702:             *
0703:             * @return true if so
0704:             */
0705:            public boolean supportsMinimumSQLGrammar() {
0706:                return true;
0707:            }
0708:
0709:            /**
0710:             * Is the ODBC Core SQL grammar supported?
0711:             *
0712:             * @return true if so
0713:             */
0714:            public boolean supportsCoreSQLGrammar() {
0715:                return false;
0716:            }
0717:
0718:            /**
0719:             * Is the ODBC Extended SQL grammar supported?
0720:             *
0721:             * @return true if so
0722:             */
0723:            public boolean supportsExtendedSQLGrammar() {
0724:                return false;
0725:            }
0726:
0727:            /**
0728:             * Is the ANSI92 entry level SQL grammar supported?
0729:             *
0730:             * All JDBC-Compliant drivers must return true.
0731:             *
0732:             * @return true if so
0733:             */
0734:            public boolean supportsANSI92EntryLevelSQL() {
0735:                return false;
0736:            }
0737:
0738:            /**
0739:             * Is the ANSI92 intermediate SQL grammar supported?
0740:             *
0741:             * @return true if so
0742:             * 
0743:             */
0744:            public boolean supportsANSI92IntermediateSQL() {
0745:                return false;
0746:            }
0747:
0748:            /**
0749:             * Is the ANSI92 full SQL grammar supported?
0750:             *
0751:             * @return true if so
0752:             * 
0753:             */
0754:            public boolean supportsANSI92FullSQL() {
0755:                return false;
0756:            }
0757:
0758:            /**
0759:             * Is the SQL Integrity Enhancement Facility supported?
0760:             *
0761:             * @return true if so
0762:             * 
0763:             */
0764:            public boolean supportsIntegrityEnhancementFacility() {
0765:                return false;
0766:            }
0767:
0768:            /**
0769:             * Is some form of outer join supported?
0770:             *
0771:             * @return true if so
0772:             * 
0773:             */
0774:            public boolean supportsOuterJoins() {
0775:                return true;
0776:            }
0777:
0778:            /**
0779:             * Are full nested outer joins supported?
0780:             *
0781:             * @return true if so
0782:             * 
0783:             */
0784:            public boolean supportsFullOuterJoins() {
0785:                return false;
0786:            }
0787:
0788:            /**
0789:             * Is there limited support for outer joins?  (This will be true
0790:             * if supportFullOuterJoins is true.)
0791:             *
0792:             * @return true if so
0793:             * 
0794:             */
0795:            public boolean supportsLimitedOuterJoins() {
0796:                return true;
0797:            }
0798:
0799:            /**
0800:             * What's the database vendor's preferred term for "schema"?
0801:             *
0802:             * @return the vendor term
0803:             * 
0804:             */
0805:            public String getSchemaTerm() {
0806:                return "SCHEMA";
0807:            }
0808:
0809:            /**
0810:             * What's the database vendor's preferred term for "procedure"?
0811:             *
0812:             * @return the vendor term
0813:             * 
0814:             */
0815:            public String getProcedureTerm() {
0816:                return "PROCEDURE";
0817:            }
0818:
0819:            /**
0820:             * What's the database vendor's preferred term for "catalog"?
0821:             *
0822:             * @return the vendor term
0823:             * 
0824:             */
0825:            public String getCatalogTerm() {
0826:                return "CATALOG";
0827:            }
0828:
0829:            /**
0830:             * Does a catalog appear at the start of a qualified table name?
0831:             * (Otherwise it appears at the end)
0832:             *
0833:             * @return true if it appears at the start
0834:             * 
0835:             */
0836:            public boolean isCatalogAtStart() {
0837:                return false;
0838:            }
0839:
0840:            /**
0841:             * What's the separator between catalog and table name?
0842:             *
0843:             * @return the separator string
0844:             * 
0845:             */
0846:            public String getCatalogSeparator() {
0847:                return "";
0848:            }
0849:
0850:            /**
0851:             * Can a schema name be used in a data manipulation statement?
0852:             *
0853:             * @return true if so
0854:             * 
0855:             */
0856:            public boolean supportsSchemasInDataManipulation() {
0857:                return true;
0858:            }
0859:
0860:            /**
0861:             * Can a schema name be used in a procedure call statement?
0862:             *
0863:             * @return true if so
0864:             * 
0865:             */
0866:            public boolean supportsSchemasInProcedureCalls() {
0867:                return true;
0868:            }
0869:
0870:            /**
0871:             * Can a schema name be used in a table definition statement?
0872:             *
0873:             * @return true if so
0874:             * 
0875:             */
0876:            public boolean supportsSchemasInTableDefinitions() {
0877:                return true;
0878:            }
0879:
0880:            /**
0881:             * Can a schema name be used in an index definition statement?
0882:             *
0883:             * @return true if so
0884:             */
0885:            public boolean supportsSchemasInIndexDefinitions() {
0886:                return true;
0887:            }
0888:
0889:            /**
0890:             * Can a schema name be used in a privilege definition statement?
0891:             *
0892:             * @return true if so
0893:             * 
0894:             */
0895:            public boolean supportsSchemasInPrivilegeDefinitions() {
0896:                return true;
0897:            }
0898:
0899:            /**
0900:             * Can a catalog name be used in a data manipulation statement?
0901:             *
0902:             * @return true if so
0903:             * 
0904:             */
0905:            public boolean supportsCatalogsInDataManipulation() {
0906:                return false;
0907:            }
0908:
0909:            /**
0910:             * Can a catalog name be used in a procedure call statement?
0911:             *
0912:             * @return true if so
0913:             * 
0914:             */
0915:            public boolean supportsCatalogsInProcedureCalls() {
0916:                return false;
0917:            }
0918:
0919:            /**
0920:             * Can a catalog name be used in a table definition statement?
0921:             *
0922:             * @return true if so
0923:             * 
0924:             */
0925:            public boolean supportsCatalogsInTableDefinitions() {
0926:                return false;
0927:            }
0928:
0929:            /**
0930:             * Can a catalog name be used in an index definition statement?
0931:             *
0932:             * @return true if so
0933:             */
0934:            public boolean supportsCatalogsInIndexDefinitions() {
0935:                return false;
0936:            }
0937:
0938:            /**
0939:             * Can a catalog name be used in a privilege definition statement?
0940:             *
0941:             * @return true if so
0942:             */
0943:            public boolean supportsCatalogsInPrivilegeDefinitions() {
0944:                return false;
0945:            }
0946:
0947:            /**
0948:             * Is positioned DELETE supported?
0949:             *
0950:             * @return true if so
0951:             */
0952:            public boolean supportsPositionedDelete() {
0953:                return true;
0954:            }
0955:
0956:            /**
0957:             * Is positioned UPDATE supported?
0958:             *
0959:             * @return true if so
0960:             */
0961:            public boolean supportsPositionedUpdate() {
0962:                return true;
0963:            }
0964:
0965:            /**
0966:             * Is SELECT for UPDATE supported?
0967:             *
0968:             * @return true if so
0969:             */
0970:            public boolean supportsSelectForUpdate() {
0971:                return true;
0972:            }
0973:
0974:            /**
0975:             * Are stored procedure calls using the stored procedure escape
0976:             * syntax supported?
0977:             *
0978:             * @return true if so
0979:             */
0980:            public boolean supportsStoredProcedures() {
0981:                return true;
0982:            }
0983:
0984:            /**
0985:             * Are subqueries in comparison expressions supported?
0986:             *
0987:             * A JDBC-Compliant driver always returns true.
0988:             *
0989:             * @return true if so
0990:             */
0991:            public boolean supportsSubqueriesInComparisons() {
0992:                return true;
0993:            }
0994:
0995:            /**
0996:             * Are subqueries in 'exists' expressions supported?
0997:             *
0998:             * A JDBC-Compliant driver always returns true.
0999:             *
1000:             * @return true if so
1001:             */
1002:            public boolean supportsSubqueriesInExists() {
1003:                return true;
1004:            }
1005:
1006:            /**
1007:             * Are subqueries in 'in' statements supported?
1008:             *
1009:             * A JDBC-Compliant driver always returns true.
1010:             *
1011:             * @return true if so
1012:             */
1013:            public boolean supportsSubqueriesInIns() {
1014:                return true;
1015:            }
1016:
1017:            /**
1018:             * Are subqueries in quantified expressions supported?
1019:             *
1020:             * A JDBC-Compliant driver always returns true.
1021:             *
1022:             * @return true if so
1023:             */
1024:            public boolean supportsSubqueriesInQuantifieds() {
1025:                return true;
1026:            }
1027:
1028:            /**
1029:             * Are correlated subqueries supported?
1030:             *
1031:             * A JDBC-Compliant driver always returns true.
1032:             *
1033:             * @return true if so
1034:             */
1035:            public boolean supportsCorrelatedSubqueries() {
1036:                return true;
1037:            }
1038:
1039:            /**
1040:             * Is SQL UNION supported?
1041:             *
1042:             * @return true if so
1043:             */
1044:            public boolean supportsUnion() {
1045:                return true;
1046:            }
1047:
1048:            /**
1049:             * Is SQL UNION ALL supported?
1050:             *
1051:             * @return true if so
1052:             */
1053:            public boolean supportsUnionAll() {
1054:                return true;
1055:            }
1056:
1057:            /**
1058:             * Can cursors remain open across commits?
1059:             *
1060:             * @return true if cursors always remain open; false if they might not remain open
1061:             */
1062:            //returns false because Derby does not support cursors that are open across commits for XA transactions.
1063:            public boolean supportsOpenCursorsAcrossCommit() {
1064:                return false;
1065:            }
1066:
1067:            /**
1068:             * Can cursors remain open across rollbacks?
1069:             *
1070:             * @return true if cursors always remain open; false if they might not remain open
1071:             */
1072:            public boolean supportsOpenCursorsAcrossRollback() {
1073:                return false;
1074:            }
1075:
1076:            /**
1077:             * Can statements remain open across commits?
1078:             *
1079:             * @return true if statements always remain open; false if they might not remain open
1080:             */
1081:            public boolean supportsOpenStatementsAcrossCommit() {
1082:                return true;
1083:            }
1084:
1085:            /**
1086:             * Can statements remain open across rollbacks?
1087:             *
1088:             * @return true if statements always remain open; false if they might not remain open
1089:             */
1090:            public boolean supportsOpenStatementsAcrossRollback() {
1091:                return false;
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:                // REMIND: This is hard-coded for the moment because it doesn't nicely
1329:                // fit within the framework we've set up for the rest of these values.
1330:                // Part of the reason is that it has a parameter, so it's not just a
1331:                // simple value look-up.  Some ideas for the future on how to make this
1332:                // not hard-coded:
1333:                //	  - code it as a query: "select true from <something> where ? in
1334:                //      (a,b,c)" where a,b,c are the supported isolation levels.  The
1335:                //      parameter would be set to "level".  This seems awfully awkward.
1336:                //    - somehow what you'd really like is to enable the instructions
1337:                //      file to contain the list, or set, of supported isolation
1338:                //      levels.  Something like:
1339:                //          supportsTr...ionLevel=SERIALIZABLE | REPEATABLE_READ | ...
1340:                //      That would take some more code that doesn't seem worthwhile at
1341:                //      the moment for this one case.
1342:
1343:                /*
1344:                	REMIND: this could be moved into a query that is e.g.
1345:                	VALUES ( ? in (8,...) )
1346:                	so that database could control the list of supported
1347:                	isolations.  For now, it's hard coded, and just the one.
1348:                 */
1349:
1350:                return (level == Connection.TRANSACTION_SERIALIZABLE
1351:                        || level == Connection.TRANSACTION_REPEATABLE_READ
1352:                        || level == Connection.TRANSACTION_READ_COMMITTED || level == Connection.TRANSACTION_READ_UNCOMMITTED);
1353:            }
1354:
1355:            /**
1356:             * Are both data definition and data manipulation statements
1357:             * within a transaction supported?
1358:             *
1359:             * @return true if so
1360:             */
1361:            public boolean supportsDataDefinitionAndDataManipulationTransactions() {
1362:                return true;
1363:            }
1364:
1365:            /**
1366:             * Are only data manipulation statements within a transaction
1367:             * supported?
1368:             *
1369:             * @return true if so
1370:             */
1371:            public boolean supportsDataManipulationTransactionsOnly() {
1372:                return false;
1373:            }
1374:
1375:            /**
1376:             * Does a data definition statement within a transaction force the
1377:             * transaction to commit?
1378:             *
1379:             * @return true if so
1380:             * 
1381:             */
1382:            public boolean dataDefinitionCausesTransactionCommit() {
1383:                return false;
1384:            }
1385:
1386:            /**
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:             * Get a description of stored procedures available in a
1398:             * catalog.
1399:             *
1400:             * <P>Only procedure descriptions matching the schema and
1401:             * procedure name criteria are returned.  They are ordered by
1402:             * PROCEDURE_SCHEM, and PROCEDURE_NAME.
1403:             *
1404:             * <P>Each procedure description has the the following columns:
1405:             *  <OL>
1406:             *	<LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)
1407:             *	<LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)
1408:             *	<LI><B>PROCEDURE_NAME</B> String => procedure name
1409:             *  <LI> reserved for future use
1410:             *  <LI> reserved for future use
1411:             *  <LI> reserved for future use
1412:             *	<LI><B>REMARKS</B> String => explanatory comment on the procedure
1413:             *	<LI><B>PROCEDURE_TYPE</B> short => kind of procedure:
1414:             *      <UL>
1415:             *      <LI> procedureResultUnknown - May return a result
1416:             *      <LI> procedureNoResult - Does not return a result
1417:             *      <LI> procedureReturnsResult - Returns a result
1418:             *      </UL>
1419:             *  <LI><B>SPECIFIC_NAME</B> String => The name which uniquely 
1420:             *  identifies this procedure within its schema (since JDBC 4.0)
1421:             *  </OL>
1422:             *
1423:             * @param catalog a catalog name; "" retrieves those without a
1424:             * catalog; null means drop catalog name from the selection criteria
1425:             * @param schemaPattern a schema name pattern; "" retrieves those
1426:             * without a schema
1427:             * @param procedureNamePattern a procedure name pattern
1428:             * @return ResultSet - each row is a procedure description
1429:             * @see #getSearchStringEscape
1430:             * @exception SQLException thrown on failure.
1431:             */
1432:            public ResultSet getProcedures(String catalog,
1433:                    String schemaPattern, String procedureNamePattern)
1434:                    throws SQLException {
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, procedureNamePattern,
1440:                        "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 getProceduresForODBC(String catalog,
1449:                    String schemaPattern, String procedureNamePattern)
1450:                    throws SQLException {
1451:
1452:                // For ODBC we still use the transformed version of the JDBC
1453:                // 3.0 query, (may change in the future).
1454:                return doGetProcs(catalog, schemaPattern, procedureNamePattern,
1455:                        "odbc_getProcedures");
1456:            }
1457:
1458:            /**
1459:             * Implements DatabaseMetaData.getFunctions() for an embedded
1460:             * database. Queries the database to get information about
1461:             * functions (procedures returning values). Executes the
1462:             * 'getFunctions' query from metadata.properties to obtain the
1463:             * ResultSet to return.<p> Compatibility: This is a new method in
1464:             * the API which is only available with with Derby versions > 10.1 and
1465:             * JDK versions >= 1.6 <p>Upgrade: Since this is a new query it
1466:             * does not have an SPS, and will be available as soon as any
1467:             * database, new or old, is booted with the new version of Derby,
1468:             * (in <b>soft and hard</b> upgrade).
1469:             * @param catalog limit the search to functions in this catalog 
1470:             * (not used)
1471:             * @param schemaPattern limit the search to functions in schemas 
1472:             * matching this pattern
1473:             * @param functionNamePattern limit the search to functions 
1474:             * matching this pattern
1475:             * @return a ResultSet with metadata information
1476:             * @throws SQLException if any of the underlying jdbc methods fail
1477:             */
1478:            public ResultSet getFunctions(java.lang.String catalog,
1479:                    java.lang.String schemaPattern,
1480:                    java.lang.String functionNamePattern) throws SQLException {
1481:                return doGetProcs(catalog, schemaPattern, functionNamePattern,
1482:                        "getFunctions");
1483:            }
1484:
1485:            /**
1486:             * Does the actual work for the getProcedures and getFunctions
1487:             * metadata calls.  See getProcedures() method above for parameter
1488:             * descriptions.
1489:             * @param queryName Name of the query to execute; is used
1490:             *	to determine whether the result set should conform to
1491:             *	JDBC or ODBC specifications.
1492:             */
1493:            private ResultSet doGetProcs(String catalog, String schemaPattern,
1494:                    String procedureNamePattern, String queryName)
1495:                    throws SQLException {
1496:
1497:                PreparedStatement s = getPreparedQuery(queryName);
1498:                s.setString(1, swapNull(catalog));
1499:                s.setString(2, swapNull(schemaPattern));
1500:                s.setString(3, swapNull(procedureNamePattern));
1501:                return s.executeQuery();
1502:            }
1503:
1504:            /**
1505:             * Get a description of a catalog's stored procedure parameters
1506:             * and result columns.
1507:             *
1508:             * <P>Only descriptions matching the schema, procedure and
1509:             * parameter name criteria are returned.  They are ordered by
1510:             * PROCEDURE_SCHEM and PROCEDURE_NAME. Within this, the return value,
1511:             * if any, is first. Next are the parameter descriptions in call
1512:             * order. The column descriptions follow in column number order.
1513:             *
1514:             * <P>Each row in the ResultSet is a parameter description or
1515:             * column description with the following fields:
1516:             *  <OL>
1517:             *	<LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)
1518:             *	<LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)
1519:             *	<LI><B>PROCEDURE_NAME</B> String => procedure name
1520:             *	<LI><B>COLUMN_NAME</B> String => column/parameter name
1521:             *	<LI><B>COLUMN_TYPE</B> Short => kind of column/parameter:
1522:             *      <UL>
1523:             *      <LI> procedureColumnUnknown - nobody knows
1524:             *      <LI> procedureColumnIn - IN parameter
1525:             *      <LI> procedureColumnInOut - INOUT parameter
1526:             *      <LI> procedureColumnOut - OUT parameter
1527:             *      <LI> procedureColumnReturn - procedure return value
1528:             *      <LI> procedureColumnResult - result column in ResultSet
1529:             *      </UL>
1530:             *  <LI><B>DATA_TYPE</B> int => SQL type from java.sql.Types
1531:             *	<LI><B>TYPE_NAME</B> String => SQL type name
1532:             *	<LI><B>PRECISION</B> int => precision
1533:             *	<LI><B>LENGTH</B> int => length in bytes of data
1534:             *	<LI><B>SCALE</B> short => scale
1535:             *	<LI><B>RADIX</B> short => radix
1536:             *	<LI><B>NULLABLE</B> short => can it contain NULL?
1537:             *      <UL>
1538:             *      <LI> procedureNoNulls - does not allow NULL values
1539:             *      <LI> procedureNullable - allows NULL values
1540:             *      <LI> procedureNullableUnknown - nullability unknown
1541:             *      </UL>
1542:             *	<LI><B>REMARKS</B> String => comment describing parameter/column
1543:             *	<LI><B>COLUMN_DEF</B> String
1544:             *	<LI><B>SQL_DATA_TYPE</B> int
1545:             *	<LI><B>SQL_DATETIME_SUB</B> int
1546:             *	<LI><B>CHAR_OCTET_LENGTH</B> int
1547:             *	<LI><B>ORDINAL_POSITION</B> int
1548:             *	<LI><B>IS_NULLABLE</B> String
1549:             *	<LI><B>SPECIFIC_NAME</B> String
1550:             *  </OL>
1551:             *
1552:             * <P><B>Note:</B> Some databases may not return the column
1553:             * descriptions for a procedure. Additional columns beyond
1554:             * SPECIFIC_NAME can be defined by the database.
1555:             *
1556:             * @param catalog a catalog name; "" retrieves those without a
1557:             * catalog; null means drop catalog name from the selection criteria
1558:             * @param schemaPattern a schema name pattern; "" retrieves those
1559:             * without a schema
1560:             * @param procedureNamePattern a procedure name pattern
1561:             * @param columnNamePattern a column name pattern
1562:             * @return ResultSet - each row is a stored procedure parameter or
1563:             *      column description
1564:             * @see #getSearchStringEscape
1565:             * @exception SQLException thrown on failure.
1566:             */
1567:            public ResultSet getProcedureColumns(String catalog,
1568:                    String schemaPattern, String procedureNamePattern,
1569:                    String columnNamePattern) throws SQLException {
1570:
1571:                // Using the new JDBC 4.0 version of the query here. The query
1572:                // was given a new name to allow the old query to
1573:                // be used by ODBCMetaDataGenerator.
1574:                return doGetProcCols(catalog, schemaPattern,
1575:                        procedureNamePattern, columnNamePattern,
1576:                        "getProcedureColumns40");
1577:            }
1578:
1579:            /**
1580:             * Get a description of a catalog's stored procedure parameters
1581:             * and result columns.  Same as getProcedureColumns() above,
1582:             * except that the result set will conform to ODBC specifications.
1583:             */
1584:            public ResultSet getProcedureColumnsForODBC(String catalog,
1585:                    String schemaPattern, String procedureNamePattern,
1586:                    String columnNamePattern) throws SQLException {
1587:
1588:                // For ODBC we still use the transformed version of the JDBC
1589:                // 3.0 query, (may change in the future).
1590:                return doGetProcCols(catalog, schemaPattern,
1591:                        procedureNamePattern, columnNamePattern,
1592:                        "odbc_getProcedureColumns");
1593:            }
1594:
1595:            /**
1596:             * Implements DatabaseMetaData.getFunctionColumns() for an embedded
1597:             * database. Queries the database to get information about
1598:             * function parameters. Executes the
1599:             * 'getFunctionColumns' query from metadata.properties to obtain the
1600:             * ResultSet.<p> Compatibility: This is a new method in
1601:             * the API which is only available with with Derby versions > 10.1 and
1602:             * JDK versions >= 1.6 <p>Upgrade: Since this is a new query it
1603:             * does not have an SPS, and will be available as soon as any
1604:             * database, new or old, is booted with the new version of Derby,
1605:             * (in <b>soft and hard</b> upgrade).
1606:             * @param catalog limit the search to functions in this catalog
1607:             * (not used)
1608:             * @param schemaPattern limit the search to functions in schemas
1609:             * matching this pattern
1610:             * @param functionNamePattern limit the search to functions
1611:             * matching this pattern
1612:             * @param parameterNamePattern limit the search parameters
1613:             * matching this pattern
1614:             * @return a ResultSet with metadata information
1615:             * @throws SQLException if a database error occurs
1616:             */
1617:            public ResultSet getFunctionColumns(String catalog,
1618:                    String schemaPattern, String functionNamePattern,
1619:                    String parameterNamePattern) throws SQLException {
1620:                PreparedStatement s = getPreparedQuery("getFunctionColumns");
1621:
1622:                // Cannot use doGetProcCols() because our query requires
1623:                // parameterNamePattern twice, because both LIKE and = is
1624:                // required to select parameters with an empty parameter
1625:                // name. That is, WHERE paramName LIKE ? will not match an
1626:                // empty paramName, but WHERE paramName LIKE ? OR paramName =
1627:                // ? will.
1628:                s.setString(1, swapNull(schemaPattern));
1629:                s.setString(2, swapNull(functionNamePattern));
1630:                s.setString(3, swapNull(parameterNamePattern));
1631:                s.setString(4, swapNull(parameterNamePattern));
1632:                return s.executeQuery();
1633:            }
1634:
1635:            /**
1636:             * Does the actual work for the getProcedureColumns metadata
1637:             * calls. See getProcedureColumns() method above for parameter
1638:             * descriptions.
1639:             * @param queryName Name of the query to execute; is used
1640:             *	to determine whether the result set should conform to
1641:             *	JDBC or ODBC specifications.
1642:             */
1643:            private ResultSet doGetProcCols(String catalog,
1644:                    String schemaPattern, String procedureNamePattern,
1645:                    String columnNamePattern, String queryName)
1646:                    throws SQLException {
1647:
1648:                PreparedStatement s = getPreparedQuery(queryName);
1649:                // 
1650:                // catalog is not part of the query
1651:                //
1652:                s.setString(1, swapNull(schemaPattern));
1653:                s.setString(2, swapNull(procedureNamePattern));
1654:                s.setString(3, swapNull(columnNamePattern));
1655:                return s.executeQuery();
1656:            }
1657:
1658:            /**
1659:             * Get a description of tables available in a catalog.
1660:             *
1661:             * <P>Only table descriptions matching the catalog, schema, table
1662:             * name and type criteria are returned.  They are ordered by
1663:             * TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.
1664:             *
1665:             * <P>Each table description has the following columns:
1666:             *  <OL>
1667:             *	<LI><B>TABLE_CAT</B> String => table catalog (may be null)
1668:             *	<LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1669:             *	<LI><B>TABLE_NAME</B> String => table name
1670:             *	<LI><B>TABLE_TYPE</B> String => table type.  Typical types are "TABLE",
1671:             *			"VIEW",	"SYSTEM TABLE", "GLOBAL TEMPORARY",
1672:             *			"LOCAL TEMPORARY", "ALIAS", "SYNONYM".
1673:             *	<LI><B>REMARKS</B> String => explanatory comment on the table
1674:             *  <LI><B>TYPE_CAT</B> String => the types catalog (may be
1675:             *          <code>null</code>)
1676:             *  <LI><B>TYPE_SCHEM</B> String => the types schema (may be
1677:             *          <code>null</code>)
1678:             *  <LI><B>TYPE_NAME</B> String => type name (may be
1679:             *          <code>null</code>)
1680:             *  <LI><B>SELF_REFERENCING_COL_NAME</B> String => name of the
1681:             *          designated "identifier" column of a typed table (may
1682:             *          be <code>null</code>)
1683:             *  <LI><B>REF_GENERATION</B> String => specifies how values in
1684:             *          SELF_REFERENCING_COL_NAME are created. Values are
1685:             *          "SYSTEM", "USER", "DERIVED". (may be
1686:             *          <code>null</code>)
1687:             *  </OL>
1688:             *
1689:             * <P><B>Note:</B> Some databases may not return information for
1690:             * all tables.
1691:             *
1692:             * @param catalog a catalog name; "" retrieves those without a
1693:             * catalog; null means drop catalog name from the selection criteria
1694:             * @param schemaPattern a schema name pattern; "" retrieves those
1695:             * without a schema
1696:             * @param tableNamePattern a table name pattern
1697:             * @param types a list of table types to include; null returns all types
1698:             * @return ResultSet - each row is a table description
1699:             * @see #getSearchStringEscape
1700:             * @exception SQLException thrown on failure.
1701:             */
1702:            public ResultSet getTables(String catalog, String schemaPattern,
1703:                    String tableNamePattern, String types[])
1704:                    throws SQLException {
1705:                synchronized (getConnectionSynchronization()) {
1706:                    setupContextStack();
1707:                    ResultSet rs = null;
1708:                    try {
1709:
1710:                        String queryText = getQueryDescriptions(false)
1711:                                .getProperty("getTables");
1712:
1713:                        /*
1714:                         * The query text is assumed to end with a "where" clause, so
1715:                         * that we can safely append
1716:                         * "and table_Type in ('xxx','yyy','zzz', ...)" and
1717:                         * have it become part of the where clause.
1718:                         *
1719:                         * Let's assume for now that the table type first char corresponds
1720:                         * to JBMS table type identifiers.
1721:                         */
1722:                        StringBuffer whereClauseTail = new StringBuffer(
1723:                                queryText);
1724:
1725:                        if (types != null && types.length >= 1) {
1726:                            whereClauseTail.append(" AND TABLETYPE IN ('");
1727:                            whereClauseTail.append(types[0].substring(0, 1));
1728:
1729:                            for (int i = 1; i < types.length; i++) {
1730:                                whereClauseTail.append("','");
1731:                                whereClauseTail
1732:                                        .append(types[i].substring(0, 1));
1733:                            }
1734:                            whereClauseTail.append("')");
1735:                        }
1736:                        // Add the order by clause after the 'in' list.
1737:                        whereClauseTail
1738:                                .append(" ORDER BY TABLE_TYPE, TABLE_SCHEM, TABLE_NAME");
1739:
1740:                        PreparedStatement s = getEmbedConnection()
1741:                                .prepareMetaDataStatement(
1742:                                        whereClauseTail.toString());
1743:
1744:                        s.setString(1, swapNull(catalog));
1745:                        s.setString(2, swapNull(schemaPattern));
1746:                        s.setString(3, swapNull(tableNamePattern));
1747:
1748:                        rs = s.executeQuery();
1749:                    } catch (Throwable t) {
1750:                        throw handleException(t);
1751:                    } finally {
1752:                        restoreContextStack();
1753:                    }
1754:
1755:                    return rs;
1756:                }
1757:            }
1758:
1759:            /**
1760:             * Get the schema names available in this database.  The results
1761:             * are ordered by schema name.
1762:             *
1763:             * <P>The schema columns are:
1764:             *  <OL>
1765:             *  <li><strong>TABLE_SCHEM</strong> String =&gt; schema name</li>
1766:             *  <li><strong>TABLE_CATALOG</strong> String =&gt; catalog name
1767:             *  (may be <code>null</code>)</li>
1768:             *  </OL>
1769:             *
1770:             * @return ResultSet - each row is a schema description
1771:             * @exception SQLException thrown on failure.
1772:             */
1773:            public ResultSet getSchemas() throws SQLException {
1774:                return getSchemas(null, null);
1775:            }
1776:
1777:            /**
1778:             * Get the catalog names available in this database.  The results
1779:             * are ordered by catalog name.
1780:             *
1781:             * <P>The catalog column is:
1782:             *  <OL>
1783:             *	<LI><B>TABLE_CAT</B> String => catalog name
1784:             *  </OL>
1785:             *
1786:             * @return ResultSet - each row has a single String column that is a
1787:             * catalog name
1788:             * @exception SQLException thrown on failure.
1789:             */
1790:            public ResultSet getCatalogs() throws SQLException {
1791:                return getSimpleQuery("getCatalogs");
1792:            }
1793:
1794:            /**
1795:             * Get the table types available in this database.  The results
1796:             * are ordered by table type.
1797:             *
1798:             * <P>The table type is:
1799:             *  <OL>
1800:             *	<LI><B>TABLE_TYPE</B> String => table type.  Typical types are "TABLE",
1801:             *			"VIEW",	"SYSTEM TABLE", "GLOBAL TEMPORARY",
1802:             *			"LOCAL TEMPORARY", "ALIAS", "SYNONYM".
1803:             *  </OL>
1804:             *
1805:             * @return ResultSet - each row has a single String column that is a
1806:             * table type
1807:             * @exception SQLException thrown on failure.
1808:             */
1809:            public ResultSet getTableTypes() throws SQLException {
1810:                return getSimpleQuery("getTableTypes");
1811:            }
1812:
1813:            /**
1814:             * Get a description of table columns available in a catalog.
1815:             *
1816:             * <P>Only column descriptions matching the catalog, schema, table
1817:             * and column name criteria are returned.  They are ordered by
1818:             * TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.
1819:             *
1820:             * <P>Each column description has the following columns:
1821:             *  <OL>
1822:             *	<LI><B>TABLE_CAT</B> String => table catalog (may be null)
1823:             *	<LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1824:             *	<LI><B>TABLE_NAME</B> String => table name
1825:             *	<LI><B>COLUMN_NAME</B> String => column name
1826:             *	<LI><B>DATA_TYPE</B> int => SQL type from java.sql.Types
1827:             *	<LI><B>TYPE_NAME</B> String => Data source dependent type name
1828:             *	<LI><B>COLUMN_SIZE</B> int => column size.  For char or date
1829:             *	    types this is the maximum number of characters, for numeric or
1830:             *	    decimal types this is precision.
1831:             *	<LI><B>BUFFER_LENGTH</B> is not used.
1832:             *	<LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits
1833:             *	<LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)
1834:             *	<LI><B>NULLABLE</B> int => is NULL allowed?
1835:             *      <UL>
1836:             *      <LI> columnNoNulls - might not allow NULL values
1837:             *      <LI> columnNullable - definitely allows NULL values
1838:             *      <LI> columnNullableUnknown - nullability unknown
1839:             *      </UL>
1840:             *	<LI><B>REMARKS</B> String => comment describing column (may be null)
1841:             * 	<LI><B>COLUMN_DEF</B> String => default value (may be null)
1842:             *	<LI><B>SQL_DATA_TYPE</B> int => unused
1843:             *	<LI><B>SQL_DATETIME_SUB</B> int => unused
1844:             *	<LI><B>CHAR_OCTET_LENGTH</B> int => for char types the
1845:             *       maximum number of bytes in the column
1846:             *	<LI><B>ORDINAL_POSITION</B> int	=> index of column in table
1847:             *      (starting at 1)
1848:             *	<LI><B>IS_NULLABLE</B> String => "NO" means column definitely
1849:             *      does not allow NULL values; "YES" means the column might
1850:             *      allow NULL values.  An empty string means nobody knows.
1851:             *  <LI><B>SCOPE_CATLOG</B> String => catalog of table that is the
1852:             *  scope of a reference attribute (<code>null</code> if DATA_TYPE
1853:             *  isn't REF)
1854:             *  <LI><B>SCOPE_SCHEMA</B> String => schema of table that is the
1855:             *  scope of a reference attribute (<code>null</code> if the
1856:             *  DATA_TYPE isn't REF)
1857:             *  <LI><B>SCOPE_TABLE</B> String => table name that this the
1858:             *  scope of a reference attribure (<code>null</code> if the
1859:             *  DATA_TYPE isn't REF)
1860:             *  <LI><B>SOURCE_DATA_TYPE</B> short => source type of a distinct
1861:             *  type or user-generated Ref type, SQL type from java.sql.Types
1862:             *  (<code>null</code> if DATA_TYPE isn't DISTINCT or
1863:             *  user-generated REF)
1864:             *  <LI><B>IS_AUTOINCREMENT</B> String => Indicates whether this
1865:             *  column is auto incremented
1866:             *  <UL>
1867:             *  <LI> YES --- if the column is auto incremented
1868:             *  <LI> NO --- if the column is not auto incremented
1869:             *  <LI> empty string --- if it cannot be determined whether the
1870:             *       column is auto incremented parameter is unknown
1871:             *  </UL>
1872:             *  </OL>
1873:             *
1874:             * @param catalog a catalog name; "" retrieves those without a
1875:             * catalog; null means drop catalog name from the selection criteria
1876:             * @param schemaPattern a schema name pattern; "" retrieves those
1877:             * without a schema
1878:             * @param tableNamePattern a table name pattern
1879:             * @param columnNamePattern a column name pattern
1880:             * @return ResultSet - each row is a column description
1881:             * @see #getSearchStringEscape
1882:             * @exception SQLException thrown on failure.
1883:             */
1884:            public ResultSet getColumns(String catalog, String schemaPattern,
1885:                    String tableNamePattern, String columnNamePattern)
1886:                    throws SQLException {
1887:
1888:                return doGetCols(catalog, schemaPattern, tableNamePattern,
1889:                        columnNamePattern, "getColumns");
1890:            }
1891:
1892:            /**
1893:             * Get a description of table columns available in a catalog.
1894:             * Same as getColumns() above, except that the result set
1895:             * will conform to ODBC specifications.
1896:             */
1897:            public ResultSet getColumnsForODBC(String catalog,
1898:                    String schemaPattern, String tableNamePattern,
1899:                    String columnNamePattern) throws SQLException {
1900:
1901:                return doGetCols(catalog, schemaPattern, tableNamePattern,
1902:                        columnNamePattern, "odbc_getColumns");
1903:            }
1904:
1905:            /**
1906:             * Does the actual work for the getColumns metadata calls.
1907:             * See getColumns() method above for parameter descriptions.
1908:             * @param queryName Name of the query to execute; is used
1909:             *	to determine whether the result set should conform to
1910:             *	JDBC or ODBC specifications.
1911:             */
1912:            private ResultSet doGetCols(String catalog, String schemaPattern,
1913:                    String tableNamePattern, String columnNamePattern,
1914:                    String queryName) throws SQLException {
1915:
1916:                PreparedStatement s = getPreparedQuery(queryName);
1917:                s.setString(1, swapNull(catalog));
1918:                s.setString(2, swapNull(schemaPattern));
1919:                s.setString(3, swapNull(tableNamePattern));
1920:                s.setString(4, swapNull(columnNamePattern));
1921:                return s.executeQuery();
1922:            }
1923:
1924:            /**
1925:             * Get a description of the access rights for a table's columns.
1926:             *
1927:             * <P>Only privileges matching the column name criteria are
1928:             * returned.  They are ordered by COLUMN_NAME and PRIVILEGE.
1929:             *
1930:             * <P>Each privilige description has the following columns:
1931:             *  <OL>
1932:             *	<LI><B>TABLE_CAT</B> String => table catalog (may be null)
1933:             *	<LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1934:             *	<LI><B>TABLE_NAME</B> String => table name
1935:             *	<LI><B>COLUMN_NAME</B> String => column name
1936:             *	<LI><B>GRANTOR</B> => grantor of access (may be null)
1937:             *	<LI><B>GRANTEE</B> String => grantee of access
1938:             *	<LI><B>PRIVILEGE</B> String => name of access (SELECT,
1939:             *      INSERT, UPDATE, REFRENCES, ...)
1940:             *	<LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
1941:             *      to grant to others; "NO" if not; null if unknown
1942:             *  </OL>
1943:             *
1944:             * @param catalog a catalog name; "" retrieves those without a
1945:             * catalog; null means drop catalog name from the selection criteria
1946:             * @param schema a schema name; "" retrieves those without a schema
1947:             * @param table a table name
1948:             * @param columnNamePattern a column name pattern
1949:             * @return ResultSet - each row is a column privilege description
1950:             * @see #getSearchStringEscape
1951:             * @exception SQLException thrown on failure.
1952:             */
1953:            public ResultSet getColumnPrivileges(String catalog, String schema,
1954:                    String table, String columnNamePattern) throws SQLException {
1955:                PreparedStatement s = getPreparedQuery("getColumnPrivileges");
1956:                s.setString(1, swapNull(catalog));
1957:                s.setString(2, swapNull(schema));
1958:                s.setString(3, swapNull(table));
1959:                s.setString(4, swapNull(columnNamePattern));
1960:                return s.executeQuery();
1961:            }
1962:
1963:            /**
1964:             * Get a description of the access rights for each table available
1965:             * in a catalog. Note that a table privilege applies to one or
1966:             * more columns in the table. It would be wrong to assume that
1967:             * this priviledge applies to all columns (this may be true for
1968:             * some systems but is not true for all.)
1969:             *
1970:             * <P>Only privileges matching the schema and table name
1971:             * criteria are returned.  They are ordered by TABLE_SCHEM,
1972:             * TABLE_NAME, and PRIVILEGE.
1973:             *
1974:             * <P>Each privilige description has the following columns:
1975:             *  <OL>
1976:             *	<LI><B>TABLE_CAT</B> String => table catalog (may be null)
1977:             *	<LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1978:             *	<LI><B>TABLE_NAME</B> String => table name
1979:             *	<LI><B>GRANTOR</B> => grantor of access (may be null)
1980:             *	<LI><B>GRANTEE</B> String => grantee of access
1981:             *	<LI><B>PRIVILEGE</B> String => name of access (SELECT,
1982:             *      INSERT, UPDATE, REFRENCES, ...)
1983:             *	<LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
1984:             *      to grant to others; "NO" if not; null if unknown
1985:             *  </OL>
1986:             *
1987:             * @param catalog a catalog name; "" retrieves those without a
1988:             * catalog; null means drop catalog name from the selection criteria
1989:             * @param schemaPattern a schema name pattern; "" retrieves those
1990:             * without a schema
1991:             * @param tableNamePattern a table name pattern
1992:             * @return ResultSet - each row is a table privilege description
1993:             * @see #getSearchStringEscape
1994:             * @exception SQLException thrown on failure.
1995:             */
1996:            public ResultSet getTablePrivileges(String catalog,
1997:                    String schemaPattern, String tableNamePattern)
1998:                    throws SQLException {
1999:                PreparedStatement s = getPreparedQuery("getTablePrivileges");
2000:                s.setString(1, swapNull(catalog));
2001:                s.setString(2, swapNull(schemaPattern));
2002:                s.setString(3, swapNull(tableNamePattern));
2003:                return s.executeQuery();
2004:            }
2005:
2006:            /**
2007:             * Get a description of a table's optimal set of columns that
2008:             * uniquely identifies a row. They are ordered by SCOPE.
2009:             *
2010:             * <P>Each column description has the following columns:
2011:             *  <OL>
2012:             *	<LI><B>SCOPE</B> short => actual scope of result
2013:             *      <UL>
2014:             *      <LI> bestRowTemporary - very temporary, while using row
2015:             *      <LI> bestRowTransaction - valid for remainder of current transaction
2016:             *      <LI> bestRowSession - valid for remainder of current session
2017:             *      </UL>
2018:             *	<LI><B>COLUMN_NAME</B> String => column name
2019:             *	<LI><B>DATA_TYPE</B> int => SQL data type from java.sql.Types
2020:             *	<LI><B>TYPE_NAME</B> String => Data source dependent type name
2021:             *	<LI><B>COLUMN_SIZE</B> int => precision
2022:             *	<LI><B>BUFFER_LENGTH</B> int => not used
2023:             *	<LI><B>DECIMAL_DIGITS</B> short	 => scale
2024:             *	<LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column
2025:             *      like an Oracle ROWID
2026:             *      <UL>
2027:             *      <LI> bestRowUnknown - may or may not be pseudo column
2028:             *      <LI> bestRowNotPseudo - is NOT a pseudo column
2029:             *      <LI> bestRowPseudo - is a pseudo column
2030:             *      </UL>
2031:             *  </OL>
2032:             *
2033:             * @param catalogPattern a catalog name; "" retrieves those without a
2034:             * catalog; null means drop catalog name from the selection criteria
2035:             * @param schemaPattern a schema name; "" retrieves those without a schema
2036:             * @param tablePattern a table name
2037:             * @param scope the scope of interest; use same values as SCOPE
2038:             * @param nullable include columns that are nullable?
2039:             * @return ResultSet - each row is a column description
2040:             * @exception SQLException thrown on failure.
2041:             */
2042:            public ResultSet getBestRowIdentifier(String catalogPattern,
2043:                    String schemaPattern, String tablePattern, int scope,
2044:                    boolean nullable) throws SQLException {
2045:                return doGetBestRowId(catalogPattern, schemaPattern,
2046:                        tablePattern, scope, nullable, "");
2047:            }
2048:
2049:            /**
2050:             * Get a description of a table's optimal set of columns that
2051:             * uniquely identifies a row. They are ordered by SCOPE.
2052:             * Same as getBestRowIdentifier() above, except that the result
2053:             * set will conform to ODBC specifications.
2054:             */
2055:            public ResultSet getBestRowIdentifierForODBC(String catalogPattern,
2056:                    String schemaPattern, String tablePattern, int scope,
2057:                    boolean nullable) throws SQLException {
2058:
2059:                return doGetBestRowId(catalogPattern, schemaPattern,
2060:                        tablePattern, scope, nullable, "odbc_");
2061:            }
2062:
2063:            /**
2064:             * Does the actual work for the getBestRowIdentifier metadata
2065:             * calls.  See getBestRowIdentifier() method above for parameter
2066:             * descriptions.
2067:             * @param queryPrefix Prefix to be appended to the names of
2068:             *	the queries used in this method.  This is used
2069:             *	to determine whether the result set should conform to
2070:             *	JDBC or ODBC specifications.
2071:             */
2072:            private ResultSet doGetBestRowId(String catalogPattern,
2073:                    String schemaPattern, String tablePattern, int scope,
2074:                    boolean nullable, String queryPrefix) throws SQLException {
2075:
2076:                int nullableInIntForm = 0;
2077:                if (nullable)
2078:                    nullableInIntForm = 1;
2079:
2080:                if (catalogPattern == null) {
2081:                    catalogPattern = "%";
2082:                }
2083:                if (schemaPattern == null) {
2084:                    schemaPattern = "%";
2085:                }
2086:                if (tablePattern == null) {
2087:                    tablePattern = "%";
2088:                }
2089:
2090:                PreparedStatement ps;
2091:                boolean done;
2092:
2093:                // scope value is bad, return an empty result
2094:                if (scope < 0 || scope > 2) {
2095:                    ps = getPreparedQuery("getBestRowIdentifierEmpty");
2096:                    return ps.executeQuery();
2097:                }
2098:
2099:                // see if there is a primary key, use it.
2100:                ps = getPreparedQuery("getBestRowIdentifierPrimaryKey");
2101:                ps.setString(1, catalogPattern);
2102:                ps.setString(2, schemaPattern);
2103:                ps.setString(3, tablePattern);
2104:
2105:                ResultSet rs = ps.executeQuery();
2106:                done = rs.next();
2107:                String constraintId = "";
2108:                if (done) {
2109:                    constraintId = rs.getString(1);
2110:                }
2111:
2112:                rs.close();
2113:                ps.close();
2114:
2115:                if (done) {
2116:                    // this one's it, do the real thing and return it.
2117:                    // we don't need to check catalog, schema, table name
2118:                    // or scope again.
2119:                    ps = getPreparedQuery(queryPrefix
2120:                            + "getBestRowIdentifierPrimaryKeyColumns");
2121:                    ps.setString(1, constraintId);
2122:                    ps.setString(2, constraintId);
2123:                    // note, primary key columns aren't nullable,
2124:                    // so we skip the nullOk parameter.
2125:                    return ps.executeQuery();
2126:                }
2127:
2128:                // get the unique constraint with the fewest columns.
2129:                ps = getPreparedQuery("getBestRowIdentifierUniqueConstraint");
2130:                ps.setString(1, catalogPattern);
2131:                ps.setString(2, schemaPattern);
2132:                ps.setString(3, tablePattern);
2133:
2134:                rs = ps.executeQuery();
2135:                done = rs.next();
2136:                if (done) {
2137:                    constraintId = rs.getString(1);
2138:                }
2139:                // REMIND: we need to actually check for null columns
2140:                // and toss out constraints with null columns if they aren't
2141:                // desired... recode this as a WHILE returning at the
2142:                // first match or falling off the end.
2143:
2144:                rs.close();
2145:                ps.close();
2146:                if (done) {
2147:                    // this one's it, do the real thing and return it.
2148:                    ps = getPreparedQuery(queryPrefix
2149:                            + "getBestRowIdentifierUniqueKeyColumns");
2150:                    ps.setString(1, constraintId);
2151:                    ps.setString(2, constraintId);
2152:                    ps.setInt(3, nullableInIntForm);
2153:                    return ps.executeQuery();
2154:                }
2155:
2156:                // second-to last try -- unique index with minimal # columns
2157:                // (only non null columns if so required)
2158:                ps = getPreparedQuery("getBestRowIdentifierUniqueIndex");
2159:                ps.setString(1, catalogPattern);
2160:                ps.setString(2, schemaPattern);
2161:                ps.setString(3, tablePattern);
2162:
2163:                rs = ps.executeQuery();
2164:                done = rs.next();
2165:                long indexNum = 0;
2166:                if (done) {
2167:                    indexNum = rs.getLong(1);
2168:                }
2169:                // REMIND: we need to actually check for null columns
2170:                // and toss out constraints with null columns if they aren't
2171:                // desired... recode this as a WHILE returning at the
2172:                // first match or falling off the end.
2173:
2174:                rs.close();
2175:                ps.close();
2176:                if (done) {
2177:                    // this one's it, do the real thing and return it.
2178:                    ps = getPreparedQuery(queryPrefix
2179:                            + "getBestRowIdentifierUniqueIndexColumns");
2180:                    ps.setLong(1, indexNum);
2181:                    ps.setInt(2, nullableInIntForm);
2182:                    return ps.executeQuery();
2183:                }
2184:
2185:                // last try -- just return all columns of the table
2186:                // the not null ones if that restriction is upon us.
2187:                ps = getPreparedQuery(queryPrefix
2188:                        + "getBestRowIdentifierAllColumns");
2189:                ps.setString(1, catalogPattern);
2190:                ps.setString(2, schemaPattern);
2191:                ps.setString(3, tablePattern);
2192:                ps.setInt(4, scope);
2193:                ps.setInt(5, nullableInIntForm);
2194:                return ps.executeQuery();
2195:            }
2196:
2197:            /**
2198:             * Get a description of a table's columns that are automatically
2199:             * updated when any value in a row is updated.  They are
2200:             * unordered.
2201:             *
2202:             * <P>Each column description has the following columns:
2203:             *  <OL>
2204:             *	<LI><B>SCOPE</B> short => is not used
2205:             *	<LI><B>COLUMN_NAME</B> String => column name
2206:             *	<LI><B>DATA_TYPE</B> int => SQL data type from java.sql.Types
2207:             *	<LI><B>TYPE_NAME</B> String => Data source dependent type name
2208:             *	<LI><B>COLUMN_SIZE</B> int => precision
2209:             *	<LI><B>BUFFER_LENGTH</B> int => length of column value in bytes
2210:             *	<LI><B>DECIMAL_DIGITS</B> short	 => scale
2211:             *	<LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column
2212:             *      like an Oracle ROWID
2213:             *      <UL>
2214:             *      <LI> versionColumnUnknown - may or may not be pseudo column
2215:             *      <LI> versionColumnNotPseudo - is NOT a pseudo column
2216:             *      <LI> versionColumnPseudo - is a pseudo column
2217:             *      </UL>
2218:             *  </OL>
2219:             *
2220:             * @param catalog a catalog name; "" retrieves those without a
2221:             * catalog; null means drop catalog name from the selection criteria
2222:             * @param schema a schema name; "" retrieves those without a schema
2223:             * @param table a table name
2224:             * @return ResultSet - each row is a column description
2225:             * @exception SQLException thrown on failure.
2226:             */
2227:            public ResultSet getVersionColumns(String catalog, String schema,
2228:                    String table) throws SQLException {
2229:                return doGetVersionCols(catalog, schema, table,
2230:                        "getVersionColumns");
2231:            }
2232:
2233:            /**
2234:             * Get a description of a table's columns that are automatically
2235:             * updated when any value in a row is updated.  They are
2236:             * unordered.  Same as getVersionColumns() above, except that
2237:             * the result set will conform to ODBC specifications.
2238:             */
2239:            public ResultSet getVersionColumnsForODBC(String catalog,
2240:                    String schema, String table) throws SQLException {
2241:                return doGetVersionCols(catalog, schema, table,
2242:                        "odbc_getVersionColumns");
2243:            }
2244:
2245:            /**
2246:             * Does the actual work for the getVersionColumns metadata
2247:             * calls.  See getVersionColumns() method above for parameter
2248:             * descriptions.
2249:             * @param queryName Name of the query to execute; is used
2250:             *	to determine whether the result set should conform to
2251:             *	JDBC or ODBC specifications.
2252:             */
2253:            private ResultSet doGetVersionCols(String catalog, String schema,
2254:                    String table, String queryName) throws SQLException {
2255:
2256:                PreparedStatement s = getPreparedQuery(queryName);
2257:                s.setString(1, swapNull(catalog));
2258:                s.setString(2, swapNull(schema));
2259:                s.setString(3, swapNull(table));
2260:                return s.executeQuery();
2261:            }
2262:
2263:            /**
2264:             * check if the dictionary is at the same version as the engine. If not, 
2265:             * then that means stored versions of the JDBC database metadata queries
2266:             * may not be compatible with this version of the software.
2267:             * This can happen if we are in soft upgrade mode. Since in soft upgrade 
2268:             * mode, we can't change these stored metadata queries in a backward 
2269:             * incompatible way, engine needs to read the metadata sql from 
2270:             * metadata.properties or metadata_net.properties file rather than
2271:             * rely on system tables.
2272:             * 
2273:             * @return true if we are not in soft upgrade mode
2274:             * @throws SQLException
2275:             */
2276:            private boolean notInSoftUpgradeMode() throws SQLException {
2277:                if (getEmbedConnection().isClosed())
2278:                    throw Util.noCurrentConnection();
2279:
2280:                boolean notInSoftUpgradeMode;
2281:                try {
2282:                    notInSoftUpgradeMode = getLanguageConnectionContext()
2283:                            .getDataDictionary().checkVersion(
2284:                                    DataDictionary.DD_VERSION_CURRENT, null);
2285:                } catch (Throwable t) {
2286:                    throw handleException(t);
2287:                }
2288:                return notInSoftUpgradeMode;
2289:            }
2290:
2291:            /**
2292:             * Get a description of a table's primary key columns.  They
2293:             * are ordered by COLUMN_NAME.
2294:             *
2295:             * <P>Each primary key column description has the following columns:
2296:             *  <OL>
2297:             *	<LI><B>TABLE_CAT</B> String => table catalog (may be null)
2298:             *	<LI><B>TABLE_SCHEM</B> String => table schema (may be null)
2299:             *	<LI><B>TABLE_NAME</B> String => table name
2300:             *	<LI><B>COLUMN_NAME</B> String => column name
2301:             *	<LI><B>KEY_SEQ</B> short => sequence number within primary key
2302:             *	<LI><B>PK_NAME</B> String => primary key name (may be null)
2303:             *  </OL>
2304:             *
2305:             * @param catalog a catalog name; "" retrieves those without a
2306:             * catalog; null means drop catalog name from the selection criteria
2307:             * @param schema a schema name pattern; "" retrieves those
2308:             * without a schema
2309:             * @param table a table name
2310:             * @return ResultSet - each row is a primary key column description
2311:             * @exception SQLException thrown on failure.
2312:             */
2313:            public ResultSet getPrimaryKeys(String catalog, String schema,
2314:                    String table) throws SQLException {
2315:                PreparedStatement s = getPreparedQuery("getPrimaryKeys");
2316:                s.setString(1, swapNull(catalog));
2317:                s.setString(2, swapNull(schema));
2318:                s.setString(3, swapNull(table));
2319:                return s.executeQuery();
2320:            }
2321:
2322:            /**
2323:             * Get a description of the primary key columns that are
2324:             * referenced by a table's foreign key columns (the primary keys
2325:             * imported by a table).  They are ordered by PKTABLE_CAT,
2326:             * PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ.
2327:             *
2328:             * <P>Each primary key column description has the following columns:
2329:             *  <OL>
2330:             *	<LI><B>PKTABLE_CAT</B> String => primary key table catalog
2331:             *      being imported (may be null)
2332:             *	<LI><B>PKTABLE_SCHEM</B> String => primary key table schema
2333:             *      being imported (may be null)
2334:             *	<LI><B>PKTABLE_NAME</B> String => primary key table name
2335:             *      being imported
2336:             *	<LI><B>PKCOLUMN_NAME</B> String => primary key column name
2337:             *      being imported
2338:             *	<LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
2339:             *	<LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
2340:             *	<LI><B>FKTABLE_NAME</B> String => foreign key table name
2341:             *	<LI><B>FKCOLUMN_NAME</B> String => foreign key column name
2342:             *	<LI><B>KEY_SEQ</B> short => sequence number within foreign key
2343:             *	<LI><B>UPDATE_RULE</B> short => What happens to
2344:             *       foreign key when primary is updated:
2345:             *      <UL>
2346:             *      <LI> importedNoAction - do not allow update of primary
2347:             *               key if it has been imported
2348:             *      <LI> importedKeyCascade - change imported key to agree
2349:             *               with primary key update
2350:             *      <LI> importedKeySetNull - change imported key to NULL if
2351:             *               its primary key has been updated
2352:             *      <LI> importedKeySetDefault - change imported key to default values
2353:             *               if its primary key has been updated
2354:             *      <LI> importedKeyRestrict - same as importedKeyNoAction
2355:             *                                 (for ODBC 2.x compatibility)
2356:             *      </UL>
2357:             *	<LI><B>DELETE_RULE</B> short => What happens to
2358:             *      the foreign key when primary is deleted.
2359:             *      <UL>
2360:             *      <LI> importedKeyNoAction - do not allow delete of primary
2361:             *               key if it has been imported
2362:             *      <LI> importedKeyCascade - delete rows that import a deleted key
2363:             *      <LI> importedKeySetNull - change imported key to NULL if
2364:             *               its primary key has been deleted
2365:             *      <LI> importedKeyRestrict - same as importedKeyNoAction
2366:             *                                 (for ODBC 2.x compatibility)
2367:             *      <LI> importedKeySetDefault - change imported key to default if
2368:             *               its primary key has been deleted
2369:             *      </UL>
2370:             *	<LI><B>FK_NAME</B> String => foreign key name (may be null)
2371:             *	<LI><B>PK_NAME</B> String => primary key name (may be null)
2372:             *	<LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
2373:             *      constraints be deferred until commit
2374:             *      <UL>
2375:             *      <LI> importedKeyInitiallyDeferred - see SQL92 for definition
2376:             *      <LI> importedKeyInitiallyImmediate - see SQL92 for definition
2377:             *      <LI> importedKeyNotDeferrable - see SQL92 for definition
2378:             *      </UL>
2379:             *  </OL>
2380:             *
2381:             * @param catalog a catalog name; "" retrieves those without a
2382:             * catalog; null means drop catalog name from the selection criteria
2383:             * @param schema a schema name pattern; "" retrieves those
2384:             * without a schema
2385:             * @param table a table name
2386:             * @return ResultSet - each row is a primary key column description
2387:             * @see #getExportedKeys
2388:             * @exception SQLException thrown on failure.
2389:             */
2390:            public ResultSet getImportedKeys(String catalog, String schema,
2391:                    String table) throws SQLException {
2392:                PreparedStatement s = getPreparedQuery("getImportedKeys");
2393:                s.setString(1, swapNull(catalog));
2394:                s.setString(2, swapNull(schema));
2395:                s.setString(3, swapNull(table));
2396:                return s.executeQuery();
2397:            }
2398:
2399:            /**
2400:             * Get a description of the foreign key columns that reference a
2401:             * table's primary key columns (the foreign keys exported by a
2402:             * table).  They are ordered by FKTABLE_CAT, FKTABLE_SCHEM,
2403:             * FKTABLE_NAME, and KEY_SEQ.
2404:             *
2405:             * <P>Each foreign key column description has the following columns:
2406:             *  <OL>
2407:             *	<LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)
2408:             *	<LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)
2409:             *	<LI><B>PKTABLE_NAME</B> String => primary key table name
2410:             *	<LI><B>PKCOLUMN_NAME</B> String => primary key column name
2411:             *	<LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
2412:             *      being exported (may be null)
2413:             *	<LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
2414:             *      being exported (may be null)
2415:             *	<LI><B>FKTABLE_NAME</B> String => foreign key table name
2416:             *      being exported
2417:             *	<LI><B>FKCOLUMN_NAME</B> String => foreign key column name
2418:             *      being exported
2419:             *	<LI><B>KEY_SEQ</B> short => sequence number within foreign key
2420:             *	<LI><B>UPDATE_RULE</B> short => What happens to
2421:             *       foreign key when primary is updated:
2422:             *      <UL>
2423:             *      <LI> importedNoAction - do not allow update of primary
2424:             *               key if it has been imported
2425:             *      <LI> importedKeyCascade - change imported key to agree
2426:             *               with primary key update
2427:             *      <LI> importedKeySetNull - change imported key to NULL if
2428:             *               its primary key has been updated
2429:             *      <LI> importedKeySetDefault - change imported key to default values
2430:             *               if its primary key has been updated
2431:             *      <LI> importedKeyRestrict - same as importedKeyNoAction
2432:             *                                 (for ODBC 2.x compatibility)
2433:             *      </UL>
2434:             *	<LI><B>DELETE_RULE</B> short => What happens to
2435:             *      the foreign key when primary is deleted.
2436:             *      <UL>
2437:             *      <LI> importedKeyNoAction - do not allow delete of primary
2438:             *               key if it has been imported
2439:             *      <LI> importedKeyCascade - delete rows that import a deleted key
2440:             *      <LI> importedKeySetNull - change imported key to NULL if
2441:             *               its primary key has been deleted
2442:             *      <LI> importedKeyRestrict - same as importedKeyNoAction
2443:             *                                 (for ODBC 2.x compatibility)
2444:             *      <LI> importedKeySetDefault - change imported key to default if
2445:             *               its primary key has been deleted
2446:             *      </UL>
2447:             *	<LI><B>FK_NAME</B> String => foreign key name (may be null)
2448:             *	<LI><B>PK_NAME</B> String => primary key name (may be null)
2449:             *	<LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
2450:             *      constraints be deferred until commit
2451:             *      <UL>
2452:             *      <LI> importedKeyInitiallyDeferred - see SQL92 for definition
2453:             *      <LI> importedKeyInitiallyImmediate - see SQL92 for definition
2454:             *      <LI> importedKeyNotDeferrable - see SQL92 for definition
2455:             *      </UL>
2456:             *  </OL>
2457:             *
2458:             * @param catalog a catalog name; "" retrieves those without a
2459:             * catalog; null means drop catalog name from the selection criteria
2460:             * @param schema a schema name pattern; "" retrieves those
2461:             * without a schema
2462:             * @param table a table name
2463:             * @return ResultSet - each row is a foreign key column description
2464:             * @see #getImportedKeys
2465:             * @exception SQLException thrown on failure.
2466:             */
2467:            public ResultSet getExportedKeys(String catalog, String schema,
2468:                    String table) throws SQLException {
2469:                PreparedStatement s = getPreparedQuery("getCrossReference");
2470:                s.setString(1, swapNull(catalog));
2471:                s.setString(2, swapNull(schema));
2472:                s.setString(3, swapNull(table));
2473:                s.setString(4, swapNull(null));
2474:                s.setString(5, swapNull(null));
2475:                s.setString(6, swapNull(null));
2476:                return s.executeQuery();
2477:            }
2478:
2479:            /**
2480:             * Get a description of the foreign key columns in the foreign key
2481:             * table that reference the primary key columns of the primary key
2482:             * table (describe how one table imports another's key.) This
2483:             * should normally return a single foreign key/primary key pair
2484:             * (most tables only import a foreign key from a table once.)  They
2485:             * are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and
2486:             * KEY_SEQ.
2487:             *
2488:             * <P>Each foreign key column description has the following columns:
2489:             *  <OL>
2490:             *	<LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)
2491:             *	<LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)
2492:             *	<LI><B>PKTABLE_NAME</B> String => primary key table name
2493:             *	<LI><B>PKCOLUMN_NAME</B> String => primary key column name
2494:             *	<LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
2495:             *      being exported (may be null)
2496:             *	<LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
2497:             *      being exported (may be null)
2498:             *	<LI><B>FKTABLE_NAME</B> String => foreign key table name
2499:             *      being exported
2500:             *	<LI><B>FKCOLUMN_NAME</B> String => foreign key column name
2501:             *      being exported
2502:             *	<LI><B>KEY_SEQ</B> short => sequence number within foreign key
2503:             *	<LI><B>UPDATE_RULE</B> short => What happens to
2504:             *       foreign key when primary is updated:
2505:             *      <UL>
2506:             *      <LI> importedNoAction - do not allow update of primary
2507:             *               key if it has been imported
2508:             *      <LI> importedKeyCascade - change imported key to agree
2509:             *               with primary key update
2510:             *      <LI> importedKeySetNull - change imported key to NULL if
2511:             *               its primary key has been updated
2512:             *      <LI> importedKeySetDefault - change imported key to default values
2513:             *               if its primary key has been updated
2514:             *      <LI> importedKeyRestrict - same as importedKeyNoAction
2515:             *                                 (for ODBC 2.x compatibility)
2516:             *      </UL>
2517:             *	<LI><B>DELETE_RULE</B> short => What happens to
2518:             *      the foreign key when primary is deleted.
2519:             *      <UL>
2520:             *      <LI> importedKeyNoAction - do not allow delete of primary
2521:             *               key if it has been imported
2522:             *      <LI> importedKeyCascade - delete rows that import a deleted key
2523:             *      <LI> importedKeySetNull - change imported key to NULL if
2524:             *               its primary key has been deleted
2525:             *      <LI> importedKeyRestrict - same as importedKeyNoAction
2526:             *                                 (for ODBC 2.x compatibility)
2527:             *      <LI> importedKeySetDefault - change imported key to default if
2528:             *               its primary key has been deleted
2529:             *      </UL>
2530:             *	<LI><B>FK_NAME</B> String => foreign key name (may be null)
2531:             *	<LI><B>PK_NAME</B> String => primary key name (may be null)
2532:             *	<LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
2533:             *      constraints be deferred until commit
2534:             *      <UL>
2535:             *      <LI> importedKeyInitiallyDeferred - see SQL92 for definition
2536:             *      <LI> importedKeyInitiallyImmediate - see SQL92 for definition
2537:             *      <LI> importedKeyNotDeferrable - see SQL92 for definition
2538:             *      </UL>
2539:             *  </OL>
2540:             *
2541:             * @param primaryCatalog a catalog name; "" retrieves those without a
2542:             * catalog; null means drop catalog name from the selection criteria
2543:             * @param primarySchema a schema name pattern; "" retrieves those
2544:             * without a schema
2545:             * @param primaryTable the table name that exports the key
2546:             * @param foreignCatalog a catalog name; "" retrieves those without a
2547:             * catalog; null means drop catalog name from the selection criteria
2548:             * @param foreignSchema a schema name pattern; "" retrieves those
2549:             * without a schema
2550:             * @param foreignTable the table name that imports the key
2551:             * @return ResultSet - each row is a foreign key column description
2552:             * @see #getImportedKeys
2553:             * @exception SQLException thrown on failure.
2554:             */
2555:            public ResultSet getCrossReference(String primaryCatalog,
2556:                    String primarySchema, String primaryTable,
2557:                    String foreignCatalog, String foreignSchema,
2558:                    String foreignTable) throws SQLException {
2559:                PreparedStatement s = getPreparedQuery("getCrossReference");
2560:                s.setString(1, swapNull(primaryCatalog));
2561:                s.setString(2, swapNull(primarySchema));
2562:                s.setString(3, swapNull(primaryTable));
2563:                s.setString(4, swapNull(foreignCatalog));
2564:                s.setString(5, swapNull(foreignSchema));
2565:                s.setString(6, swapNull(foreignTable));
2566:                return s.executeQuery();
2567:            }
2568:
2569:            /**
2570:             * Get a description of all the standard SQL types supported by
2571:             * this database. They are ordered by DATA_TYPE and then by how
2572:             * closely the data type maps to the corresponding JDBC SQL type.
2573:             *
2574:             * <P>Each type description has the following columns:
2575:             *  <OL>
2576:             *	<LI><B>TYPE_NAME</B> String => Type name
2577:             *	<LI><B>DATA_TYPE</B> int => SQL data type from java.sql.Types
2578:             *	<LI><B>PRECISION</B> int => maximum precision
2579:             *	<LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal
2580:             *      (may be null)
2581:             *	<LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal
2582:                    (may be null)
2583:             *	<LI><B>CREATE_PARAMS</B> String => parameters used in creating
2584:             *      the type (may be null)
2585:             *	<LI><B>NULLABLE</B> short => can you use NULL for this type?
2586:             *      <UL>
2587:             *      <LI> typeNoNulls - does not allow NULL values
2588:             *      <LI> typeNullable - allows NULL values
2589:             *      <LI> typeNullableUnknown - nullability unknown
2590:             *      </UL>
2591:             *	<LI><B>CASE_SENSITIVE</B> boolean=> is it case sensitive?
2592:             *	<LI><B>SEARCHABLE</B> short => can you use "WHERE" based on this type:
2593:             *      <UL>
2594:             *      <LI> typePredNone - No support
2595:             *      <LI> typePredChar - Only supported with WHERE .. LIKE
2596:             *      <LI> typePredBasic - Supported except for WHERE .. LIKE
2597:             *      <LI> typeSearchable - Supported for all WHERE ..
2598:             *      </UL>
2599:             *	<LI><B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned?
2600:             *	<LI><B>FIXED_PREC_SCALE</B> boolean => can it be a money value?
2601:             *	<LI><B>AUTO_INCREMENT</B> boolean => can it be used for an
2602:             *      auto-increment value?
2603:             *	<LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name
2604:             *      (may be null)
2605:             *	<LI><B>MINIMUM_SCALE</B> short => minimum scale supported
2606:             *	<LI><B>MAXIMUM_SCALE</B> short => maximum scale supported
2607:             *	<LI><B>SQL_DATA_TYPE</B> int => unused
2608:             *	<LI><B>SQL_DATETIME_SUB</B> int => unused
2609:             *	<LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10
2610:             *  </OL>
2611:             *
2612:             * @return ResultSet - each row is a SQL type description
2613:             * @exception SQLException thrown on failure.
2614:             */
2615:            public ResultSet getTypeInfo() throws SQLException {
2616:                return getSimpleQuery("getTypeInfo");
2617:            }
2618:
2619:            /**
2620:             * Get a description of all the standard SQL types supported by
2621:             * this database. They are ordered by DATA_TYPE and then by how
2622:             * closely the data type maps to the corresponding JDBC SQL type.
2623:             * Same as getTypeInfo above, except that the result set will
2624:             * conform to ODBC specifications.
2625:             */
2626:            public ResultSet getTypeInfoForODBC() throws SQLException {
2627:                return getSimpleQuery("odbc_getTypeInfo");
2628:            }
2629:
2630:            /**
2631:             * Get a description of a table's indices and statistics. They are
2632:             * ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.
2633:             *
2634:             * <P>Each index column description has the following columns:
2635:             *  <OL>
2636:             *	<LI><B>TABLE_CAT</B> String => table catalog (may be null)
2637:             *	<LI><B>TABLE_SCHEM</B> String => table schema (may be null)
2638:             *	<LI><B>TABLE_NAME</B> String => table name
2639:             *	<LI><B>NON_UNIQUE</B> boolean => Can index values be non-unique?
2640:             *      false when TYPE is tableIndexStatistic
2641:             *	<LI><B>INDEX_QUALIFIER</B> String => index catalog (may be null);
2642:             *      null when TYPE is tableIndexStatistic
2643:             *	<LI><B>INDEX_NAME</B> String => index name; null when TYPE is
2644:             *      tableIndexStatistic
2645:             *	<LI><B>TYPE</B> short => index type:
2646:             *      <UL>
2647:             *      <LI> tableIndexStatistic - this identifies table statistics that are
2648:             *           returned in conjuction with a table's index descriptions
2649:             *      <LI> tableIndexClustered - this is a clustered index
2650:             *      <LI> tableIndexHashed - this is a hashed index
2651:             *      <LI> tableIndexOther - this is some other style of index
2652:             *      </UL>
2653:             *	<LI><B>ORDINAL_POSITION</B> short => column sequence number
2654:             *      within index; zero when TYPE is tableIndexStatistic
2655:             *	<LI><B>COLUMN_NAME</B> String => column name; null when TYPE is
2656:             *      tableIndexStatistic
2657:             *	<LI><B>ASC_OR_DESC</B> String => column sort sequence, "A" => ascending,
2658:             *      "D" => descending, may be null if sort sequence is not supported;
2659:             *      null when TYPE is tableIndexStatistic
2660:             *	<LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatistic, then
2661:             *      this is the number of rows in the table; otherwise, it is the
2662:             *      number of unique values in the index.
2663:             *	<LI><B>PAGES</B> int => When TYPE is  tableIndexStatisic then
2664:             *      this is the number of pages used for the table, otherwise it
2665:             *      is the number of pages used for the current index.
2666:             *	<LI><B>FILTER_CONDITION</B> String => Filter condition, if any.
2667:             *      (may be null)
2668:             *  </OL>
2669:             *
2670:             * @param catalog a catalog name; "" retrieves those without a
2671:             * catalog; null means drop catalog name from the selection criteria
2672:             * @param schema a schema name pattern; "" retrieves those without a schema
2673:             * @param table a table name
2674:             * @param unique when true, return only indices for unique values;
2675:             *     when false, return indices regardless of whether unique or not
2676:             * @param approximate when true, result is allowed to reflect approximate
2677:             *     or out of data values; when false, results are requested to be
2678:             *     accurate
2679:             * @return ResultSet - each row is an index column description
2680:             * @exception SQLException thrown on failure.
2681:             */
2682:            public ResultSet getIndexInfo(String catalog, String schema,
2683:                    String table, boolean unique, boolean approximate)
2684:                    throws SQLException {
2685:                return doGetIndexInfo(catalog, schema, table, unique,
2686:                        approximate, "getIndexInfo");
2687:            }
2688:
2689:            /**
2690:             * Get a description of a table's indices and statistics. They are
2691:             * ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.
2692:             * Same as getIndexInfo above, except that the result set will
2693:             * conform to ODBC specifications.
2694:             */
2695:            public ResultSet getIndexInfoForODBC(String catalog, String schema,
2696:                    String table, boolean unique, boolean approximate)
2697:                    throws SQLException {
2698:                return doGetIndexInfo(catalog, schema, table, unique,
2699:                        approximate, "odbc_getIndexInfo");
2700:            }
2701:
2702:            /**
2703:             * Does the actual work for the getIndexInfo metadata
2704:             * calls.  See getIndexInfo() method above for parameter
2705:             * descriptions.
2706:             * @param queryName Name of the query to execute; is used
2707:             *	to determine whether the result set should conform to
2708:             *	JDBC or ODBC specifications.
2709:             */
2710:            private ResultSet doGetIndexInfo(String catalog, String schema,
2711:                    String table, boolean unique, boolean approximate,
2712:                    String queryName) throws SQLException {
2713:
2714:                int approximateInInt = 0;
2715:                if (approximate)
2716:                    approximateInInt = 1;
2717:                PreparedStatement s = getPreparedQuery(queryName);
2718:                s.setString(1, swapNull(catalog));
2719:                s.setString(2, swapNull(schema));
2720:                s.setString(3, swapNull(table));
2721:                s.setBoolean(4, unique);
2722:                s.setInt(5, approximateInInt);
2723:                return s.executeQuery();
2724:            }
2725:
2726:            /////////////////////////////////////////////////////////////////////////
2727:            //
2728:            //	JDBC 2.0	-	New public methods
2729:            //
2730:            /////////////////////////////////////////////////////////////////////////
2731:
2732:            /**
2733:             * JDBC 2.0
2734:             *
2735:             * Does the database support the given result set type?
2736:             *
2737:             * @param type defined in java.sql.ResultSet
2738:             * @return true if so 
2739:             * @see Connection
2740:             */
2741:            public boolean supportsResultSetType(int type) {
2742:                if ((type == JDBC20Translation.TYPE_FORWARD_ONLY)
2743:                        || (type == JDBC20Translation.TYPE_SCROLL_INSENSITIVE)) {
2744:                    return true;
2745:                }
2746:                //we don't support TYPE_SCROLL_SENSITIVE yet.
2747:                return false;
2748:            }
2749:
2750:            /**
2751:             * JDBC 2.0
2752:             *
2753:             * Does the database support the concurrency type in combination
2754:             * with the given result set type?
2755:             *
2756:             * @param type defined in java.sql.ResultSet
2757:             * @param concurrency type defined in java.sql.ResultSet
2758:             * @return true if so 
2759:             * @see Connection
2760:             */
2761:            public boolean supportsResultSetConcurrency(int type,
2762:                    int concurrency) {
2763:                if (type == JDBC20Translation.TYPE_SCROLL_SENSITIVE) {
2764:                    // (TYPE_SCROLL_SENSITIVE, *)
2765:                    return false;
2766:                } else {
2767:                    // (FORWARD_ONLY, CONCUR_UPDATABLE)
2768:                    // (FORWARD_ONLY, CONCUR_READ_ONLY)
2769:                    // (TYPE_SCROLL_INSENSITIVE, CONCUR_UPDATABLE)
2770:                    // (TYPE_SCROLL_INSENSITIVE, READ_ONLY)
2771:                    return true;
2772:                }
2773:            }
2774:
2775:            /**
2776:             * JDBC 2.0
2777:             *
2778:             * Determine whether a result set's updates are visible.
2779:             *
2780:             * @param type result set type, i.e. ResultSet.TYPE_XXX
2781:             * @return true if updates are visible for the result set type
2782:             */
2783:            public boolean ownUpdatesAreVisible(int type) {
2784:                if (type == JDBC20Translation.TYPE_SCROLL_INSENSITIVE) {
2785:                    return true;
2786:                } else {
2787:                    return false;
2788:                }
2789:            }
2790:
2791:            /**
2792:             * JDBC 2.0
2793:             *
2794:             * Determine whether a result set's deletes are visible.
2795:             *
2796:             * @param type result set type, i.e. ResultSet.TYPE_XXX
2797:             * @return true if deletes are visible for the result set type
2798:             */
2799:            public boolean ownDeletesAreVisible(int type) {
2800:                if (type == JDBC20Translation.TYPE_SCROLL_INSENSITIVE) {
2801:                    return true;
2802:                } else {
2803:                    return false;
2804:                }
2805:            }
2806:
2807:            /**
2808:             * JDBC 2.0
2809:             *
2810:             * Determine whether a result set's inserts are visible.
2811:             *
2812:             * @param type result set type, i.e. ResultSet.TYPE_XXX
2813:             * @return true if inserts are visible for the result set type
2814:             */
2815:            public boolean ownInsertsAreVisible(int type) {
2816:                return false;
2817:            }
2818:
2819:            // Since Derby materializes a forward only ResultSet incrementally, it is 
2820:            // possible to see changes made by others and hence following 3 metadata 
2821:            // calls will return true for forward only ResultSets.
2822:
2823:            /**
2824:             * JDBC 2.0
2825:             *
2826:             * Determine whether updates made by others are visible.
2827:             *
2828:             * @param type result set type, i.e. ResultSet.TYPE_XXX
2829:             * @return true if updates are visible for the result set type
2830:             */
2831:            public boolean othersUpdatesAreVisible(int type) {
2832:                if (type == JDBC20Translation.TYPE_FORWARD_ONLY)
2833:                    return true;
2834:                return false;
2835:            }
2836:
2837:            /**
2838:             * JDBC 2.0
2839:             *
2840:             * Determine whether deletes made by others are visible.
2841:             *
2842:             * @param type result set type, i.e. ResultSet.TYPE_XXX
2843:             * @return true if deletes are visible for the result set type
2844:             */
2845:            public boolean othersDeletesAreVisible(int type) {
2846:                if (type == JDBC20Translation.TYPE_FORWARD_ONLY)
2847:                    return true;
2848:                return false;
2849:            }
2850:
2851:            /**
2852:             * JDBC 2.0
2853:             *
2854:             * Determine whether inserts made by others are visible.
2855:             *
2856:             * @param type result set type, i.e. ResultSet.TYPE_XXX
2857:             * @return true if inserts are visible for the result set type
2858:             */
2859:            public boolean othersInsertsAreVisible(int type) {
2860:                if (type == JDBC20Translation.TYPE_FORWARD_ONLY)
2861:                    return true;
2862:                return false;
2863:            }
2864:
2865:            /**
2866:             * JDBC 2.0
2867:             *
2868:             * Determine whether or not a visible row update can be detected by 
2869:             * calling ResultSet.rowUpdated().
2870:             *
2871:             * @param type result set type, i.e. ResultSet.TYPE_XXX
2872:             * @return true if updates are detected by the resultset type
2873:             */
2874:            public boolean updatesAreDetected(int type) {
2875:                if (type == JDBC20Translation.TYPE_SCROLL_INSENSITIVE) {
2876:                    return true;
2877:                } else {
2878:                    // For forward only resultsets, we move to before the next
2879:                    // row after a update and that is why updatesAreDetected
2880:                    // returns false.
2881:                    return false;
2882:                }
2883:            }
2884:
2885:            /**
2886:             * JDBC 2.0
2887:             *
2888:             * Determine whether or not a visible row delete can be detected by
2889:             * calling ResultSet.rowDeleted().  If deletesAreDetected()
2890:             * returns false, then deleted rows are removed from the result set.
2891:             *
2892:             * @param type result set type, i.e. ResultSet.TYPE_XXX
2893:             * @return true if deletes are detected by the resultset type
2894:             */
2895:            public boolean deletesAreDetected(int type) {
2896:                if (type == JDBC20Translation.TYPE_SCROLL_INSENSITIVE) {
2897:                    return true;
2898:                } else {
2899:                    // For forward only resultsets, we move to before the next
2900:                    // row after a delete and that is why deletesAreDetected
2901:                    // returns false
2902:                    return false;
2903:                }
2904:            }
2905:
2906:            /**
2907:             * JDBC 2.0
2908:             *
2909:             * Determine whether or not a visible row insert can be detected
2910:             * by calling ResultSet.rowInserted().
2911:             *
2912:             * @param type result set type, i.e. ResultSet.TYPE_XXX
2913:             * @return true if inserts are detected by the resultset type
2914:             */
2915:            public boolean insertsAreDetected(int type) {
2916:                return false;
2917:            }
2918:
2919:            /**
2920:             * JDBC 2.0
2921:             *
2922:             * Return true if the driver supports batch updates, else return false.
2923:             *
2924:             */
2925:            public boolean supportsBatchUpdates() {
2926:                return true;
2927:            }
2928:
2929:            /**
2930:             * JDBC 2.0
2931:             *
2932:             * Get a description of the user-defined types defined in a particular
2933:             * schema.  Schema specific UDTs may have type JAVA_OBJECT, STRUCT, 
2934:             * or DISTINCT.
2935:             *
2936:             * <P>Only types matching the catalog, schema, type name and type  
2937:             * criteria are returned.  They are ordered by DATA_TYPE, TYPE_SCHEM 
2938:             * and TYPE_NAME.  The type name parameter may be a fully qualified 
2939:             * name.  In this case, the catalog and schemaPattern parameters are
2940:             * ignored.
2941:             *
2942:             * <P>Each type description has the following columns:
2943:             *  <OL>
2944:             *	<LI><B>TYPE_CAT</B> String => the type's catalog (may be null)
2945:             *	<LI><B>TYPE_SCHEM</B> String => type's schema (may be null)
2946:             *	<LI><B>TYPE_NAME</B> String => type name
2947:             *  <LI><B>CLASS_NAME</B> String => Java class name
2948:             *	<LI><B>DATA_TYPE</B> String => type value defined in java.sql.Types.  
2949:             *  One of JAVA_OBJECT, STRUCT, or DISTINCT
2950:             *	<LI><B>REMARKS</B> String => explanatory comment on the type
2951:             *  <LI><B>BASE_TYPE</B> short => type code of the source type of
2952:             *  a DISTINCT type or the type that implements the user-generated
2953:             *  reference type of the SELF_REFERENCING_COLUMN of a structured
2954:             *  type as defined in java.sql.Types (<code>null</code> if
2955:             *  DATA_TYPE is not DISTINCT or not STRUCT with
2956:             *  REFERENCE_GENERATION = USER_DEFINED)
2957:             *  </OL>
2958:             *
2959:             * <P><B>Note:</B> If the driver does not support UDTs then an empty
2960:             * result set is returned.
2961:             *
2962:             * @param catalog a catalog name; "" retrieves those without a
2963:             * catalog; null means drop catalog name from the selection criteria
2964:             * @param schemaPattern a schema name pattern; "" retrieves those
2965:             * without a schema
2966:             * @param typeNamePattern a type name pattern; may be a fully qualified
2967:             * name
2968:             * @param types a list of user-named types to include (JAVA_OBJECT, 
2969:             * STRUCT, or DISTINCT); null returns all types 
2970:             * @return ResultSet - each row is a type description
2971:             * @exception SQLException if a database-access error occurs.
2972:             */
2973:            public ResultSet getUDTs(String catalog, String schemaPattern,
2974:                    String typeNamePattern, int[] types) throws SQLException {
2975:                //we don't have support for catalog names
2976:                //we don't have java class types per schema, instead it's per database and hence
2977:                //we ignore schemapattern.
2978:                //the only type of user-named types we support are JAVA_OBJECT
2979:                synchronized (getConnectionSynchronization()) {
2980:                    setupContextStack();
2981:                    ResultSet rs = null;
2982:                    int getClassTypes = 0;
2983:                    try {
2984:                        String queryText = getQueryDescriptions(false)
2985:                                .getProperty("getUDTs");
2986:
2987:                        if (types != null && types.length >= 1) {
2988:                            for (int i = 0; i < types.length; i++) {
2989:                                if (types[i] == java.sql.Types.JAVA_OBJECT)
2990:                                    getClassTypes = 1;
2991:                            }
2992:                        } else
2993:                            getClassTypes = 1;
2994:
2995:                        PreparedStatement s = getEmbedConnection()
2996:                                .prepareMetaDataStatement(queryText);
2997:
2998:                        s.setInt(1, java.sql.Types.JAVA_OBJECT);
2999:                        s.setString(2, catalog);
3000:                        s.setString(3, schemaPattern);
3001:                        s.setString(4, swapNull(typeNamePattern));
3002:                        s.setInt(5, getClassTypes);
3003:
3004:                        rs = s.executeQuery();
3005:                    } finally {
3006:                        restoreContextStack();
3007:                    }
3008:                    return rs;
3009:                }
3010:            }
3011:
3012:            /**
3013:             * JDBC 2.0
3014:             *
3015:             * Return the connection that produced this metadata object.
3016:             *
3017:             */
3018:            public Connection getConnection() {
3019:                return getEmbedConnection().getApplicationConnection();
3020:            }
3021:
3022:            /**
3023:            Following methods are for the new JDBC 3.0 methods in java.sql.DatabaseMetaData
3024:            (see the JDBC 3.0 spec). We have the JDBC 3.0 methods in Local20
3025:            package, so we don't have to have a new class in Local30.
3026:            The new JDBC 3.0 methods don't make use of any new JDBC3.0 classes and
3027:            so this will work fine in jdbc2.0 configuration.
3028:             */
3029:
3030:            /////////////////////////////////////////////////////////////////////////
3031:            //
3032:            //	JDBC 3.0	-	New public methods
3033:            //
3034:            /////////////////////////////////////////////////////////////////////////
3035:            /**
3036:             * JDBC 3.0
3037:             *
3038:             * Retrieves whether this database supports statement pooling.
3039:             *
3040:             * @return true if statement pooling is supported; false otherwise
3041:             */
3042:            public boolean supportsStatementPooling() {
3043:                return false;
3044:            }
3045:
3046:            /**
3047:             * JDBC 3.0
3048:             *
3049:             * Retrieves whether this database supports savepoints.
3050:             *
3051:             * @return true if savepoints are supported; false otherwise
3052:             */
3053:            public boolean supportsSavepoints() {
3054:                return true;
3055:            }
3056:
3057:            /**
3058:             * JDBC 3.0
3059:             *
3060:             * Retrieves whether this database supports named parameters to callable statements.
3061:             *
3062:             * @return true if named parameters are supported; false otherwise
3063:             */
3064:            public boolean supportsNamedParameters() {
3065:                return false;
3066:            }
3067:
3068:            /**
3069:             * JDBC 3.0
3070:             *
3071:             * Retrieves whether it is possible to have multiple ResultSet objects returned from a
3072:             * CallableStatement object simultaneously.
3073:             *
3074:             * @return true if a CallableStatement object can return multiple ResultSet objects
3075:             * simultaneously; false otherwise
3076:             */
3077:            public boolean supportsMultipleOpenResults() {
3078:                return true;
3079:            }
3080:
3081:            /**
3082:             * JDBC 3.0
3083:             *
3084:             * Retrieves whether auto-generated keys can be retrieved after a statement
3085:             * has been executed.
3086:             *
3087:             * @return true if auto-generated keys can be retrieved after a statement has
3088:             * executed; false otherwise
3089:             */
3090:            public boolean supportsGetGeneratedKeys() {
3091:                /*
3092:                 * Currently reverting the returned value to false until there 
3093:                 * is more support for autogenerated keys in Derby.
3094:                 * (such as support for specifying the returned columns for
3095:                 * the autogenerated key)
3096:                 */
3097:                return false;
3098:            }
3099:
3100:            /**
3101:             * JDBC 3.0
3102:             *
3103:             * Retrieves whether this database supports the given result set holdability.
3104:             *
3105:             * @param holdability - one of the following constants:
3106:             * ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT
3107:             * @return true if so; false otherwise
3108:             * executed; false otherwise
3109:             */
3110:            public boolean supportsResultSetHoldability(int holdability) {
3111:                return true;
3112:            }
3113:
3114:            /**
3115:             * JDBC 3.0
3116:             *
3117:             * Retrieves the default holdability of this ResultSet object.
3118:             *
3119:             * @return the default holdability which is ResultSet.HOLD_CURSORS_OVER_COMMIT
3120:             */
3121:            public int getResultSetHoldability() {
3122:                return JDBC30Translation.HOLD_CURSORS_OVER_COMMIT;
3123:            }
3124:
3125:            /**
3126:             * JDBC 3.0
3127:             *
3128:             * Retrieves the major version number of the underlying database.
3129:             *
3130:             * @return the underlying database's major version
3131:             */
3132:            public int getDatabaseMajorVersion() {
3133:                ProductVersionHolder pvh = Monitor.getMonitor()
3134:                        .getEngineVersion();
3135:                if (pvh == null) {
3136:                    return -1;
3137:                }
3138:                return pvh.getMajorVersion();
3139:            }
3140:
3141:            /**
3142:             * JDBC 3.0
3143:             *
3144:             * Retrieves the minor version number of the underlying database.
3145:             *
3146:             * @return the underlying database's minor version
3147:             */
3148:            public int getDatabaseMinorVersion() {
3149:                ProductVersionHolder pvh = Monitor.getMonitor()
3150:                        .getEngineVersion();
3151:                if (pvh == null) {
3152:                    return -1;
3153:                }
3154:                return pvh.getMinorVersion();
3155:            }
3156:
3157:            /**
3158:             * JDBC 3.0
3159:             *
3160:             * Retrieves the major JDBC version number for this driver.
3161:             *
3162:             * @return JDBC version major number
3163:             */
3164:            public int getJDBCMajorVersion() {
3165:                return 3;
3166:            }
3167:
3168:            /**
3169:             * JDBC 3.0
3170:             *
3171:             * Retrieves the minor JDBC version number for this driver.
3172:             *
3173:             * @return JDBC version minor number
3174:             */
3175:            public int getJDBCMinorVersion() {
3176:                return 0;
3177:            }
3178:
3179:            /**
3180:             * JDBC 3.0
3181:             *
3182:             * Indicates whether the SQLSTATEs returned by SQLException.getSQLState
3183:             * is X/Open (now known as Open Group) SQL CLI or SQL99.
3184:             *
3185:             * @return the type of SQLSTATEs, one of: sqlStateXOpen or sqlStateSQL99
3186:             */
3187:            public int getSQLStateType() {
3188:                return JDBC30Translation.SQL_STATE_SQL99;
3189:            }
3190:
3191:            /**
3192:             * JDBC 3.0
3193:             *
3194:             * Indicates whether updates made to a LOB are made on a copy or
3195:             * directly to the LOB.
3196:             *
3197:             * @return true if updates are made to a copy of the LOB; false if
3198:             * updates are made directly to the LOB
3199:             * @exception SQLException Feature not implemented for now.
3200:             */
3201:            public boolean locatorsUpdateCopy() throws SQLException {
3202:                return false;
3203:            }
3204:
3205:            /**
3206:             * JDBC 3.0
3207:             *
3208:             * Retrieves a description of the user-defined type (UDT) hierarchies defined
3209:             * in a particular schema in this database. Only the immediate super type/ sub type
3210:             * relationship is modeled.
3211:             *
3212:             * @param catalog - a catalog name; "" retrieves those without a catalog;
3213:             * null means drop catalog name from the selection criteria
3214:             * @param schemaPattern - a schema name pattern; "" retrieves those without a schema
3215:             * @param typeNamePattern - a UDT name pattern; may be a fully-qualified name
3216:             * @return a ResultSet object in which a row gives information about the designated UDT
3217:             * @exception SQLException Feature not implemented for now.
3218:             */
3219:            public ResultSet getSuperTypes(String catalog,
3220:                    String schemaPattern, String typeNamePattern)
3221:                    throws SQLException {
3222:                return getSimpleQuery("getSuperTypes");
3223:            }
3224:
3225:            /**
3226:             * JDBC 3.0
3227:             *
3228:             * Retrieves a description of the table hierarchies defined in a particular
3229:             * schema in this database.
3230:             *
3231:             * @param catalog - a catalog name; "" retrieves those without a catalog;
3232:             * null means drop catalog name from the selection criteria
3233:             * @param schemaPattern - a schema name pattern; "" retrieves those without a schema
3234:             * @param typeNamePattern - a UDT name pattern; may be a fully-qualified name
3235:             * @return a ResultSet object in which each row is a type description
3236:             * @exception SQLException if a database access error occurs
3237:             */
3238:            public ResultSet getSuperTables(String catalog,
3239:                    String schemaPattern, String typeNamePattern)
3240:                    throws SQLException {
3241:                return getSimpleQuery("getSuperTables");
3242:            }
3243:
3244:            /**
3245:             * JDBC 3.0
3246:             *
3247:             * Retrieves a description of the given attribute of the given type for a
3248:             * user-defined type (UDT) that is available in the given schema and catalog.
3249:             *
3250:             * @param catalog - a catalog name; must match the catalog name as it is
3251:             * stored in the database; "" retrieves those without a catalog; null means that
3252:             * the catalog name should not be used to narrow the search
3253:             * @param schemaPattern - a schema name pattern; "" retrieves those without a schema;
3254:             * null means that the schema name should not be used to narrow the search
3255:             * @param typeNamePattern - a type name pattern; must match the type name as it is
3256:             * stored in the database
3257:             * @param attributeNamePattern - an attribute name pattern; must match the attribute
3258:             * name as it is declared in the database
3259:             * @return a ResultSet object in which each row is a type description
3260:             * @exception SQLException if a database access error occurs.
3261:             */
3262:            public ResultSet getAttributes(String catalog,
3263:                    String schemaPattern, String typeNamePattern,
3264:                    String attributeNamePattern) throws SQLException {
3265:                return getSimpleQuery("getAttributes");
3266:            }
3267:
3268:            /////////////////////////////////////////////////////////////////////////
3269:            //
3270:            //  JDBC 4.0 - New public methods
3271:            //
3272:            /////////////////////////////////////////////////////////////////////////
3273:
3274:            /**
3275:             * JDBC 4.0
3276:             *
3277:             * <p>Returns a list of the client info properties supported by
3278:             * the driver. The result set contains the following columns:
3279:             *
3280:             * <p>
3281:             * <ol>
3282:             *  <li>NAME String=&gt; The name of the client info property.</li>
3283:             *  <li>MAX_LEN int=&gt; The maximum length of the value for the
3284:             *      property.</li>
3285:             *  <li>DEFAULT_VALUE String=&gt; The default value of the property.</li>
3286:             *  <li>DESCRIPTION String=&gt; A description of the property.</li>
3287:             * </ol>
3288:             *
3289:             * <p>The <code>ResultSet</code> is sorted by the NAME column.
3290:             *
3291:             * @return A <code>ResultSet</code> object; each row is a
3292:             * supported client info property
3293:             * @exception SQLException if an error occurs
3294:             */
3295:            public ResultSet getClientInfoProperties() throws SQLException {
3296:                return getSimpleQuery("getClientInfoProperties");
3297:            }
3298:
3299:            /**
3300:             * JDBC 4.0
3301:             *
3302:             * <p>Get the schema names available in this database. The results
3303:             * are ordered by schema name.
3304:             *
3305:             * <p>The schema columns are:
3306:             *  <ol>
3307:             *  <li><strong>TABLE_SCHEM</strong> String =&gt; schema name</li>
3308:             *  <li><strong>TABLE_CATALOG</strong> String =&gt; catalog name
3309:             *  (may be <code>null</code>)</li>
3310:             *  </ol>
3311:             *
3312:             * @param catalog catalog name used to narrow down the search; ""
3313:             * means no catalog, <code>null</code> means any catalog
3314:             * @param schemaPattern schema name used to narrow down the
3315:             * search, <code>null</code> means schema name should not be used
3316:             * to narrow down search
3317:             * @return a <code>ResultSet</code> object in which each row is a
3318:             * schema description
3319:             * @exception SQLException if a database error occurs
3320:             */
3321:            public ResultSet getSchemas(String catalog, String schemaPattern)
3322:                    throws SQLException {
3323:                PreparedStatement s = getPreparedQuery("getSchemas");
3324:                s.setString(1, swapNull(catalog));
3325:                s.setString(2, swapNull(schemaPattern));
3326:                return s.executeQuery();
3327:            }
3328:
3329:            //////////////////////////////////////////////////////////////
3330:            //
3331:            // MISC 
3332:            //
3333:            //////////////////////////////////////////////////////////////
3334:
3335:            /**
3336:             * Get metadata that the client driver will cache. The metadata is
3337:             * fetched using SYSIBM.METADATA (found in metadata_net.properties).
3338:             *
3339:             * @return the result set returned by SYSIBM.METADATA
3340:             * @exception SQLException if a database error occurs
3341:             */
3342:            public ResultSet getClientCachedMetaData() throws SQLException {
3343:                return getSimpleQuery("METADATA", true);
3344:            }
3345:
3346:            /*
3347:             * utility helper routines:
3348:             */
3349:
3350:            /**
3351:             * Execute a query in metadata.properties (or SPS in the SYS
3352:             * schema) or metadata_net.properties (or SPS in the SYSIBM
3353:             * schema).
3354:             *
3355:             * @param nameKey the name of the query
3356:             * @param net if <code>true</code>, execute a query in
3357:             * metadata_net.properties; otherwise, execute a query in
3358:             * metadata.properties
3359:             * @return a <code>ResultSet</code> value
3360:             * @exception SQLException if a database error occurs
3361:             */
3362:            private ResultSet getSimpleQuery(String nameKey, boolean net)
3363:                    throws SQLException {
3364:                PreparedStatement ps = getPreparedQuery(nameKey, net);
3365:                if (ps == null)
3366:                    return null;
3367:
3368:                return ps.executeQuery();
3369:            }
3370:
3371:            /**
3372:             * Execute a query in metadata.properties, or an SPS in the SYS
3373:             * schema.
3374:             *
3375:             * @param nameKey the name of the query
3376:             * @return a <code>ResultSet</code> value
3377:             * @exception SQLException if a database error occurs
3378:             */
3379:            protected ResultSet getSimpleQuery(String nameKey)
3380:                    throws SQLException {
3381:                return getSimpleQuery(nameKey, false);
3382:            }
3383:
3384:            /**
3385:             * Get a stored prepared statement from the system tables.
3386:             *
3387:             * @param nameKey the name of the query
3388:             * @param net if <code>true</code>, find query in SYSIBM schema;
3389:             * otherwise, find query in SYS schema
3390:             * @return a <code>PreparedStatement</code> value
3391:             * @exception SQLException if a database error occurs
3392:             */
3393:            private PreparedStatement getPreparedQueryUsingSystemTables(
3394:                    String nameKey, boolean net) throws SQLException {
3395:                synchronized (getConnectionSynchronization()) {
3396:                    setupContextStack();
3397:                    PreparedStatement ps = null;
3398:
3399:                    try {
3400:                        String queryText = getQueryDescriptions(net)
3401:                                .getProperty(nameKey);
3402:                        if (queryText == null) {
3403:                            throw Util.notImplemented(nameKey);
3404:                        }
3405:
3406:                        ps = prepareSPS(nameKey, queryText, net);
3407:                    }
3408:
3409:                    catch (Throwable t) {
3410:                        throw handleException(t);
3411:                    }
3412:
3413:                    finally {
3414:                        restoreContextStack();
3415:                    }
3416:                    return ps;
3417:                }
3418:            }
3419:
3420:            /**
3421:             * Either get the prepared query for the metadata call from the
3422:             * system tables, or from the metadata.properties or
3423:             * metadata_net.properties file.
3424:             * In soft upgrade mode, the queries stored in the system tables
3425:             * might not be upto date with the Derby engine release because
3426:             * system tables can't be modified in backward incompatible way in
3427:             * soft upgrade mode. Because of this, if the database is in 
3428:             * soft upgrade mode, get the queries from metadata.properties
3429:             * file rather than from the system tables.
3430:             *
3431:             * Getting queries from metadata(_net).properties might cause problems
3432:             * if system catalogs have been changed between versions either by
3433:             * addition of columns or have new catalogs. To continue
3434:             * to support soft upgrade from older versions of database, find
3435:             * query that most closely matches database dictionary version.
3436:             *
3437:             * @param queryName Name of the metadata query for which we need
3438:             * a prepared statement
3439:             * @param net if <code>true</code>, use metadata_net.properties
3440:             * instead of metadata.properties
3441:             * @return PreparedStatement
3442:             * @exception SQLException if a database error occurs
3443:             */
3444:            private PreparedStatement getPreparedQuery(String queryName,
3445:                    boolean net) throws SQLException {
3446:                PreparedStatement s;
3447:                //We can safely goto system table since we are not in soft upgrade
3448:                //mode and hence metadata sql in system tables are uptodate
3449:                //with this Derby release.
3450:                if (notInSoftUpgradeMode())
3451:                    s = getPreparedQueryUsingSystemTables(queryName, net);
3452:                else {
3453:                    try {
3454:                        //Can't use stored prepared statements because we are in soft upgrade
3455:                        //mode and hence need to get metadata sql from metadata.properties file 
3456:                        //or metadata_net.properties
3457:                        String queryText = getQueryFromDescription(queryName,
3458:                                net);
3459:                        s = getEmbedConnection().prepareMetaDataStatement(
3460:                                queryText);
3461:                    } catch (Throwable t) {
3462:                        throw handleException(t);
3463:                    }
3464:                }
3465:                return s;
3466:            }
3467:
3468:            /**
3469:             * Get a prepared query from system tables or metadata.properties.
3470:             *
3471:             * @param queryName name of the query
3472:             * @return a <code>PreparedStatement</code> value
3473:             * @exception SQLException if a database error occurs
3474:             */
3475:            protected PreparedStatement getPreparedQuery(String queryName)
3476:                    throws SQLException {
3477:                return getPreparedQuery(queryName, false);
3478:            }
3479:
3480:            /**
3481:             * Given a queryName, find closest match in queryDescriptions. This method
3482:             * should be called in soft-upgrade mode only, where current software version
3483:             * doesn't match dictionary version. For these cases, there may be
3484:             * multiple entries in queryDescriptions for given queryName. Find a
3485:             * version of the query that closely matches dictionary version.
3486:             *
3487:             * This method is currently coded to handle two specific queries,
3488:             * getColumnPrivileges and getTablePrivileges. Derby databases that are 10.1
3489:             * or earlier will not have new system tables added for 10.2 for privileges.
3490:             * 
3491:             * It should be possible to automate finding closest match by generating
3492:             * all Major_Minor versions between software version and dictionary version
3493:             * and try each one from Dictionary version to current version. Since only
3494:             * needed for two queries, overhead may not be worth it yet.
3495:             *
3496:             * @param queryName name of the query
3497:             * @param net if <code>true</code>, get the query from
3498:             * metadata_net.properties instead of metadata.properties
3499:             * @return the query text
3500:             * @exception StandardException if an error occurs
3501:             */
3502:            private String getQueryFromDescription(String queryName, boolean net)
3503:                    throws StandardException {
3504:                DataDictionary dd = getLanguageConnectionContext()
3505:                        .getDataDictionary();
3506:
3507:                // If dictionary version is below 10.2, special case
3508:                // getColumnPrivileges and getTablePrivileges since new system tables
3509:                // for privileges wouldn't be present.
3510:                if (!dd
3511:                        .checkVersion(DataDictionary.DD_VERSION_DERBY_10_2,
3512:                                null)) {
3513:                    if (queryName.equals("getColumnPrivileges"))
3514:                        queryName = "getColumnPrivileges_10_1";
3515:
3516:                    if (queryName.equals("getTablePrivileges"))
3517:                        queryName = "getTablePrivileges_10_1";
3518:                }
3519:
3520:                return getQueryDescriptions(net).getProperty(queryName);
3521:            }
3522:
3523:            /*
3524:             ** Given a SPS name and a query text it returns a 
3525:             ** java.sql.PreparedStatement for the SPS. If the SPS
3526:             ** doeesn't exist is created.
3527:             ** 
3528:             */
3529:            private PreparedStatement prepareSPS(String spsName,
3530:                    String spsText, boolean net) throws StandardException,
3531:                    SQLException {
3532:
3533:                LanguageConnectionContext lcc = getLanguageConnectionContext();
3534:
3535:                /* We now need to do this in sub transaction because we could possibly recompile SPS
3536:                 * later, and the recompile is in a sub transaction, and will update the SYSSTATEMENTS
3537:                 * entry.  Don't want to block.
3538:                 */
3539:                lcc.beginNestedTransaction(true);
3540:
3541:                DataDictionary dd = getLanguageConnectionContext()
3542:                        .getDataDictionary();
3543:                SPSDescriptor spsd = dd.getSPSDescriptor(spsName, net ? dd
3544:                        .getSysIBMSchemaDescriptor() : dd
3545:                        .getSystemSchemaDescriptor());
3546:                lcc.commitNestedTransaction();
3547:
3548:                if (spsd == null) {
3549:                    throw Util.notImplemented(spsName);
3550:                }
3551:
3552:                /* manish:
3553:                   There should be a nicer way of getting a 
3554:                   java.sql.PreparedStatement from an SPS descriptor!
3555:                 */
3556:                /*
3557:                 ** It is unnecessarily expensive to get the
3558:                 ** the statement, and then send an EXECUTE
3559:                 ** statement, but we have no (easy) way of turning
3560:                 ** the statement into a java.sql.PreparedStatement.
3561:                 */
3562:                String queryText = "EXECUTE STATEMENT "
3563:                        + (net ? "SYSIBM" : "SYS") + ".\"" + spsName + "\"";
3564:                return getEmbedConnection().prepareMetaDataStatement(queryText);
3565:
3566:            }
3567:
3568:            static final protected String swapNull(String s) {
3569:                return (s == null ? "%" : s);
3570:            }
3571:
3572:            /**
3573:             *	Gets the constant action factory 
3574:             *
3575:             *	@return	the constant action factory.
3576:             *
3577:             * @exception StandardException		Thrown on failur4e
3578:             */
3579:            private GenericConstantActionFactory getGenericConstantActionFactory()
3580:                    throws StandardException {
3581:                if (constantActionFactory == null) {
3582:                    GenericExecutionFactory execFactory = (GenericExecutionFactory) getLanguageConnectionContext()
3583:                            .getLanguageConnectionFactory()
3584:                            .getExecutionFactory();
3585:                    constantActionFactory = execFactory
3586:                            .getConstantActionFactory();
3587:                }
3588:
3589:                return constantActionFactory;
3590:            }
3591:
3592:            /**
3593:             *	Gets the LanguageConnectionContext for this connection.
3594:             *
3595:             *	@return	the lcc for this connection
3596:             *
3597:             */
3598:            private LanguageConnectionContext getLanguageConnectionContext() {
3599:                return getEmbedConnection().getLanguageConnection();
3600:            }
3601:
3602:            /*
3603:             ** Priv block code, moved out of the old Java2 version.
3604:             */
3605:
3606:            /**
3607:             * Loads the query descriptions from metadata.properties and
3608:             * metadata_net.properties into <code>queryDescriptions</code> and
3609:             * <code>queryDescriptions_net</code>.
3610:             */
3611:            private void loadQueryDescriptions() {
3612:                java.security.AccessController.doPrivileged(this );
3613:            }
3614:
3615:            /**
3616:             * Performs a privileged action. Reads the query descriptions.
3617:             *
3618:             * @return <code>null</code>
3619:             */
3620:            public final Object run() {
3621:                // SECURITY PERMISSION - IP3
3622:                PBloadQueryDescriptions();
3623:                return null;
3624:            }
3625:
3626:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.