diff options
author | Dave Cramer <davec@fastcrypt.com> | 2002-08-16 19:37:57 +0000 |
---|---|---|
committer | Dave Cramer <davec@fastcrypt.com> | 2002-08-16 19:37:57 +0000 |
commit | 7ffe65fefbb24771f1187116b430e27d051fc128 (patch) | |
tree | 1ba58068cdbd20c4748831a6f6a6d5cf338d4039 /src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java | |
parent | b3766d9fa56fcf21d4fa1f2ab4da64ec21b854ee (diff) | |
download | postgresql-7ffe65fefbb24771f1187116b430e27d051fc128.tar.gz |
removed duplicate code from jdbc2 classes
Diffstat (limited to 'src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java')
-rw-r--r-- | src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java | 770 |
1 files changed, 518 insertions, 252 deletions
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java index 6a8d20d669..0682737b8b 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java @@ -5,10 +5,20 @@ import java.sql.*; import java.util.*; import org.postgresql.Field; import org.postgresql.util.PSQLException; +import org.postgresql.Driver; -public abstract class AbstractJdbc1DatabaseMetaData +public abstract class AbstractJdbc1DatabaseMetaData { + private static final String keywords = "abort,acl,add,aggregate,append,archive," + + "arch_store,backward,binary,change,cluster,"+ + "copy,database,delimiter,delimiters,do,extend,"+ + "explain,forward,heavy,index,inherits,isnull,"+ + "light,listen,load,merge,nothing,notify,"+ + "notnull,oids,purge,rename,replace,retrieve,"+ + "returns,rule,recipe,setof,stdin,stdout,store,"+ + "vacuum,verbose,version"; + protected AbstractJdbc1Connection connection; // The connection association // These define various OID's. Hopefully they will stay constant. @@ -20,7 +30,7 @@ public abstract class AbstractJdbc1DatabaseMetaData public AbstractJdbc1DatabaseMetaData(AbstractJdbc1Connection conn) { - this.connection = conn; + this.connection = conn; } /* @@ -32,7 +42,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean allProceduresAreCallable() throws SQLException { - return true; // For now... + if (Driver.logDebug) Driver.debug("allProceduresAreCallable"); + return true; // For now... } /* @@ -44,6 +55,7 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean allTablesAreSelectable() throws SQLException { + if (Driver.logDebug) Driver.debug("allTablesAreSelectable"); return true; // For now... } @@ -55,7 +67,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getURL() throws SQLException { - return connection.getURL(); + String url = connection.getURL(); + if (Driver.logDebug) Driver.debug("getURL " + url); + return url; } /* @@ -66,7 +80,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getUserName() throws SQLException { - return connection.getUserName(); + String userName = connection.getUserName(); + if (Driver.logDebug) Driver.debug("getUserName " + userName); + return userName; } /* @@ -77,7 +93,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean isReadOnly() throws SQLException { - return connection.isReadOnly(); + boolean isReadOnly = connection.isReadOnly(); + if (Driver.logDebug) Driver.debug("isReadOnly " + isReadOnly); + return isReadOnly; } /* @@ -88,7 +106,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean nullsAreSortedHigh() throws SQLException { - return connection.haveMinimumServerVersion("7.2"); + boolean nullSortedHigh = connection.haveMinimumServerVersion("7.2"); + if (Driver.logDebug) Driver.debug("nullsAreSortedHigh " + nullSortedHigh); + return nullSortedHigh; } /* @@ -99,7 +119,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean nullsAreSortedLow() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("nullsAreSortedLow false"); + return false; } /* @@ -110,7 +131,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean nullsAreSortedAtStart() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("nullsAreSortedAtStart false"); + return false; } /* @@ -121,7 +143,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean nullsAreSortedAtEnd() throws SQLException { - return ! connection.haveMinimumServerVersion("7.2"); + boolean nullsAreSortedAtEnd = ! connection.haveMinimumServerVersion("7.2"); + if (Driver.logDebug) Driver.debug("nullsAreSortedAtEnd " + nullsAreSortedAtEnd); + return nullsAreSortedAtEnd; } /* @@ -133,7 +157,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getDatabaseProductName() throws SQLException { - return "PostgreSQL"; + if (Driver.logDebug) Driver.debug("getDatabaseProductName PostgresSQL"); + return "PostgreSQL"; } /* @@ -144,7 +169,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getDatabaseProductVersion() throws SQLException { - return connection.getDBVersionNumber(); + String versionNumber = connection.getDBVersionNumber(); + if (Driver.logDebug) Driver.debug("getDatabaseProductVersion " + versionNumber); + return versionNumber; } /* @@ -156,7 +183,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getDriverName() throws SQLException { - return "PostgreSQL Native Driver"; + String driverName = "PostgreSQL Native Driver"; + if (Driver.logDebug) Driver.debug("getDriverName" + driverName); + return driverName; } /* @@ -168,7 +197,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getDriverVersion() throws SQLException { - return connection.getDriver().getVersion(); + String driverVersion = connection.this_driver.getVersion(); + if (Driver.logDebug) Driver.debug("getDriverVersion " + driverVersion); + return driverVersion; } /* @@ -178,7 +209,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public int getDriverMajorVersion() { - return connection.getDriver().getMajorVersion(); + int majorVersion = connection.this_driver.getMajorVersion(); + if (Driver.logDebug) Driver.debug("getMajorVersion " + majorVersion); + return majorVersion; } /* @@ -188,7 +221,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public int getDriverMinorVersion() { - return connection.getDriver().getMinorVersion(); + int minorVersion = connection.this_driver.getMinorVersion(); + if (Driver.logDebug) Driver.debug("getMinorVersion " + minorVersion); + return minorVersion; } /* @@ -200,7 +235,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean usesLocalFiles() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("usesLocalFiles " + false); + return false; } /* @@ -212,7 +248,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean usesLocalFilePerTable() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("usesLocalFilePerTable " + false); + return false; } /* @@ -229,7 +266,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsMixedCaseIdentifiers() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("supportsMixedCaseIdentifiers " + false); + return false; } /* @@ -240,7 +278,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean storesUpperCaseIdentifiers() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("storesUpperCaseIdentifiers " + false); + return false; } /* @@ -251,7 +290,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean storesLowerCaseIdentifiers() throws SQLException { - return true; + if (Driver.logDebug) Driver.debug("storesLowerCaseIdentifiers " + true); + return true; } /* @@ -262,7 +302,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean storesMixedCaseIdentifiers() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("storesMixedCaseIdentifiers " + false); + return false; } /* @@ -275,7 +316,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException { - return true; + if (Driver.logDebug) Driver.debug("supportsMixedCaseQuotedIdentifiers " + true); + return true; } /* @@ -286,7 +328,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean storesUpperCaseQuotedIdentifiers() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("storesUpperCaseQuotedIdentifiers " + false); + return false; } /* @@ -297,7 +340,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean storesLowerCaseQuotedIdentifiers() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("storesLowerCaseQuotedIdentifiers " + false); + return false; } /* @@ -308,7 +352,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean storesMixedCaseQuotedIdentifiers() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("storesMixedCaseQuotedIdentifiers " + false); + return false; } /* @@ -321,7 +366,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getIdentifierQuoteString() throws SQLException { - return "\""; + if (Driver.logDebug) Driver.debug("getIdentifierQuoteString \"" ); + return "\""; } /* @@ -342,31 +388,31 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getSQLKeywords() throws SQLException { - return "abort,acl,add,aggregate,append,archive,arch_store,backward,binary,change,cluster,copy,database,delimiter,delimiters,do,extend,explain,forward,heavy,index,inherits,isnull,light,listen,load,merge,nothing,notify,notnull,oids,purge,rename,replace,retrieve,returns,rule,recipe,setof,stdin,stdout,store,vacuum,verbose,version"; + return keywords; } public String getNumericFunctions() throws SQLException { - // XXX-Not Implemented - return ""; + if (Driver.logDebug) Driver.debug("getNumericFunctions"); + return ""; } public String getStringFunctions() throws SQLException { - // XXX-Not Implemented - return ""; + if (Driver.logDebug) Driver.debug("getStringFunctions"); + return ""; } public String getSystemFunctions() throws SQLException { - // XXX-Not Implemented - return ""; + if (Driver.logDebug) Driver.debug("getSystemFunctions"); + return ""; } public String getTimeDateFunctions() throws SQLException { - // XXX-Not Implemented - return ""; + if (Driver.logDebug) Driver.debug("getTimeDateFunctions"); + return ""; } /* @@ -378,7 +424,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getSearchStringEscape() throws SQLException { - return "\\"; + if (Driver.logDebug) Driver.debug("getSearchStringEscape"); + return "\\"; } /* @@ -394,7 +441,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getExtraNameCharacters() throws SQLException { - return ""; + if (Driver.logDebug) Driver.debug("getExtraNameCharacters"); + return ""; } /* @@ -406,7 +454,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsAlterTableWithAddColumn() throws SQLException { - return true; + if (Driver.logDebug) Driver.debug("supportsAlterTableWithAddColumn " + true); + return true; } /* @@ -418,6 +467,7 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsAlterTableWithDropColumn() throws SQLException { + if (Driver.logDebug) Driver.debug("supportsAlterTableWithDropColumn " + false); return false; } @@ -441,7 +491,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsColumnAliasing() throws SQLException { - return true; + if (Driver.logDebug) Driver.debug("supportsColumnAliasing " + true); + return true; } /* @@ -453,19 +504,20 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean nullPlusNonNullIsNull() throws SQLException { - return true; + if (Driver.logDebug) Driver.debug("nullPlusNonNullIsNull " + true); + return true; } public boolean supportsConvert() throws SQLException { - // XXX-Not Implemented - return false; + if (Driver.logDebug) Driver.debug("supportsConvert " + false); + return false; } public boolean supportsConvert(int fromType, int toType) throws SQLException { - // XXX-Not Implemented - return false; + if (Driver.logDebug) Driver.debug("supportsConvert " + false); + return false; } /* @@ -477,7 +529,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsTableCorrelationNames() throws SQLException { - return true; + if (Driver.logDebug) Driver.debug("supportsTableCorrelationNames " + true); + return true; } /* @@ -489,7 +542,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsDifferentTableCorrelationNames() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("supportsDifferentTableCorrelationNames " + false); + return false; } /* @@ -502,7 +556,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsExpressionsInOrderBy() throws SQLException { - return true; + if (Driver.logDebug) Driver.debug("supportsExpressionsInOrderBy " + true); + return true; } /* @@ -513,7 +568,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsOrderByUnrelated() throws SQLException { - return connection.haveMinimumServerVersion("6.4"); + boolean supportsOrderByUnrelated = connection.haveMinimumServerVersion("6.4"); + if (Driver.logDebug) Driver.debug("supportsOrderByUnrelated " + supportsOrderByUnrelated); + return supportsOrderByUnrelated; } /* @@ -525,7 +582,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsGroupBy() throws SQLException { - return true; + if (Driver.logDebug) Driver.debug("supportsGroupBy " + true); + return true; } /* @@ -536,7 +594,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsGroupByUnrelated() throws SQLException { - return connection.haveMinimumServerVersion("6.4"); + boolean supportsGroupByUnrelated = connection.haveMinimumServerVersion("6.4"); + if (Driver.logDebug) Driver.debug("supportsGroupByUnrelated " + supportsGroupByUnrelated); + return supportsGroupByUnrelated; } /* @@ -551,7 +611,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsGroupByBeyondSelect() throws SQLException { - return supportsGroupByUnrelated(); + boolean supportsGroupByBeyondSelect = connection.haveMinimumServerVersion("6.4"); + if (Driver.logDebug) Driver.debug("supportsGroupByUnrelated " + supportsGroupByBeyondSelect); + return supportsGroupByBeyondSelect; } /* @@ -563,7 +625,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsLikeEscapeClause() throws SQLException { - return connection.haveMinimumServerVersion("7.1"); + boolean supportsLikeEscapeClause = connection.haveMinimumServerVersion("7.1"); + if (Driver.logDebug) Driver.debug("supportsLikeEscapeClause " + supportsLikeEscapeClause); + return supportsLikeEscapeClause; } /* @@ -576,7 +640,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsMultipleResultSets() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("supportsMultipleResultSets " + false); + return false; } /* @@ -589,7 +654,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsMultipleTransactions() throws SQLException { - return true; + if (Driver.logDebug) Driver.debug("supportsMultipleTransactions " + true); + return true; } /* @@ -604,7 +670,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsNonNullableColumns() throws SQLException { - return true; + if (Driver.logDebug) Driver.debug("supportsNonNullableColumns true"); + return true; } /* @@ -621,7 +688,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsMinimumSQLGrammar() throws SQLException { - return true; + if (Driver.logDebug) Driver.debug("supportsMinimumSQLGrammar TRUE"); + return true; } /* @@ -633,7 +701,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsCoreSQLGrammar() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("supportsCoreSQLGrammar FALSE "); + return false; } /* @@ -646,7 +715,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsExtendedSQLGrammar() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("supportsExtendedSQLGrammar FALSE"); + return false; } /* @@ -663,7 +733,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsANSI92EntryLevelSQL() throws SQLException { - return false; + boolean schemas = connection.haveMinimumServerVersion("7.3"); + if (Driver.logDebug) Driver.debug("supportsANSI92EntryLevelSQL " + schemas); + return schemas; } /* @@ -675,7 +747,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsANSI92IntermediateSQL() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("supportsANSI92IntermediateSQL false "); + return false; } /* @@ -686,7 +759,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsANSI92FullSQL() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("supportsANSI92FullSQL false "); + return false; } /* @@ -698,7 +772,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsIntegrityEnhancementFacility() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("supportsIntegrityEnhancementFacility false "); + return false; } /* @@ -709,7 +784,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsOuterJoins() throws SQLException { - return connection.haveMinimumServerVersion("7.1"); + boolean supportsOuterJoins = connection.haveMinimumServerVersion("7.1"); + if (Driver.logDebug) Driver.debug("supportsOuterJoins " + supportsOuterJoins); + return supportsOuterJoins; } /* @@ -720,7 +797,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsFullOuterJoins() throws SQLException { - return connection.haveMinimumServerVersion("7.1"); + boolean supportsFullOuterJoins = connection.haveMinimumServerVersion("7.1"); + if (Driver.logDebug) Driver.debug("supportsFullOuterJoins " + supportsFullOuterJoins); + return supportsFullOuterJoins; } /* @@ -731,7 +810,9 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsLimitedOuterJoins() throws SQLException { - return supportsFullOuterJoins(); + boolean supportsLimitedOuterJoins = connection.haveMinimumServerVersion("7.1"); + if (Driver.logDebug) Driver.debug("supportsFullOuterJoins " + supportsLimitedOuterJoins); + return supportsLimitedOuterJoins; } /* @@ -744,7 +825,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getSchemaTerm() throws SQLException { - return "schema"; + if (Driver.logDebug) Driver.debug("getSchemaTerm schema"); + return "schema"; } /* @@ -756,7 +838,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getProcedureTerm() throws SQLException { - return "function"; + if (Driver.logDebug) Driver.debug("getProcedureTerm function "); + return "function"; } /* @@ -767,7 +850,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getCatalogTerm() throws SQLException { - return "database"; + if (Driver.logDebug) Driver.debug("getCatalogTerm database "); + return "database"; } /* @@ -779,7 +863,10 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean isCatalogAtStart() throws SQLException { - throw org.postgresql.Driver.notImplemented(); + // return true here; we return false for every other catalog function + // so it won't matter what we return here D.C. + if (Driver.logDebug) Driver.debug("isCatalogAtStart not implemented"); + return true; } /* @@ -790,7 +877,10 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public String getCatalogSeparator() throws SQLException { - throw org.postgresql.Driver.notImplemented(); + // Give them something to work with here + // everything else returns false so it won't matter what we return here D.C. + if (Driver.logDebug) Driver.debug("getCatalogSeparator not implemented "); + return "."; } /* @@ -801,7 +891,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsSchemasInDataManipulation() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("supportsSchemasInDataManipulation false"); + return false; } /* @@ -812,7 +903,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsSchemasInProcedureCalls() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("supportsSchemasInProcedureCalls false"); + return false; } /* @@ -823,7 +915,10 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsSchemasInTableDefinitions() throws SQLException { - return false; + boolean schemas = connection.haveMinimumServerVersion("7.3"); + + if (Driver.logDebug) Driver.debug("supportsSchemasInTableDefinitions " + schemas); + return schemas; } /* @@ -834,7 +929,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsSchemasInIndexDefinitions() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("supportsSchemasInIndexDefinitions false"); + return false; } /* @@ -845,7 +941,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("supportsSchemasInPrivilegeDefinitions false"); + return false; } /* @@ -856,7 +953,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsCatalogsInDataManipulation() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("supportsCatalogsInDataManipulation false"); + return false; } /* @@ -867,7 +965,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsCatalogsInProcedureCalls() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("supportsCatalogsInDataManipulation false"); + return false; } /* @@ -878,7 +977,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsCatalogsInTableDefinitions() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("supportsCatalogsInTableDefinitions false"); + return false; } /* @@ -889,7 +989,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsCatalogsInIndexDefinitions() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("supportsCatalogsInIndexDefinitions false"); + return false; } /* @@ -900,7 +1001,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException { - return false; + if (Driver.logDebug) Driver.debug("supportsCatalogsInPrivilegeDefinitions false"); + return false; } /* @@ -912,7 +1014,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsPositionedDelete() throws SQLException { - return false; // For now... + if (Driver.logDebug) Driver.debug("supportsPositionedDelete false"); + return false; // For now... } /* @@ -923,7 +1026,8 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsPositionedUpdate() throws SQLException { - return false; // For now... + if (Driver.logDebug) Driver.debug("supportsPositionedUpdate false"); + return false; // For now... } /* @@ -934,7 +1038,7 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsSelectForUpdate() throws SQLException { - return connection.haveMinimumServerVersion("6.5"); + return connection.haveMinimumServerVersion("6.5"); } /* @@ -946,7 +1050,7 @@ public abstract class AbstractJdbc1DatabaseMetaData */ public boolean supportsStoredProcedures() throws SQLException { - return false; + return false; } /* @@ -1703,7 +1807,7 @@ public abstract class AbstractJdbc1DatabaseMetaData String relKind; switch (r.getBytes(3)[0]) { - case (byte) 'r': + case (byte) 'r': if ( r.getString(1).startsWith("pg_") ) { relKind = "SYSTEM TABLE"; @@ -1991,7 +2095,7 @@ public abstract class AbstractJdbc1DatabaseMetaData tuple[7] = null; // Buffer length // Decimal digits = scale - // From the source (see e.g. backend/utils/adt/numeric.c, + // From the source (see e.g. backend/utils/adt/format_type.c, // function numeric()) the scale and precision can be calculated // from the typmod value. if (typname.equals("numeric") || typname.equals("decimal")) @@ -2080,6 +2184,7 @@ public abstract class AbstractJdbc1DatabaseMetaData { byte[][] tuple = new byte[8][0]; tuple[0] = tuple[1] = "".getBytes(); + if (Driver.logDebug) Driver.debug("relname=\"" + r.getString(1) + "\" relacl=\"" + r.getString(2) + "\""); // For now, don't add to the result as relacl needs to be processed. //v.addElement(tuple); @@ -2088,41 +2193,68 @@ public abstract class AbstractJdbc1DatabaseMetaData return connection.getResultSet(null, f, v, "OK", 1); } - /* - * Get a description of the access rights for each table available - * in a catalog. - * - * This method is currently unimplemented. - * - * <P>Only privileges matching the schema and table name - * criteria are returned. They are ordered by TABLE_SCHEM, - * TABLE_NAME, and PRIVILEGE. - * - * <P>Each privilige description has the following columns: - * <OL> - * <LI><B>TABLE_CAT</B> String => table catalog (may be null) - * <LI><B>TABLE_SCHEM</B> String => table schema (may be null) - * <LI><B>TABLE_NAME</B> String => table name - * <LI><B>COLUMN_NAME</B> String => column name - * <LI><B>GRANTOR</B> => grantor of access (may be null) - * <LI><B>GRANTEE</B> String => grantee of access - * <LI><B>PRIVILEGE</B> String => name of access (SELECT, - * INSERT, UPDATE, REFRENCES, ...) - * <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted - * to grant to others; "NO" if not; null if unknown - * </OL> - * - * @param catalog a catalog name; "" retrieves those without a catalog - * @param schemaPattern a schema name pattern; "" retrieves those - * without a schema - * @param tableNamePattern a table name pattern - * @return ResultSet each row is a table privilege description - * @see #getSearchStringEscape - */ - public java.sql.ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) throws SQLException - { - throw org.postgresql.Driver.notImplemented(); - } + /* + * Get a description of the access rights for each table available + * in a catalog. + * + * This method is currently unimplemented. + * + * <P>Only privileges matching the schema and table name + * criteria are returned. They are ordered by TABLE_SCHEM, + * TABLE_NAME, and PRIVILEGE. + * + * <P>Each privilige description has the following columns: + * <OL> + * <LI><B>TABLE_CAT</B> String => table catalog (may be null) + * <LI><B>TABLE_SCHEM</B> String => table schema (may be null) + * <LI><B>TABLE_NAME</B> String => table name + * <LI><B>COLUMN_NAME</B> String => column name + * <LI><B>GRANTOR</B> => grantor of access (may be null) + * <LI><B>GRANTEE</B> String => grantee of access + * <LI><B>PRIVILEGE</B> String => name of access (SELECT, + * INSERT, UPDATE, REFRENCES, ...) + * <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted + * to grant to others; "NO" if not; null if unknown + * </OL> + * + * @param catalog a catalog name; "" retrieves those without a catalog + * @param schemaPattern a schema name pattern; "" retrieves those + * without a schema + * @param tableNamePattern a table name pattern + * @return ResultSet each row is a table privilege description + * @see #getSearchStringEscape + */ + public java.sql.ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) throws SQLException + { + Field f[] = new Field[8]; + Vector v = new Vector(); + + if (tableNamePattern == null) + tableNamePattern = "%"; + + f[0] = new Field(connection, "TABLE_CAT", iVarcharOid, 32); + f[1] = new Field(connection, "TABLE_SCHEM", iVarcharOid, 32); + f[2] = new Field(connection, "TABLE_NAME", iVarcharOid, 32); + f[3] = new Field(connection, "COLUMN_NAME", iVarcharOid, 32); + f[4] = new Field(connection, "GRANTOR", iVarcharOid, 32); + f[5] = new Field(connection, "GRANTEE", iVarcharOid, 32); + f[6] = new Field(connection, "PRIVILEGE", iVarcharOid, 32); + f[7] = new Field(connection, "IS_GRANTABLE", iVarcharOid, 32); + + // This is taken direct from the psql source + java.sql.ResultSet r = connection.ExecSQL("SELECT relname, relacl FROM pg_class, pg_user WHERE ( relkind = 'r' OR relkind = 'i') and relname !~ '^pg_' and relname !~ '^xin[vx][0-9]+' and usesysid = relowner and relname like '" + tableNamePattern.toLowerCase() + "' ORDER BY relname"); + while (r.next()) + { + byte[][] tuple = new byte[8][0]; + tuple[0] = tuple[1] = "".getBytes(); + if (Driver.logDebug) Driver.debug("relname=\"" + r.getString(1) + "\" relacl=\"" + r.getString(2) + "\""); + + // For now, don't add to the result as relacl needs to be processed. + //v.addElement(tuple); + } + + return connection.getResultSet(null, f, v, "OK", 1); + } /* * Get a description of a table's optimal set of columns that @@ -2253,140 +2385,274 @@ public abstract class AbstractJdbc1DatabaseMetaData ); } - private java.sql.ResultSet getImportedExportedKeys(String catalog, String schema, String primaryTable, String foreignTable) throws SQLException - { - Field f[] = new Field[14]; - - f[0] = new Field(connection, "PKTABLE_CAT", iVarcharOid, 32); - f[1] = new Field(connection, "PKTABLE_SCHEM", iVarcharOid, 32); - f[2] = new Field(connection, "PKTABLE_NAME", iVarcharOid, 32); - f[3] = new Field(connection, "PKCOLUMN_NAME", iVarcharOid, 32); - f[4] = new Field(connection, "FKTABLE_CAT", iVarcharOid, 32); - f[5] = new Field(connection, "FKTABLE_SCHEM", iVarcharOid, 32); - f[6] = new Field(connection, "FKTABLE_NAME", iVarcharOid, 32); - f[7] = new Field(connection, "FKCOLUMN_NAME", iVarcharOid, 32); - f[8] = new Field(connection, "KEY_SEQ", iInt2Oid, 2); - f[9] = new Field(connection, "UPDATE_RULE", iInt2Oid, 2); - f[10] = new Field(connection, "DELETE_RULE", iInt2Oid, 2); - f[11] = new Field(connection, "FK_NAME", iVarcharOid, 32); - f[12] = new Field(connection, "PK_NAME", iVarcharOid, 32); - f[13] = new Field(connection, "DEFERRABILITY", iInt2Oid, 2); - - java.sql.ResultSet rs = connection.ExecSQL("SELECT c.relname,c2.relname," - + "t.tgconstrname,ic.relname," - + "t.tgdeferrable,t.tginitdeferred," - + "t.tgnargs,t.tgargs,p.proname " - + "FROM pg_trigger t,pg_class c,pg_class c2," - + "pg_class ic,pg_proc p, pg_index i " - + "WHERE t.tgrelid=c.oid AND t.tgconstrrelid=c2.oid " - + "AND t.tgfoid=p.oid AND tgisconstraint " - + ((primaryTable != null) ? "AND c.relname='" + primaryTable + "' " : "") - + ((foreignTable != null) ? "AND c2.relname='" + foreignTable + "' " : "") - + "AND i.indrelid=c.oid " - + "AND i.indexrelid=ic.oid AND i.indisprimary " - + "ORDER BY c.relname,c2.relname" - ); - Vector tuples = new Vector(); - short seq = 0; - if (rs.next()) - { - boolean hasMore; - do - { - byte tuple[][] = new byte[14][0]; - for (int k = 0;k < 14;k++) - tuple[k] = null; +/* + SELECT + c.relname as primary, + c2.relname as foreign, + t.tgconstrname, + ic.relname as fkeyname, + af.attnum as fkeyseq, + ipc.relname as pkeyname, + ap.attnum as pkeyseq, + t.tgdeferrable, + t.tginitdeferred, + t.tgnargs,t.tgargs, + p1.proname as updaterule, + p2.proname as deleterule +FROM + pg_trigger t, + pg_trigger t1, + pg_class c, + pg_class c2, + pg_class ic, + pg_class ipc, + pg_proc p1, + pg_proc p2, + pg_index if, + pg_index ip, + pg_attribute af, + pg_attribute ap +WHERE + (t.tgrelid=c.oid + AND t.tgisconstraint + AND t.tgconstrrelid=c2.oid + AND t.tgfoid=p1.oid + and p1.proname like '%%upd') + + and + (t1.tgrelid=c.oid + and t1.tgisconstraint + and t1.tgconstrrelid=c2.oid + AND t1.tgfoid=p2.oid + and p2.proname like '%%del') + + AND c2.relname='users' + + AND + (if.indrelid=c.oid + AND if.indexrelid=ic.oid + and ic.oid=af.attrelid + AND if.indisprimary) + + and + (ip.indrelid=c2.oid + and ip.indexrelid=ipc.oid + and ipc.oid=ap.attrelid + and ip.indisprimary) + +*/ +/** + * + * @param catalog + * @param schema + * @param primaryTable if provided will get the keys exported by this table + * @param foreignTable if provided will get the keys imported by this table + * @return ResultSet + * @throws SQLException + */ + + protected java.sql.ResultSet getImportedExportedKeys(String catalog, String schema, String primaryTable, String foreignTable) throws SQLException + { + Field f[] = new Field[14]; + + f[0] = new Field(connection, "PKTABLE_CAT", iVarcharOid, 32); + f[1] = new Field(connection, "PKTABLE_SCHEM", iVarcharOid, 32); + f[2] = new Field(connection, "PKTABLE_NAME", iVarcharOid, 32); + f[3] = new Field(connection, "PKCOLUMN_NAME", iVarcharOid, 32); + f[4] = new Field(connection, "FKTABLE_CAT", iVarcharOid, 32); + f[5] = new Field(connection, "FKTABLE_SCHEM", iVarcharOid, 32); + f[6] = new Field(connection, "FKTABLE_NAME", iVarcharOid, 32); + f[7] = new Field(connection, "FKCOLUMN_NAME", iVarcharOid, 32); + f[8] = new Field(connection, "KEY_SEQ", iInt2Oid, 2); + f[9] = new Field(connection, "UPDATE_RULE", iInt2Oid, 2); + f[10] = new Field(connection, "DELETE_RULE", iInt2Oid, 2); + f[11] = new Field(connection, "FK_NAME", iVarcharOid, 32); + f[12] = new Field(connection, "PK_NAME", iVarcharOid, 32); + f[13] = new Field(connection, "DEFERRABILITY", iInt2Oid, 2); + + java.sql.ResultSet rs = connection.ExecSQL( + "SELECT distinct " + + "c.relname as prelname, " + + "c2.relname as frelname, " + + "t.tgconstrname, " + + "a.attnum as keyseq, " + + "ic.relname as fkeyname, " + + "t.tgdeferrable, " + + "t.tginitdeferred, " + + "t.tgnargs,t.tgargs, " + + "p1.proname as updaterule, " + + "p2.proname as deleterule " + + "FROM " + + "pg_trigger t, " + + "pg_trigger t1, " + + "pg_class c, " + + "pg_class c2, " + + "pg_class ic, " + + "pg_proc p1, " + + "pg_proc p2, " + + "pg_index i, " + + "pg_attribute a " + + "WHERE " + // isolate the update rule + + "(t.tgrelid=c.oid " + + "AND t.tgisconstraint " + + "AND t.tgconstrrelid=c2.oid " + + "AND t.tgfoid=p1.oid " + + "and p1.proname like '%%upd') " + + + "and " + // isolate the delete rule + + "(t1.tgrelid=c.oid " + + "and t1.tgisconstraint " + + "and t1.tgconstrrelid=c2.oid " + + "AND t1.tgfoid=p2.oid " + + "and p2.proname like '%%del') " + + // if we are looking for exported keys then primary table will be used + + ((primaryTable != null) ? "AND c.relname='" + primaryTable + "' " : "") + + // if we are looking for imported keys then the foreign table will be used + + ((foreignTable != null) ? "AND c2.relname='" + foreignTable + "' " : "") + + "AND i.indrelid=c.oid " + + "AND i.indexrelid=ic.oid " + + "AND ic.oid=a.attrelid " + + "AND i.indisprimary " + + "ORDER BY " + + // orderby is as follows getExported, orders by FKTABLE, + // getImported orders by PKTABLE + // getCrossReference orders by FKTABLE, so this should work for both, + // since when getting crossreference, primaryTable will be defined + + + (primaryTable != null ? "frelname" : "prelname") + ",keyseq"); + +// returns the following columns +// and some example data with a table defined as follows + +// create table people ( id int primary key); +// create table policy ( id int primary key); +// create table users ( id int primary key, people_id int references people(id), policy_id int references policy(id)) + +// prelname | frelname | tgconstrname | keyseq | fkeyName | tgdeferrable | tginitdeferred +// 1 | 2 | 3 | 4 | 5 | 6 | 7 + +// people | users | <unnamed> | 1 | people_pkey | f | f + +// | tgnargs | tgargs | updaterule | deleterule +// | 8 | 9 | 10 | 11 +// | 6 | <unnamed>\000users\000people\000UNSPECIFIED\000people_id\000id\000 | RI_FKey_noaction_upd | RI_FKey_noaction_del + + Vector tuples = new Vector(); + + + while ( rs.next() ) + { + byte tuple[][] = new byte[14][]; + + tuple[2] = rs.getBytes(1); //PKTABLE_NAME + tuple[6] = rs.getBytes(2); //FKTABLE_NAME + String fKeyName = rs.getString(3); + String updateRule = rs.getString(10); + + if (updateRule != null ) + { + // Rules look like this RI_FKey_noaction_del so we want to pull out the part between the 'Key_' and the last '_' s + + String rule = updateRule.substring(8, updateRule.length() - 4); + + int action = java.sql.DatabaseMetaData.importedKeyNoAction; + + if ( rule == null || "noaction".equals(rule) ) + action = java.sql.DatabaseMetaData.importedKeyNoAction; + if ("cascade".equals(rule)) + action = java.sql.DatabaseMetaData.importedKeyCascade; + else if ("setnull".equals(rule)) + action = java.sql.DatabaseMetaData.importedKeySetNull; + else if ("setdefault".equals(rule)) + action = java.sql.DatabaseMetaData.importedKeySetDefault; + else if ("restrict".equals(rule)) + action = java.sql.DatabaseMetaData.importedKeyRestrict; + + tuple[9] = Integer.toString(action).getBytes(); + + } + + String deleteRule = rs.getString(11); + + if ( deleteRule != null ) + { + + String rule = updateRule.substring(8, updateRule.length() - 4); + + int action = java.sql.DatabaseMetaData.importedKeyNoAction; + if ("cascade".equals(rule)) + action = java.sql.DatabaseMetaData.importedKeyCascade; + else if ("setnull".equals(rule)) + action = java.sql.DatabaseMetaData.importedKeySetNull; + else if ("setdefault".equals(rule)) + action = java.sql.DatabaseMetaData.importedKeySetDefault; + tuple[10] = Integer.toString(action).getBytes(); + } + - String fKeyName = rs.getString(3); - boolean foundRule = false; - do - { - String proname = rs.getString(9); - if (proname != null && proname.startsWith("RI_FKey_")) - { - int col = -1; - if (proname.endsWith("_upd")) - col = 9; // UPDATE_RULE - else if (proname.endsWith("_del")) - col = 10; // DELETE_RULE - if (col > -1) - { - String rule = proname.substring(8, proname.length() - 4); - int action = java.sql.DatabaseMetaData.importedKeyNoAction; - if ("cascade".equals(rule)) - action = java.sql.DatabaseMetaData.importedKeyCascade; - else if ("setnull".equals(rule)) - action = java.sql.DatabaseMetaData.importedKeySetNull; - else if ("setdefault".equals(rule)) - action = java.sql.DatabaseMetaData.importedKeySetDefault; - tuple[col] = Integer.toString(action).getBytes(); - - if (!foundRule) - { - tuple[2] = rs.getBytes(1); //PKTABLE_NAME - tuple[6] = rs.getBytes(2); //FKTABLE_NAME - - // Parse the tgargs data - StringBuffer fkeyColumns = new StringBuffer(); - StringBuffer pkeyColumns = new StringBuffer(); - int numColumns = (rs.getInt(7) >> 1) - 2; - String s = rs.getString(8); - int pos = s.lastIndexOf("\\000"); - for (int c = 0;c < numColumns;c++) - { - if (pos > -1) - { - int pos2 = s.lastIndexOf("\\000", pos - 1); - if (pos2 > -1) - { - if (pkeyColumns.length() > 0) - pkeyColumns.insert(0, ','); - pkeyColumns.insert(0, s.substring(pos2 + 4, pos)); //PKCOLUMN_NAME - pos = s.lastIndexOf("\\000", pos2 - 1); - if (pos > -1) - { - if (fkeyColumns.length() > 0) - fkeyColumns.insert(0, ','); - fkeyColumns.insert(0, s.substring(pos + 4, pos2)); //FKCOLUMN_NAME - } - } - } - } - tuple[3] = pkeyColumns.toString().getBytes(); //PKCOLUMN_NAME - tuple[7] = fkeyColumns.toString().getBytes(); //FKCOLUMN_NAME - - tuple[8] = Integer.toString(seq++).getBytes(); //KEY_SEQ - tuple[11] = fKeyName.getBytes(); //FK_NAME - tuple[12] = rs.getBytes(4); //PK_NAME - - // DEFERRABILITY - int deferrability = java.sql.DatabaseMetaData.importedKeyNotDeferrable; - boolean deferrable = rs.getBoolean(5); - boolean initiallyDeferred = rs.getBoolean(6); - if (deferrable) - { - if (initiallyDeferred) - deferrability = java.sql.DatabaseMetaData.importedKeyInitiallyDeferred; - else - deferrability = java.sql.DatabaseMetaData.importedKeyInitiallyImmediate; - } - tuple[13] = Integer.toString(deferrability).getBytes(); - - foundRule = true; - } - } - } - } - while ((hasMore = rs.next()) && fKeyName.equals(rs.getString(3))); + // Parse the tgargs data + String fkeyColumn=""; + String pkeyColumn=""; - if(foundRule) tuples.addElement(tuple); - } - while (hasMore); - } + // Note, I am guessing at most of this, but it should be close + // if not, please correct + // the keys are in pairs and start after the first four arguments + // the arguments are seperated by \000 - return connection.getResultSet(null, f, tuples, "OK", 1); - } + int keySequence = rs.getInt(4); //KEY_SEQ + + // get the args + String targs = rs.getString(9); + + // args look like this + //<unnamed>\000ww\000vv\000UNSPECIFIED\000m\000a\000n\000b\000 + // we are primarily interested in the column names which are the last items in the string + + StringTokenizer st = new StringTokenizer(targs, "\\000"); + + int advance = 4 + (keySequence-1) * 2; + for( int i=0; st.hasMoreTokens() && i < advance ; i++ ) st.nextToken(); // advance to the key column of interest + + if ( st.hasMoreTokens() ) + { + fkeyColumn = st.nextToken(); + } + if ( st.hasMoreTokens() ) + { + pkeyColumn = st.nextToken(); + } + + tuple[3] = pkeyColumn.getBytes(); //PKCOLUMN_NAME + tuple[7] = fkeyColumn.getBytes(); //FKCOLUMN_NAME + + tuple[8] = rs.getBytes(4); //KEY_SEQ + tuple[11] = targs.getBytes(); //FK_NAME this will give us a unique name for the foreign key + tuple[12] = rs.getBytes(5); //PK_NAME + + // DEFERRABILITY + int deferrability = java.sql.DatabaseMetaData.importedKeyNotDeferrable; + boolean deferrable = rs.getBoolean(6); + boolean initiallyDeferred = rs.getBoolean(7); + if (deferrable) + { + if (initiallyDeferred) + deferrability = java.sql.DatabaseMetaData.importedKeyInitiallyDeferred; + else + deferrability = java.sql.DatabaseMetaData.importedKeyInitiallyImmediate; + } + tuple[13] = Integer.toString(deferrability).getBytes(); + + tuples.addElement(tuple); + } + + return connection.getResultSet(null, f, tuples, "OK", 1); + } /* * Get a description of the primary key columns that are |