postgresql-jdbc.git / summary / log / commit / refs

commit    14e64be7dc43feaef210e82fcd9b6089e54e5e4f
Author:   Jorge Solorzano <jorsol@gmail.com>
Commit:   Vladimir Sitnikov <sitnikov.vladimir@gmail.com>
Date:     Mon Nov 14 10:38:36 2016 +0000

    refactor: remove support for postgresql < 8.2 (#661)


.../src/main/java/org/postgresql/PGProperty.java | 10 +- .../java/org/postgresql/core/BaseConnection.java | 56 - .../org/postgresql/core/ConnectionFactory.java | 9 +- .../java/org/postgresql/core/ServerVersion.java | 9 - .../org/postgresql/ds/common/BaseDataSource.java | 16 - .../src/main/java/org/postgresql/jdbc/PgArray.java | 11 +- .../java/org/postgresql/jdbc/PgConnection.java | 166 +-- .../org/postgresql/jdbc/PgDatabaseMetaData.java | 1364 +++++--------------- .../org/postgresql/jdbc/PgPreparedStatement.java | 160 +-- .../main/java/org/postgresql/jdbc/PgResultSet.java | 138 +- .../java/org/postgresql/jdbc/TimestampUtils.java | 24 +- .../java/org/postgresql/jdbc/TypeInfoCache.java | 60 +- .../java/org/postgresql/xa/PGXAConnection.java | 7 - .../test/java/org/postgresql/test/TestUtil.java | 27 +- .../java/org/postgresql/test/jdbc2/ArrayTest.java | 14 +- .../java/org/postgresql/test/jdbc2/BlobTest.java | 3 +- .../postgresql/test/jdbc2/CallableStmtTest.java | 48 +- .../java/org/postgresql/test/jdbc2/CopyTest.java | 13 +- .../test/jdbc2/DatabaseEncodingTest.java | 2 +- .../test/jdbc2/DatabaseMetaDataPropertiesTest.java | 22 +- .../test/jdbc2/DatabaseMetaDataTest.java | 135 +- .../org/postgresql/test/jdbc2/GeometricTest.java | 5 +- .../org/postgresql/test/jdbc2/IntervalTest.java | 10 +- .../org/postgresql/test/jdbc2/Jdbc2TestSuite.java | 6 +- .../java/org/postgresql/test/jdbc2/NotifyTest.java | 3 +- .../java/org/postgresql/test/jdbc2/OID74Test.java | 78 -- .../test/jdbc2/PreparedStatementTest.java | 136 +- .../org/postgresql/test/jdbc2/StatementTest.java | 43 +- .../org/postgresql/test/jdbc2/TimestampTest.java | 3 +- .../org/postgresql/test/jdbc2/TimezoneTest.java | 88 +- .../test/jdbc3/DatabaseMetaDataTest.java | 20 +- .../org/postgresql/test/jdbc3/Jdbc3BlobTest.java | 3 +- .../postgresql/test/jdbc3/Jdbc3SavepointTest.java | 2 +- .../org/postgresql/test/jdbc3/Jdbc3TestSuite.java | 8 +- .../java/org/postgresql/test/jdbc4/ArrayTest.java | 6 +- .../org/postgresql/test/jdbc4/ClientInfoTest.java | 9 +- .../test/jdbc4/DatabaseMetaDataTest.java | 8 +- .../org/postgresql/test/jdbc4/Jdbc4TestSuite.java | 3 +- .../java/org/postgresql/test/jdbc4/JsonbTest.java | 4 +- .../org/postgresql/test/sspi/SSPITestSuite.java | 7 +- .../java/org/postgresql/test/xa/XATestSuite.java | 22 +- 41 files changed, 726 insertions(+), 2032 deletions(-) diff --git a/pgjdbc/src/main/java/org/postgresql/PGProperty.java b/pgjdbc/src/main/java/org/postgresql/PGProperty.java index b949f934..8098ef45 100644 --- a/pgjdbc/src/main/java/org/postgresql/PGProperty.java +++ b/pgjdbc/src/main/java/org/postgresql/PGProperty.java @@ -51,8 +51,8 @@ public enum PGProperty { * fallback. */ PROTOCOL_VERSION("protocolVersion", null, - "Force use of a particular protocol version when connecting, if set, disables protocol version fallback.", - false, "2", "3"), + "Force use of a particular protocol version when connecting, currently only version 3 is supported.", + false, "3"), /** * The loglevel. Can be one of {@link Driver#DEBUG}, {@link Driver#INFO}, {@link Driver#OFF}. @@ -105,12 +105,6 @@ public enum PGProperty { BINARY_TRANSFER("binaryTransfer", "true", "Use binary format for sending and receiving data if possible"), - /** - * Force compatibility of some features with an older version of the driver. - */ - COMPATIBLE("compatible", Driver.MAJORVERSION + "." + Driver.MINORVERSION, - "Force compatibility of some features with an older version of the driver"), - /** * Puts this connection in read-only mode. */ diff --git a/pgjdbc/src/main/java/org/postgresql/core/BaseConnection.java b/pgjdbc/src/main/java/org/postgresql/core/BaseConnection.java index 705cf6da..287bf331 100644 --- a/pgjdbc/src/main/java/org/postgresql/core/BaseConnection.java +++ b/pgjdbc/src/main/java/org/postgresql/core/BaseConnection.java @@ -75,62 +75,6 @@ public interface BaseConnection extends PGConnection, Connection { TypeInfo getTypeInfo(); - /** - * Check if we should use driver behaviour introduced in a particular driver version. This - * defaults to behaving as the actual driver's version but can be overridden by the "compatible" - * URL parameter. - * - * If possible you should use the integer version of this method instead. It was introduced with - * the 9.4 driver release. - * - * @param ver the driver version to check - * @return true if the driver's behavioural version is at least "ver". - * @deprecated Avoid using this in new code that can require PgJDBC 9.4. - */ - @Deprecated - boolean haveMinimumCompatibleVersion(String ver); - - /** - * Check if we should use driver behaviour introduced in a particular driver version. - * - * This defaults to behaving as the actual driver's version but can be overridden by the - * "compatible" URL parameter. - * - * The version is of the form xxyyzz, e.g. 90401 for PgJDBC 9.4.1. - * - * This is used to toggle between different functionality as it changes across different releases - * of the jdbc driver code. The values here are versions of the jdbc client and not server - * versions. For example in 7.1 get/setBytes worked on LargeObject values, in 7.2 these methods - * were changed to work on bytea values. This change in functionality could be disabled by setting - * the "compatible" level to be 7.1, in which case the driver will revert to the 7.1 - * functionality. - * - * @param ver the driver version to check, eg 90401 for 9.4.1 - * @return true if the driver's behavioural version is at least "ver". - */ - boolean haveMinimumCompatibleVersion(int ver); - - /** - * Check if we should use driver behaviour introduced in a particular driver version. - * - * This defaults to behaving as the actual driver's version but can be overridden by the - * "compatible" URL parameter. - * - * @param ver the driver version to check - * @return true if the driver's behavioural version is at least "ver". - */ - boolean haveMinimumCompatibleVersion(Version ver); - - /** - * Check if we have at least a particular server version. - * - * @param ver the server version to check - * @return true if the server version is at least "ver". - * @deprecated Use haveMinimumServerVersion(int) instead - */ - @Deprecated - boolean haveMinimumServerVersion(String ver); - /** * Check if we have at least a particular server version. * diff --git a/pgjdbc/src/main/java/org/postgresql/core/ConnectionFactory.java b/pgjdbc/src/main/java/org/postgresql/core/ConnectionFactory.java index e7f73832..faf77aba 100644 --- a/pgjdbc/src/main/java/org/postgresql/core/ConnectionFactory.java +++ b/pgjdbc/src/main/java/org/postgresql/core/ConnectionFactory.java @@ -29,7 +29,7 @@ public abstract class ConnectionFactory { * If the "protocolVersion" property is specified, only that protocol version is tried. Otherwise, * all protocols are tried in order, falling back to older protocols as necessary. * <p> - * Currently, protocol versions 3 (7.4+) and 2 (pre-7.4) are supported. + * Currently, protocol versions 3 (7.4+) is supported. * * @param hostSpecs at least one host and port to connect to; multiple elements for round-robin * failover @@ -45,11 +45,10 @@ public abstract class ConnectionFactory { String database, Properties info, Logger logger) throws SQLException { String protoName = PGProperty.PROTOCOL_VERSION.get(info); - if (protoName == null || "".equals(protoName) - || "2".equals(protoName) || "3".equals(protoName)) { + if (protoName == null || protoName.isEmpty() || "3".equals(protoName)) { ConnectionFactory connectionFactory = new ConnectionFactoryImpl(); - QueryExecutor queryExecutor = - connectionFactory.openConnectionImpl(hostSpecs, user, database, info, logger); + QueryExecutor queryExecutor = connectionFactory.openConnectionImpl( + hostSpecs, user, database, info, logger); if (queryExecutor != null) { return queryExecutor; } diff --git a/pgjdbc/src/main/java/org/postgresql/core/ServerVersion.java b/pgjdbc/src/main/java/org/postgresql/core/ServerVersion.java index 0c4fbd73..a2d154c9 100644 --- a/pgjdbc/src/main/java/org/postgresql/core/ServerVersion.java +++ b/pgjdbc/src/main/java/org/postgresql/core/ServerVersion.java @@ -14,15 +14,6 @@ import java.text.ParsePosition; public enum ServerVersion implements Version { INVALID("0.0.0"), - v6_4("6.4.0"), - v6_5("6.5.0"), - v7_0("7.0.0"), - v7_1("7.1.0"), - v7_2("7.2.0"), - v7_3("7.3.0"), - v7_4("7.4.0"), - v8_0("8.0.0"), - v8_1("8.1.0"), v8_2("8.2.0"), v8_3("8.3.0"), v8_4("8.4.0"), diff --git a/pgjdbc/src/main/java/org/postgresql/ds/common/BaseDataSource.java b/pgjdbc/src/main/java/org/postgresql/ds/common/BaseDataSource.java index 70525c3e..223b8252 100644 --- a/pgjdbc/src/main/java/org/postgresql/ds/common/BaseDataSource.java +++ b/pgjdbc/src/main/java/org/postgresql/ds/common/BaseDataSource.java @@ -216,22 +216,6 @@ public abstract class BaseDataSource implements Referenceable { this.portNumber = portNumber; } - /** - * @return value of compatible parameter - * @see PGProperty#COMPATIBLE - */ - public String getCompatible() { - return PGProperty.COMPATIBLE.get(properties); - } - - /** - * @param compatible value of compatible parameter - * @see PGProperty#COMPATIBLE - */ - public void setCompatible(String compatible) { - PGProperty.COMPATIBLE.set(properties, compatible); - } - /** * @return login timeout * @see PGProperty#LOGIN_TIMEOUT diff --git a/pgjdbc/src/main/java/org/postgresql/jdbc/PgArray.java b/pgjdbc/src/main/java/org/postgresql/jdbc/PgArray.java index f9024265..f75d0ab2 100644 --- a/pgjdbc/src/main/java/org/postgresql/jdbc/PgArray.java +++ b/pgjdbc/src/main/java/org/postgresql/jdbc/PgArray.java @@ -10,7 +10,6 @@ import org.postgresql.core.BaseStatement; import org.postgresql.core.Encoding; import org.postgresql.core.Field; import org.postgresql.core.Oid; -import org.postgresql.core.ServerVersion; import org.postgresql.jdbc2.ArrayAssistant; import org.postgresql.jdbc2.ArrayAssistantRegistry; import org.postgresql.util.ByteConverter; @@ -85,11 +84,6 @@ public class PgArray implements java.sql.Array { */ private final boolean useObjects; - /** - * Are we connected to an 8.2 or higher server? Only 8.2 or higher supports null array elements. - */ - private final boolean haveMinServer82; - /** * Value of field as {@link PgArrayList}. Will be initialized only once within * {@link #buildArrayList()}. @@ -101,8 +95,7 @@ public class PgArray implements java.sql.Array { private PgArray(BaseConnection connection, int oid) throws SQLException { this.connection = connection; this.oid = oid; - this.useObjects = connection.haveMinimumCompatibleVersion(ServerVersion.v8_3); - this.haveMinServer82 = connection.haveMinimumServerVersion(ServerVersion.v8_2); + this.useObjects = true; } /** @@ -504,7 +497,7 @@ public class PgArray implements java.sql.Array { // add element to current array if (b != null && (!b.isEmpty() || wasInsideString)) { - curArray.add(!wasInsideString && haveMinServer82 && b.equals("NULL") ? null : b); + curArray.add(!wasInsideString && b.equals("NULL") ? null : b); } wasInsideString = false; diff --git a/pgjdbc/src/main/java/org/postgresql/jdbc/PgConnection.java b/pgjdbc/src/main/java/org/postgresql/jdbc/PgConnection.java index 6123b195..a8a68f4b 100644 --- a/pgjdbc/src/main/java/org/postgresql/jdbc/PgConnection.java +++ b/pgjdbc/src/main/java/org/postgresql/jdbc/PgConnection.java @@ -93,8 +93,6 @@ public class PgConnection implements BaseConnection { /* Actual network handler */ private final QueryExecutor queryExecutor; - /* Compatible version as xxyyzz form */ - private final int compatibleInt; /* Query that runs COMMIT */ private final Query commitQuery; @@ -212,13 +210,7 @@ public class PgConnection implements BaseConnection { } // Now make the initial connection and set up local state - this.queryExecutor = - ConnectionFactory.openConnection(hostSpecs, user, database, info, logger); - int compat = Utils.parseServerVersionStr(PGProperty.COMPATIBLE.get(info)); - if (compat == 0) { - compat = Driver.MAJORVERSION * 10000 + Driver.MINORVERSION * 100; - } - this.compatibleInt = compat; + this.queryExecutor = ConnectionFactory.openConnection(hostSpecs, user, database, info, logger); // Set read-only early if requested if (PGProperty.READ_ONLY.getBoolean(info)) { @@ -251,25 +243,6 @@ public class PgConnection implements BaseConnection { binaryOids.add(Oid.BOX); binaryOids.add(Oid.UUID); } - // the pre 8.0 servers do not disclose their internal encoding for - // time fields so do not try to use them. - if (!haveMinimumCompatibleVersion(ServerVersion.v8_0)) { - binaryOids.remove(Oid.TIME); - binaryOids.remove(Oid.TIMETZ); - binaryOids.remove(Oid.TIMESTAMP); - binaryOids.remove(Oid.TIMESTAMPTZ); - } - // driver supports only null-compatible arrays - if (!haveMinimumCompatibleVersion(ServerVersion.v8_3)) { - binaryOids.remove(Oid.INT2_ARRAY); - binaryOids.remove(Oid.INT4_ARRAY); - binaryOids.remove(Oid.INT8_ARRAY); - binaryOids.remove(Oid.FLOAT4_ARRAY); - binaryOids.remove(Oid.FLOAT8_ARRAY); - binaryOids.remove(Oid.FLOAT8_ARRAY); - binaryOids.remove(Oid.VARCHAR_ARRAY); - binaryOids.remove(Oid.TEXT_ARRAY); - } binaryOids.addAll(getOidSet(PGProperty.BINARY_TRANSFER_ENABLE.get(info))); binaryOids.removeAll(getOidSet(PGProperty.BINARY_TRANSFER_DISABLE.get(info))); @@ -291,7 +264,6 @@ public class PgConnection implements BaseConnection { queryExecutor.setBinarySendOids(useBinarySendForOids); if (logger.logDebug()) { - logger.debug(" compatible = " + compatibleInt); logger.debug(" loglevel = " + logLevel); logger.debug(" prepare threshold = " + prepareThreshold); logger.debug(" types using binary send = " + oidsToString(useBinarySendForOids)); @@ -315,18 +287,16 @@ public class PgConnection implements BaseConnection { PSQLState.INVALID_PARAMETER_VALUE); } } else { - bindStringAsVarchar = haveMinimumCompatibleVersion(ServerVersion.v8_0); + bindStringAsVarchar = true; } // Initialize timestamp stuff - timestampUtils = new TimestampUtils(haveMinimumServerVersion(ServerVersion.v7_4), - haveMinimumServerVersion(ServerVersion.v8_2), !queryExecutor.getIntegerDateTimes(), - new Provider<TimeZone>() { - @Override - public TimeZone get() { - return queryExecutor.getTimeZone(); - } - }); + timestampUtils = new TimestampUtils(!queryExecutor.getIntegerDateTimes(), new Provider<TimeZone>() { + @Override + public TimeZone get() { + return queryExecutor.getTimeZone(); + } + }); // Initialize common queries. // isParameterized==true so full parse is performed and the engine knows the query @@ -732,9 +702,9 @@ public class PgConnection implements BaseConnection { PSQLState.ACTIVE_SQL_TRANSACTION); } - if (haveMinimumServerVersion(ServerVersion.v7_4) && readOnly != this.readOnly) { - String readOnlySql = - "SET SESSION CHARACTERISTICS AS TRANSACTION " + (readOnly ? "READ ONLY" : "READ WRITE"); + if (readOnly != this.readOnly) { + String readOnlySql + = "SET SESSION CHARACTERISTICS AS TRANSACTION " + (readOnly ? "READ ONLY" : "READ WRITE"); execSQLUpdate(readOnlySql); // nb: no BEGIN triggered. } @@ -827,52 +797,28 @@ public class PgConnection implements BaseConnection { checkClosed(); String level = null; - - if (haveMinimumServerVersion(ServerVersion.v7_3)) { - // 7.3+ returns the level as a query result. - ResultSet rs = execSQLQuery("SHOW TRANSACTION ISOLATION LEVEL"); // nb: no BEGIN triggered - if (rs.next()) { - level = rs.getString(1); - } - rs.close(); - } else { - // 7.2 returns the level as an INFO message. Ew. - // We juggle the warning chains a bit here. - - // Swap out current warnings. - SQLWarning saveWarnings = getWarnings(); - clearWarnings(); - - // Run the query any examine any resulting warnings. - execSQLUpdate("SHOW TRANSACTION ISOLATION LEVEL"); // nb: no BEGIN triggered - SQLWarning warning = getWarnings(); - if (warning != null) { - level = warning.getMessage(); - } - - // Swap original warnings back. - clearWarnings(); - if (saveWarnings != null) { - addWarning(saveWarnings); - } + final ResultSet rs = execSQLQuery("SHOW TRANSACTION ISOLATION LEVEL"); // nb: no BEGIN triggered + if (rs.next()) { + level = rs.getString(1); } + rs.close(); - // XXX revisit: throw exception instead of silently eating the error in unknown cases? + // TODO revisit: throw exception instead of silently eating the error in unknown cases? if (level == null) { return Connection.TRANSACTION_READ_COMMITTED; // Best guess. } level = level.toUpperCase(Locale.US); - if (level.contains("READ COMMITTED")) { + if (level.equals("READ COMMITTED")) { return Connection.TRANSACTION_READ_COMMITTED; } - if (level.contains("READ UNCOMMITTED")) { + if (level.equals("READ UNCOMMITTED")) { return Connection.TRANSACTION_READ_UNCOMMITTED; } - if (level.contains("REPEATABLE READ")) { + if (level.equals("REPEATABLE READ")) { return Connection.TRANSACTION_REPEATABLE_READ; } - if (level.contains("SERIALIZABLE")) { + if (level.equals("SERIALIZABLE")) { return Connection.TRANSACTION_SERIALIZABLE; } @@ -900,19 +846,18 @@ public class PgConnection implements BaseConnection { } protected String getIsolationLevelName(int level) { - boolean pg80 = haveMinimumServerVersion(ServerVersion.v8_0); - - if (level == Connection.TRANSACTION_READ_COMMITTED) { - return "READ COMMITTED"; - } else if (level == Connection.TRANSACTION_SERIALIZABLE) { - return "SERIALIZABLE"; - } else if (pg80 && level == Connection.TRANSACTION_READ_UNCOMMITTED) { - return "READ UNCOMMITTED"; - } else if (pg80 && level == Connection.TRANSACTION_REPEATABLE_READ) { - return "REPEATABLE READ"; + switch (level) { + case Connection.TRANSACTION_READ_COMMITTED: + return "READ COMMITTED"; + case Connection.TRANSACTION_SERIALIZABLE: + return "SERIALIZABLE"; + case Connection.TRANSACTION_READ_UNCOMMITTED: + return "READ UNCOMMITTED"; + case Connection.TRANSACTION_REPEATABLE_READ: + return "REPEATABLE READ"; + default: + return null; } - - return null; } public void setCatalog(String catalog) throws SQLException { @@ -982,19 +927,6 @@ public class PgConnection implements BaseConnection { } } - @Override - public boolean haveMinimumServerVersion(String ver) { - int requiredver = Utils.parseServerVersionStr(ver); - if (requiredver == 0) { - /* - * Failed to parse input version. Fall back on legacy behaviour for BC. - */ - return (queryExecutor.getServerVersion().compareTo(ver) >= 0); - } else { - return haveMinimumServerVersion(requiredver); - } - } - @Override public boolean haveMinimumServerVersion(int ver) { return queryExecutor.getServerVersionNum() >= ver; @@ -1005,22 +937,6 @@ public class PgConnection implements BaseConnection { return haveMinimumServerVersion(ver.getVersionNum()); } - @Override - public boolean haveMinimumCompatibleVersion(int ver) { - return compatibleInt >= ver; - } - - @Override - public boolean haveMinimumCompatibleVersion(String ver) { - return haveMinimumCompatibleVersion(ServerVersion.from(ver)); - } - - @Override - public boolean haveMinimumCompatibleVersion(Version ver) { - return haveMinimumCompatibleVersion(ver.getVersionNum()); - } - - @Override public Encoding getEncoding() { return queryExecutor.getEncoding(); @@ -1578,12 +1494,9 @@ public class PgConnection implements BaseConnection { @Override public Savepoint setSavepoint() throws SQLException { - String pgName; checkClosed(); - if (!haveMinimumServerVersion(ServerVersion.v8_0)) { - throw new PSQLException(GT.tr("Server versions prior to 8.0 do not support savepoints."), - PSQLState.NOT_IMPLEMENTED); - } + + String pgName; if (getAutoCommit()) { throw new PSQLException(GT.tr("Cannot establish a savepoint in auto-commit mode."), PSQLState.NO_ACTIVE_SQL_TRANSACTION); @@ -1604,10 +1517,7 @@ public class PgConnection implements BaseConnection { @Override public Savepoint setSavepoint(String name) throws SQLException { checkClosed(); - if (!haveMinimumServerVersion(ServerVersion.v8_0)) { - throw new PSQLException(GT.tr("Server versions prior to 8.0 do not support savepoints."), - PSQLState.NOT_IMPLEMENTED); - } + if (getAutoCommit()) { throw new PSQLException(GT.tr("Cannot establish a savepoint in auto-commit mode."), PSQLState.NO_ACTIVE_SQL_TRANSACTION); @@ -1627,10 +1537,6 @@ public class PgConnection implements BaseConnection { @Override public void rollback(Savepoint savepoint) throws SQLException { checkClosed(); - if (!haveMinimumServerVersion(ServerVersion.v8_0)) { - throw new PSQLException(GT.tr("Server versions prior to 8.0 do not support savepoints."), - PSQLState.NOT_IMPLEMENTED); - } PSQLSavepoint pgSavepoint = (PSQLSavepoint) savepoint; execSQLUpdate("ROLLBACK TO SAVEPOINT " + pgSavepoint.getPGName()); @@ -1639,10 +1545,6 @@ public class PgConnection implements BaseConnection { @Override public void releaseSavepoint(Savepoint savepoint) throws SQLException { checkClosed(); - if (!haveMinimumServerVersion(ServerVersion.v8_0)) { - throw new PSQLException(GT.tr("Server versions prior to 8.0 do not support savepoints."), - PSQLState.NOT_IMPLEMENTED); - } PSQLSavepoint pgSavepoint = (PSQLSavepoint) savepoint; execSQLUpdate("RELEASE SAVEPOINT " + pgSavepoint.getPGName()); diff --git a/pgjdbc/src/main/java/org/postgresql/jdbc/PgDatabaseMetaData.java b/pgjdbc/src/main/java/org/postgresql/jdbc/PgDatabaseMetaData.java index 489ddbb2..98f21164 100644 --- a/pgjdbc/src/main/java/org/postgresql/jdbc/PgDatabaseMetaData.java +++ b/pgjdbc/src/main/java/org/postgresql/jdbc/PgDatabaseMetaData.java @@ -55,19 +55,8 @@ public class PgDatabaseMetaData implements DatabaseMetaData { protected int getMaxIndexKeys() throws SQLException { if (INDEX_MAX_KEYS == 0) { String sql; - if (connection.haveMinimumServerVersion(ServerVersion.v8_0)) { - sql = "SELECT setting FROM pg_catalog.pg_settings WHERE name='max_index_keys'"; - } else { - String from; - if (connection.haveMinimumServerVersion(ServerVersion.v7_3)) { - from = - "pg_catalog.pg_namespace n, pg_catalog.pg_type t1, pg_catalog.pg_type t2 WHERE t1.typnamespace=n.oid AND n.nspname='pg_catalog' AND "; - } else { - from = "pg_type t1, pg_type t2 WHERE "; - } - sql = "SELECT t1.typlen/t2.typlen FROM " + from - + " t1.typelem=t2.oid AND t1.typname='oidvector'"; - } + sql = "SELECT setting FROM pg_catalog.pg_settings WHERE name='max_index_keys'"; + Statement stmt = connection.createStatement(); ResultSet rs = null; try { @@ -91,12 +80,9 @@ public class PgDatabaseMetaData implements DatabaseMetaData { protected int getMaxNameLength() throws SQLException { if (NAMEDATALEN == 0) { String sql; - if (connection.haveMinimumServerVersion(ServerVersion.v7_3)) { - sql = - "SELECT t.typlen FROM pg_catalog.pg_type t, pg_catalog.pg_namespace n WHERE t.typnamespace=n.oid AND t.typname='name' AND n.nspname='pg_catalog'"; - } else { - sql = "SELECT typlen FROM pg_type WHERE typname='name'"; - } + sql = "SELECT t.typlen FROM pg_catalog.pg_type t, pg_catalog.pg_namespace n " + + "WHERE t.typnamespace=n.oid AND t.typname='name' AND n.nspname='pg_catalog'"; + Statement stmt = connection.createStatement(); ResultSet rs = null; try { @@ -136,7 +122,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { } public boolean nullsAreSortedHigh() throws SQLException { - return connection.haveMinimumServerVersion(ServerVersion.v7_2); + return true; } public boolean nullsAreSortedLow() throws SQLException { @@ -148,7 +134,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { } public boolean nullsAreSortedAtEnd() throws SQLException { - return !connection.haveMinimumServerVersion(ServerVersion.v7_2); + return false; } /** @@ -305,20 +291,13 @@ public class PgDatabaseMetaData implements DatabaseMetaData { // ','+EscapedFunctions.INSERT+','+EscapedFunctions.LOCATE+ // ','+EscapedFunctions.RIGHT+ - if (connection.haveMinimumServerVersion(ServerVersion.v7_3)) { - funcs += ',' + EscapedFunctions.REPLACE; - } + funcs += ',' + EscapedFunctions.REPLACE; return funcs; } public String getSystemFunctions() throws SQLException { - if (connection.haveMinimumServerVersion(ServerVersion.v7_3)) { - return EscapedFunctions.DATABASE + ',' + EscapedFunctions.IFNULL + ',' - + EscapedFunctions.USER; - } else { - return EscapedFunctions.IFNULL + ',' + EscapedFunctions.USER; - } + return EscapedFunctions.DATABASE + ',' + EscapedFunctions.IFNULL + ',' + EscapedFunctions.USER; } public String getTimeDateFunctions() throws SQLException { @@ -329,9 +308,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { + EscapedFunctions.MONTHNAME + ',' + EscapedFunctions.NOW + ',' + EscapedFunctions.QUARTER + ',' + EscapedFunctions.SECOND + ',' + EscapedFunctions.WEEK + ',' + EscapedFunctions.YEAR; - if (connection.haveMinimumServerVersion(ServerVersion.v8_0)) { - timeDateFuncs += ',' + EscapedFunctions.TIMESTAMPADD; - } + timeDateFuncs += ',' + EscapedFunctions.TIMESTAMPADD; // +','+EscapedFunctions.TIMESTAMPDIFF; @@ -385,7 +362,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { * @return true if connected to PostgreSQL 7.3+ */ public boolean supportsAlterTableWithDropColumn() throws SQLException { - return connection.haveMinimumServerVersion(ServerVersion.v7_3); + return true; } public boolean supportsColumnAliasing() throws SQLException { @@ -422,7 +399,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { * @return true if connected to PostgreSQL 6.4+ */ public boolean supportsOrderByUnrelated() throws SQLException { - return connection.haveMinimumServerVersion(ServerVersion.v6_4); + return true; } public boolean supportsGroupBy() throws SQLException { @@ -435,7 +412,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { * @return true if connected to PostgreSQL 6.4+ */ public boolean supportsGroupByUnrelated() throws SQLException { - return connection.haveMinimumServerVersion(ServerVersion.v6_4); + return true; } /* @@ -444,7 +421,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { * @return true if connected to PostgreSQL 6.4+ */ public boolean supportsGroupByBeyondSelect() throws SQLException { - return connection.haveMinimumServerVersion(ServerVersion.v6_4); + return true; } /* @@ -453,7 +430,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { * @return true if connected to PostgreSQL 7.1+ */ public boolean supportsLikeEscapeClause() throws SQLException { - return connection.haveMinimumServerVersion(ServerVersion.v7_1); + return true; } public boolean supportsMultipleResultSets() throws SQLException { @@ -518,7 +495,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { * @throws SQLException if a database access error occurs */ public boolean supportsANSI92EntryLevelSQL() throws SQLException { - return connection.haveMinimumServerVersion(ServerVersion.v7_3); + return true; } /** @@ -557,7 +534,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { * @return true if connected to PostgreSQL 7.1+ */ public boolean supportsOuterJoins() throws SQLException { - return connection.haveMinimumServerVersion(ServerVersion.v7_1); + return true; } /** @@ -566,7 +543,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { * @return true if connected to PostgreSQL 7.1+ */ public boolean supportsFullOuterJoins() throws SQLException { - return connection.haveMinimumServerVersion(ServerVersion.v7_1); + return true; } /** @@ -575,7 +552,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { * @return true if connected to PostgreSQL 7.1+ */ public boolean supportsLimitedOuterJoins() throws SQLException { - return connection.haveMinimumServerVersion(ServerVersion.v7_1); + return true; } /** @@ -621,7 +598,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { * @return true if connected to PostgreSQL 7.3+ */ public boolean supportsSchemasInDataManipulation() throws SQLException { - return connection.haveMinimumServerVersion(ServerVersion.v7_3); + return true; } /** @@ -630,7 +607,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { * @return true if connected to PostgreSQL 7.3+ */ public boolean supportsSchemasInProcedureCalls() throws SQLException { - return connection.haveMinimumServerVersion(ServerVersion.v7_3); + return true; } /** @@ -639,7 +616,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { * @return true if connected to PostgreSQL 7.3+ */ public boolean supportsSchemasInTableDefinitions() throws SQLException { - return connection.haveMinimumServerVersion(ServerVersion.v7_3); + return true; } /** @@ -648,7 +625,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { * @return true if connected to PostgreSQL 7.3+ */ public boolean supportsSchemasInIndexDefinitions() throws SQLException { - return connection.haveMinimumServerVersion(ServerVersion.v7_3); + return true; } /** @@ -657,7 +634,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { * @return true if connected to PostgreSQL 7.3+ */ public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException { - return connection.haveMinimumServerVersion(ServerVersion.v7_3); + return true; } public boolean supportsCatalogsInDataManipulation() throws SQLException { @@ -700,7 +677,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { * @return true if connected to PostgreSQL 6.5+ */ public boolean supportsSelectForUpdate() throws SQLException { - return connection.haveMinimumServerVersion(ServerVersion.v6_5); + return true; } public boolean supportsStoredProcedures() throws SQLException { @@ -729,7 +706,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { * @return true if connected to PostgreSQL 7.1+ */ public boolean supportsCorrelatedSubqueries() throws SQLException { - return connection.haveMinimumServerVersion(ServerVersion.v7_1); + return true; } /** @@ -747,7 +724,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { * @return true if connected to PostgreSQL 7.1+ */ public boolean supportsUnionAll() throws SQLException { - return connection.haveMinimumServerVersion(ServerVersion.v7_1); + return true; } /** @@ -866,11 +843,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { } public int getMaxRowSize() throws SQLException { - if (connection.haveMinimumServerVersion(ServerVersion.v7_1)) { - return 1073741824; // 1 GB - } else { - return 8192; // XXX could be altered - } + return 1073741824; // 1 GB } public boolean doesMaxRowSizeIncludeBlobs() throws SQLException { @@ -878,11 +851,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { } public int getMaxStatementLength() throws SQLException { - if (connection.haveMinimumServerVersion(ServerVersion.v7_0)) { - return 0; // actually whatever fits in size_t - } else { - return 16384; - } + return 0; // actually whatever fits in size_t } public int getMaxStatements() throws SQLException { @@ -916,15 +885,14 @@ public class PgDatabaseMetaData implements DatabaseMetaData { * READ_UNCOMMITTED and REPEATABLE_READ are accepted aliases for READ_COMMITTED. */ public boolean supportsTransactionIsolationLevel(int level) throws SQLException { - if (level == Connection.TRANSACTION_SERIALIZABLE - || level == Connection.TRANSACTION_READ_COMMITTED) { - return true; - } else if (connection.haveMinimumServerVersion(ServerVersion.v8_0) - && (level == Connection.TRANSACTION_READ_UNCOMMITTED - || level == Connection.TRANSACTION_REPEATABLE_READ)) { - return true; - } else { - return false; + switch (level) { + case Connection.TRANSACTION_READ_UNCOMMITTED: + case Connection.TRANSACTION_READ_COMMITTED: + case Connection.TRANSACTION_REPEATABLE_READ: + case Connection.TRANSACTION_SERIALIZABLE: + return true; + default: + return false; } } @@ -968,13 +936,13 @@ public class PgDatabaseMetaData implements DatabaseMetaData { * includes the single quotes needed around it. * * @param s input value + * * @return string literal for direct inclusion into a query * @throws SQLException if something wrong happens */ protected String escapeQuotes(String s) throws SQLException { StringBuilder sb = new StringBuilder(); - if (!connection.getStandardConformingStrings() - && connection.haveMinimumServerVersion(ServerVersion.v8_1)) { + if (!connection.getStandardConformingStrings()) { sb.append("E"); } sb.append("'"); @@ -983,78 +951,33 @@ public class PgDatabaseMetaData implements DatabaseMetaData { return sb.toString(); } - public ResultSet getProcedures(String catalog, String schemaPattern, - String procedureNamePattern) throws SQLException { - return getProcedures(getJDBCMajorVersion(), catalog, schemaPattern, procedureNamePattern); - } - - protected ResultSet getProcedures(int jdbcVersion, String catalog, String schemaPattern, - String procedureNamePattern) throws SQLException { + public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern) + throws SQLException { String sql; - if (connection.haveMinimumServerVersion(ServerVersion.v7_3)) { - sql = - "SELECT NULL AS PROCEDURE_CAT, n.nspname AS PROCEDURE_SCHEM, p.proname AS PROCEDURE_NAME, NULL, NULL, NULL, d.description AS REMARKS, " - + java.sql.DatabaseMetaData.procedureReturnsResult + " AS PROCEDURE_TYPE "; - if (jdbcVersion >= 4) { - sql += ", p.proname || '_' || p.oid AS SPECIFIC_NAME "; - } - sql += " FROM pg_catalog.pg_namespace n, pg_catalog.pg_proc p " + sql = "SELECT NULL AS PROCEDURE_CAT, n.nspname AS PROCEDURE_SCHEM, p.proname AS PROCEDURE_NAME, " + + "NULL, NULL, NULL, d.description AS REMARKS, " + + DatabaseMetaData.procedureReturnsResult + " AS PROCEDURE_TYPE, " + + " p.proname || '_' || p.oid AS SPECIFIC_NAME " + + " FROM pg_catalog.pg_namespace n, pg_catalog.pg_proc p " + " LEFT JOIN pg_catalog.pg_description d ON (p.oid=d.objoid) " + " LEFT JOIN pg_catalog.pg_class c ON (d.classoid=c.oid AND c.relname='pg_proc') " + " LEFT JOIN pg_catalog.pg_namespace pn ON (c.relnamespace=pn.oid AND pn.nspname='pg_catalog') " + " WHERE p.pronamespace=n.oid "; - if (schemaPattern != null && !"".equals(schemaPattern)) { - sql += " AND n.nspname LIKE " + escapeQuotes(schemaPattern); - } - if (procedureNamePattern != null) { - sql += " AND p.proname LIKE " + escapeQuotes(procedureNamePattern); - } - sql += " ORDER BY PROCEDURE_SCHEM, PROCEDURE_NAME, p.oid::text "; - } else if (connection.haveMinimumServerVersion(ServerVersion.v7_1)) { - sql = - "SELECT NULL AS PROCEDURE_CAT, NULL AS PROCEDURE_SCHEM, p.proname AS PROCEDURE_NAME, NULL, NULL, NULL, d.description AS REMARKS, " - + java.sql.DatabaseMetaData.procedureReturnsResult + " AS PROCEDURE_TYPE "; - if (jdbcVersion >= 4) { - sql += ", p.proname || '_' || p.oid AS SPECIFIC_NAME "; - } - sql += " FROM pg_proc p " - + " LEFT JOIN pg_description d ON (p.oid=d.objoid) "; - if (connection.haveMinimumServerVersion(ServerVersion.v7_2)) { - sql += " LEFT JOIN pg_class c ON (d.classoid=c.oid AND c.relname='pg_proc') "; - } - if (procedureNamePattern != null) { - sql += " WHERE p.proname LIKE " + escapeQuotes(procedureNamePattern); - } - sql += " ORDER BY PROCEDURE_NAME, p.oid::text "; - } else { - sql = - "SELECT NULL AS PROCEDURE_CAT, NULL AS PROCEDURE_SCHEM, p.proname AS PROCEDURE_NAME, NULL, NULL, NULL, NULL AS REMARKS, " - + java.sql.DatabaseMetaData.procedureReturnsResult + " AS PROCEDURE_TYPE "; - if (jdbcVersion >= 4) { - sql += ", p.proname || '_' || p.oid AS SPECIFIC_NAME "; - } - sql += " FROM pg_proc p "; - if (procedureNamePattern != null) { - sql += " WHERE p.proname LIKE " + escapeQuotes(procedureNamePattern); - } - sql += " ORDER BY PROCEDURE_NAME, p.oid::text "; + if (schemaPattern != null && !schemaPattern.isEmpty()) { + sql += " AND n.nspname LIKE " + escapeQuotes(schemaPattern); + } + if (procedureNamePattern != null && !procedureNamePattern.isEmpty()) { + sql += " AND p.proname LIKE " + escapeQuotes(procedureNamePattern); } + sql += " ORDER BY PROCEDURE_SCHEM, PROCEDURE_NAME, p.oid::text "; + return createMetaDataStatement().executeQuery(sql); } public ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern) throws SQLException { - return getProcedureColumns(getJDBCMajorVersion(), catalog, schemaPattern, procedureNamePattern, - columnNamePattern); - } + int columns = 20; - protected ResultSet getProcedureColumns(int jdbcVersion, String catalog, - String schemaPattern, String procedureNamePattern, String columnNamePattern) - throws SQLException { - int columns = 13; - if (jdbcVersion >= 4) { - columns += 7; - } Field f[] = new Field[columns]; List<byte[][]> v = new ArrayList<byte[][]>(); // The new ResultSet tuple stuff @@ -1071,47 +994,26 @@ public class PgDatabaseMetaData implements DatabaseMetaData { f[10] = new Field("RADIX", Oid.INT2); f[11] = new Field("NULLABLE", Oid.INT2); f[12] = new Field("REMARKS", Oid.VARCHAR); - if (jdbcVersion >= 4) { - f[13] = new Field("COLUMN_DEF", Oid.VARCHAR); - f[14] = new Field("SQL_DATA_TYPE", Oid.INT4); - f[15] = new Field("SQL_DATETIME_SUB", Oid.INT4); - f[16] = new Field("CHAR_OCTECT_LENGTH", Oid.INT4); - f[17] = new Field("ORDINAL_POSITION", Oid.INT4); - f[18] = new Field("IS_NULLABLE", Oid.VARCHAR); - f[19] = new Field("SPECIFIC_NAME", Oid.VARCHAR); - } + f[13] = new Field("COLUMN_DEF", Oid.VARCHAR); + f[14] = new Field("SQL_DATA_TYPE", Oid.INT4); + f[15] = new Field("SQL_DATETIME_SUB", Oid.INT4); + f[16] = new Field("CHAR_OCTECT_LENGTH", Oid.INT4); + f[17] = new Field("ORDINAL_POSITION", Oid.INT4); + f[18] = new Field("IS_NULLABLE", Oid.VARCHAR); + f[19] = new Field("SPECIFIC_NAME", Oid.VARCHAR); String sql; - if (connection.haveMinimumServerVersion(ServerVersion.v7_3)) { - sql = "SELECT n.nspname,p.proname,p.prorettype,p.proargtypes, t.typtype,t.typrelid "; - - if (connection.haveMinimumServerVersion(ServerVersion.v8_1)) { - sql += ", p.proargnames, p.proargmodes, p.proallargtypes "; - } else if (connection.haveMinimumServerVersion(ServerVersion.v8_0)) { - sql += ", p.proargnames, NULL AS proargmodes, NULL AS proallargtypes "; - } else { - sql += ", NULL AS proargnames, NULL AS proargmodes, NULL AS proallargtypes "; - } - sql += ", p.oid " + sql = "SELECT n.nspname,p.proname,p.prorettype,p.proargtypes, t.typtype,t.typrelid, " + + " p.proargnames, p.proargmodes, p.proallargtypes, p.oid " + " FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n, pg_catalog.pg_type t " + " WHERE p.pronamespace=n.oid AND p.prorettype=t.oid "; - if (schemaPattern != null && !"".equals(schemaPattern)) { - sql += " AND n.nspname LIKE " + escapeQuotes(schemaPattern); - } - if (procedureNamePattern != null) { - sql += " AND p.proname LIKE " + escapeQuotes(procedureNamePattern); - } - sql += " ORDER BY n.nspname, p.proname, p.oid::text "; - } else { - sql = - "SELECT NULL AS nspname,p.proname,p.prorettype,p.proargtypes,t.typtype,t.typrelid, NULL AS proargnames, NULL AS proargmodes, NULL AS proallargtypes, p.oid " - + " FROM pg_proc p,pg_type t " - + " WHERE p.prorettype=t.oid "; - if (procedureNamePattern != null) { - sql += " AND p.proname LIKE " + escapeQuotes(procedureNamePattern); - } - sql += " ORDER BY p.proname, p.oid::text "; + if (schemaPattern != null && !schemaPattern.isEmpty()) { + sql += " AND n.nspname LIKE " + escapeQuotes(schemaPattern); + } + if (procedureNamePattern != null && !procedureNamePattern.isEmpty()) { + sql += " AND p.proname LIKE " + escapeQuotes(procedureNamePattern); } + sql += " ORDER BY n.nspname, p.proname, p.oid::text "; byte isnullableUnknown[] = new byte[0]; @@ -1150,19 +1052,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { Long allArgTypes[] = null; Array allArgTypesArray = rs.getArray("proallargtypes"); if (allArgTypesArray != null) { - // Depending on what the user has selected we'll get - // either long[] or Long[] back, and there's no - // obvious way for the driver to override this for - // it's own usage. - if (connection.haveMinimumCompatibleVersion(ServerVersion.v8_3)) { - allArgTypes = (Long[]) allArgTypesArray.getArray(); - } else { - long tempAllArgTypes[] = (long[]) allArgTypesArray.getArray(); - allArgTypes = new Long[tempAllArgTypes.length]; - for (int i = 0; i < tempAllArgTypes.length; i++) { - allArgTypes[i] = tempAllArgTypes[i]; - } - } + allArgTypes = (Long[]) allArgTypesArray.getArray(); numArgs = allArgTypes.length; } @@ -1186,11 +1076,10 @@ public class PgDatabaseMetaData implements DatabaseMetaData { tuple[11] = connection .encodeString(Integer.toString(java.sql.DatabaseMetaData.procedureNullableUnknown)); tuple[12] = null; - if (jdbcVersion >= 4) { - tuple[17] = connection.encodeString(Integer.toString(0)); - tuple[18] = isnullableUnknown; - tuple[19] = specificName; - } + tuple[17] = connection.encodeString(Integer.toString(0)); + tuple[18] = isnullableUnknown; + tuple[19] = specificName; + v.add(tuple); } @@ -1235,22 +1124,18 @@ public class PgDatabaseMetaData implements DatabaseMetaData { tuple[11] = connection.encodeString(Integer.toString(DatabaseMetaData.procedureNullableUnknown)); tuple[12] = null; - if (jdbcVersion >= 4) { - tuple[17] = connection.encodeString(Integer.toString(i + 1)); - tuple[18] = isnullableUnknown; - tuple[19] = specificName; - } + tuple[17] = connection.encodeString(Integer.toString(i + 1)); + tuple[18] = isnullableUnknown; + tuple[19] = specificName; + v.add(tuple); } // if we are returning a multi-column result. if (returnTypeType.equals("c") || (returnTypeType.equals("p") && argModesArray != null)) { - String columnsql = "SELECT a.attname,a.atttypid FROM "; - if (connection.haveMinimumServerVersion(ServerVersion.v7_3)) { - columnsql += "pg_catalog."; - } - columnsql += "pg_attribute a WHERE a.attrelid = " + returnTypeRelid - + " AND a.attnum > 0 ORDER BY a.attnum "; + String columnsql = "SELECT a.attname,a.atttypid FROM pg_catalog.pg_attribute a " + + " WHERE a.attrelid = " + returnTypeRelid + + " AND a.attnum > 0 ORDER BY a.attnum "; Statement columnstmt = connection.createStatement(); ResultSet columnrs = columnstmt.executeQuery(columnsql); while (columnrs.next()) { @@ -1272,11 +1157,10 @@ public class PgDatabaseMetaData implements DatabaseMetaData { tuple[11] = connection .encodeString(Integer.toString(java.sql.DatabaseMetaData.procedureNullableUnknown)); tuple[12] = null; - if (jdbcVersion >= 4) { - tuple[17] = connection.encodeString(Integer.toString(0)); - tuple[18] = isnullableUnknown; - tuple[19] = specificName; - } + tuple[17] = connection.encodeString(Integer.toString(0)); + tuple[18] = isnullableUnknown; + tuple[19] = specificName; + v.add(tuple); } columnrs.close(); @@ -1295,116 +1179,54 @@ public class PgDatabaseMetaData implements DatabaseMetaData { String select; String orderby; String useSchemas; - if (connection.haveMinimumServerVersion(ServerVersion.v7_3)) { - useSchemas = "SCHEMAS"; - select = "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, c.relname AS TABLE_NAME, " - + " CASE n.nspname ~ '^pg_' OR n.nspname = 'information_schema' " - + " WHEN true THEN CASE " - + " WHEN n.nspname = 'pg_catalog' OR n.nspname = 'information_schema' THEN CASE c.relkind " - + " WHEN 'r' THEN 'SYSTEM TABLE' " - + " WHEN 'v' THEN 'SYSTEM VIEW' " - + " WHEN 'i' THEN 'SYSTEM INDEX' " - + " ELSE NULL " - + " END " - + " WHEN n.nspname = 'pg_toast' THEN CASE c.relkind " - + " WHEN 'r' THEN 'SYSTEM TOAST TABLE' " - + " WHEN 'i' THEN 'SYSTEM TOAST INDEX' " - + " ELSE NULL " - + " END " - + " ELSE CASE c.relkind " - + " WHEN 'r' THEN 'TEMPORARY TABLE' " - + " WHEN 'i' THEN 'TEMPORARY INDEX' " - + " WHEN 'S' THEN 'TEMPORARY SEQUENCE' " - + " WHEN 'v' THEN 'TEMPORARY VIEW' " - + " ELSE NULL " - + " END " - + " END " - + " WHEN false THEN CASE c.relkind " - + " WHEN 'r' THEN 'TABLE' " - + " WHEN 'i' THEN 'INDEX' " - + " WHEN 'S' THEN 'SEQUENCE' " - + " WHEN 'v' THEN 'VIEW' " - + " WHEN 'c' THEN 'TYPE' " - + " WHEN 'f' THEN 'FOREIGN TABLE' " - + " WHEN 'm' THEN 'MATERIALIZED VIEW' " - + " ELSE NULL " - + " END " - + " ELSE NULL " - + " END " - + " AS TABLE_TYPE, d.description AS REMARKS " - + " FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c " - + " LEFT JOIN pg_catalog.pg_description d ON (c.oid = d.objoid AND d.objsubid = 0) " - + " LEFT JOIN pg_catalog.pg_class dc ON (d.classoid=dc.oid AND dc.relname='pg_class') " - + " LEFT JOIN pg_catalog.pg_namespace dn ON (dn.oid=dc.relnamespace AND dn.nspname='pg_catalog') " - + " WHERE c.relnamespace = n.oid "; - if (schemaPattern != null && !"".equals(schemaPattern)) { - select += " AND n.nspname LIKE " + escapeQuotes(schemaPattern); - } - orderby = " ORDER BY TABLE_TYPE,TABLE_SCHEM,TABLE_NAME "; - } else { - useSchemas = "NOSCHEMAS"; - String tableType = "" - + " CASE c.relname ~ '^pg_' " - + " WHEN true THEN CASE c.relname ~ '^pg_toast_' " - + " WHEN true THEN CASE c.relkind " - + " WHEN 'r' THEN 'SYSTEM TOAST TABLE' " - + " WHEN 'i' THEN 'SYSTEM TOAST INDEX' " - + " ELSE NULL " - + " END " - + " WHEN false THEN CASE c.relname ~ '^pg_temp_' " - + " WHEN true THEN CASE c.relkind " - + " WHEN 'r' THEN 'TEMPORARY TABLE' " - + " WHEN 'i' THEN 'TEMPORARY INDEX' " - + " WHEN 'S' THEN 'TEMPORARY SEQUENCE' " - + " WHEN 'v' THEN 'TEMPORARY VIEW' " - + " ELSE NULL " - + " END " - + " WHEN false THEN CASE c.relkind " - + " WHEN 'r' THEN 'SYSTEM TABLE' " - + " WHEN 'v' THEN 'SYSTEM VIEW' " - + " WHEN 'i' THEN 'SYSTEM INDEX' " - + " ELSE NULL " - + " END " - + " ELSE NULL " - + " END " - + " ELSE NULL " - + " END " - + " WHEN false THEN CASE c.relkind " - + " WHEN 'r' THEN 'TABLE' " - + " WHEN 'i' THEN 'INDEX' " - + " WHEN 'S' THEN 'SEQUENCE' " - + " WHEN 'v' THEN 'VIEW' " - + " WHEN 'c' THEN 'TYPE' " - + " ELSE NULL " - + " END " - + " ELSE NULL " - + " END "; - orderby = " ORDER BY TABLE_TYPE,TABLE_NAME "; - if (connection.haveMinimumServerVersion(ServerVersion.v7_2)) { - select = - "SELECT NULL AS TABLE_CAT, NULL AS TABLE_SCHEM, c.relname AS TABLE_NAME, " + tableType - + " AS TABLE_TYPE, d.description AS REMARKS " - + " FROM pg_class c " - + " LEFT JOIN pg_description d ON (c.oid=d.objoid AND d.objsubid = 0) " - + " LEFT JOIN pg_class dc ON (d.classoid = dc.oid AND dc.relname='pg_class') " - + " WHERE true "; - } else if (connection.haveMinimumServerVersion(ServerVersion.v7_1)) { - select = - "SELECT NULL AS TABLE_CAT, NULL AS TABLE_SCHEM, c.relname AS TABLE_NAME, " + tableType - + " AS TABLE_TYPE, d.description AS REMARKS " - + " FROM pg_class c " - + " LEFT JOIN pg_description d ON (c.oid=d.objoid) " - + " WHERE true "; - } else { - select = - "SELECT NULL AS TABLE_CAT, NULL AS TABLE_SCHEM, c.relname AS TABLE_NAME, " + tableType - + " AS TABLE_TYPE, NULL AS REMARKS " - + " FROM pg_class c " - + " WHERE true "; - } - } - - if (tableNamePattern != null && !"".equals(tableNamePattern)) { + useSchemas = "SCHEMAS"; + select = "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, c.relname AS TABLE_NAME, " + + " CASE n.nspname ~ '^pg_' OR n.nspname = 'information_schema' " + + " WHEN true THEN CASE " + + " WHEN n.nspname = 'pg_catalog' OR n.nspname = 'information_schema' THEN CASE c.relkind " + + " WHEN 'r' THEN 'SYSTEM TABLE' " + + " WHEN 'v' THEN 'SYSTEM VIEW' " + + " WHEN 'i' THEN 'SYSTEM INDEX' " + + " ELSE NULL " + + " END " + + " WHEN n.nspname = 'pg_toast' THEN CASE c.relkind " + + " WHEN 'r' THEN 'SYSTEM TOAST TABLE' " + + " WHEN 'i' THEN 'SYSTEM TOAST INDEX' " + + " ELSE NULL " + + " END " + + " ELSE CASE c.relkind " + + " WHEN 'r' THEN 'TEMPORARY TABLE' " + + " WHEN 'i' THEN 'TEMPORARY INDEX' " + + " WHEN 'S' THEN 'TEMPORARY SEQUENCE' " + + " WHEN 'v' THEN 'TEMPORARY VIEW' " + + " ELSE NULL " + + " END " + + " END " + + " WHEN false THEN CASE c.relkind " + + " WHEN 'r' THEN 'TABLE' " + + " WHEN 'i' THEN 'INDEX' " + + " WHEN 'S' THEN 'SEQUENCE' " + + " WHEN 'v' THEN 'VIEW' " + + " WHEN 'c' THEN 'TYPE' " + + " WHEN 'f' THEN 'FOREIGN TABLE' " + + " WHEN 'm' THEN 'MATERIALIZED VIEW' " + + " ELSE NULL " + + " END " + + " ELSE NULL " + + " END " + + " AS TABLE_TYPE, d.description AS REMARKS " + + " FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c " + + " LEFT JOIN pg_catalog.pg_description d ON (c.oid = d.objoid AND d.objsubid = 0) " + + " LEFT JOIN pg_catalog.pg_class dc ON (d.classoid=dc.oid AND dc.relname='pg_class') " + + " LEFT JOIN pg_catalog.pg_namespace dn ON (dn.oid=dc.relnamespace AND dn.nspname='pg_catalog') " + + " WHERE c.relnamespace = n.oid "; + + if (schemaPattern != null && !schemaPattern.isEmpty()) { + select += " AND n.nspname LIKE " + escapeQuotes(schemaPattern); + } + orderby = " ORDER BY TABLE_TYPE,TABLE_SCHEM,TABLE_NAME "; + + if (tableNamePattern != null && !tableNamePattern.isEmpty()) { select += " AND c.relname LIKE " + escapeQuotes(tableNamePattern); } if (types != null) { @@ -1504,44 +1326,21 @@ public class PgDatabaseMetaData implements DatabaseMetaData { @Override public ResultSet getSchemas() throws SQLException { - return getSchemas(getJDBCMajorVersion(), null, null); + return getSchemas(null, null); } - protected ResultSet getSchemas(int jdbcVersion, String catalog, String schemaPattern) - throws SQLException { + @Override + public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException { String sql; - // Show only the users temp schemas, but not other peoples - // because they can't access any objects in them. - if (connection.haveMinimumServerVersion(ServerVersion.v7_3)) { - // 7.3 can't extract elements from an array returned by - // a function, so we've got to coerce it to text and then - // hack it up with a regex. - String tempSchema = - "substring(textin(array_out(pg_catalog.current_schemas(true))) from '{(pg_temp_[0-9]+),')"; - if (connection.haveMinimumServerVersion(ServerVersion.v7_4)) { - tempSchema = "(pg_catalog.current_schemas(true))[1]"; - } - sql = "SELECT nspname AS TABLE_SCHEM "; - if (jdbcVersion >= 3) { - sql += ", NULL AS TABLE_CATALOG "; - } - sql += - " FROM pg_catalog.pg_namespace WHERE nspname <> 'pg_toast' AND (nspname !~ '^pg_temp_' OR nspname = " - + tempSchema + ") AND (nspname !~ '^pg_toast_temp_' OR nspname = replace(" - + tempSchema + ", 'pg_temp_', 'pg_toast_temp_')) "; - if (schemaPattern != null && !"".equals(schemaPattern)) { - sql += " AND nspname LIKE " + escapeQuotes(schemaPattern); - } - sql += " ORDER BY TABLE_SCHEM"; - } else { - sql = "SELECT ''::text AS TABLE_SCHEM "; - if (jdbcVersion >= 3) { - sql += ", NULL AS TABLE_CATALOG "; - } - if (schemaPattern != null) { - sql += " WHERE ''::text LIKE " + escapeQuotes(schemaPattern); - } + sql = "SELECT nspname AS TABLE_SCHEM, NULL AS TABLE_CATALOG FROM pg_catalog.pg_namespace " + + " WHERE nspname <> 'pg_toast' AND (nspname !~ '^pg_temp_' " + + " OR nspname = (pg_catalog.current_schemas(true))[1]) AND (nspname !~ '^pg_toast_temp_' " + + " OR nspname = replace((pg_catalog.current_schemas(true))[1], 'pg_temp_', 'pg_toast_temp_')) "; + if (schemaPattern != null && !schemaPattern.isEmpty()) { + sql += " AND nspname LIKE " + escapeQuotes(schemaPattern); } + sql += " ORDER BY TABLE_SCHEM"; + return createMetaDataStatement().executeQuery(sql); } @@ -1578,16 +1377,10 @@ public class PgDatabaseMetaData implements DatabaseMetaData { return ((BaseStatement) createMetaDataStatement()).createDriverResultSet(f, v); } - protected ResultSet getColumns(int jdbcVersion, String catalog, String schemaPattern, - String tableNamePattern, String columnNamePattern) throws SQLException { - int numberOfFields; - if (jdbcVersion >= 4) { - numberOfFields = 23; - } else if (jdbcVersion >= 3) { - numberOfFields = 22; - } else { - numberOfFields = 18; - } + public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, + String columnNamePattern) throws SQLException { + + int numberOfFields = 23; // JDBC4 List<byte[][]> v = new ArrayList<byte[][]>(); // The new ResultSet tuple stuff Field f[] = new Field[numberOfFields]; // The field descriptors for the new ResultSet @@ -1609,98 +1402,57 @@ public class PgDatabaseMetaData implements DatabaseMetaData { f[15] = new Field("CHAR_OCTET_LENGTH", Oid.VARCHAR); f[16] = new Field("ORDINAL_POSITION", Oid.INT4); f[17] = new Field("IS_NULLABLE", Oid.VARCHAR); - - if (jdbcVersion >= 3) { - f[18] = new Field("SCOPE_CATLOG", Oid.VARCHAR); - f[19] = new Field("SCOPE_SCHEMA", Oid.VARCHAR); - f[20] = new Field("SCOPE_TABLE", Oid.VARCHAR); - f[21] = new Field("SOURCE_DATA_TYPE", Oid.INT2); - } - - if (jdbcVersion >= 4) { - f[22] = new Field("IS_AUTOINCREMENT", Oid.VARCHAR); - } + f[18] = new Field("SCOPE_CATLOG", Oid.VARCHAR); + f[19] = new Field("SCOPE_SCHEMA", Oid.VARCHAR); + f[20] = new Field("SCOPE_TABLE", Oid.VARCHAR); + f[21] = new Field("SOURCE_DATA_TYPE", Oid.INT2); + f[22] = new Field("IS_AUTOINCREMENT", Oid.VARCHAR); String sql; - if (connection.haveMinimumServerVersion(ServerVersion.v7_3)) { - // a.attnum isn't decremented when preceding columns are dropped, - // so the only way to calculate the correct column number is with - // window functions, new in 8.4. - // - // We want to push as much predicate information below the window - // function as possible (schema/table names), but must leave - // column name outside so we correctly count the other columns. - // - if (connection.haveMinimumServerVersion(ServerVersion.v8_4)) { - sql = "SELECT * FROM ("; - } else { - sql = ""; - } - - sql += - "SELECT n.nspname,c.relname,a.attname,a.atttypid,a.attnotnull OR (t.typtype = 'd' AND t.typnotnull) AS attnotnull,a.atttypmod,a.attlen,"; - - if (connection.haveMinimumServerVersion(ServerVersion.v8_4)) { - sql += "row_number() OVER (PARTITION BY a.attrelid ORDER BY a.attnum) AS attnum, "; - } else { - sql += "a.attnum,"; - } - - sql += - "pg_catalog.pg_get_expr(def.adbin, def.adrelid) AS adsrc,dsc.description,t.typbasetype,t.typtype " - + " FROM pg_catalog.pg_namespace n " - + " JOIN pg_catalog.pg_class c ON (c.relnamespace = n.oid) " - + " JOIN pg_catalog.pg_attribute a ON (a.attrelid=c.oid) " - + " JOIN pg_catalog.pg_type t ON (a.atttypid = t.oid) " - + " LEFT JOIN pg_catalog.pg_attrdef def ON (a.attrelid=def.adrelid AND a.attnum = def.adnum) " - + " LEFT JOIN pg_catalog.pg_description dsc ON (c.oid=dsc.objoid AND a.attnum = dsc.objsubid) " - + " LEFT JOIN pg_catalog.pg_class dc ON (dc.oid=dsc.classoid AND dc.relname='pg_class') " - + " LEFT JOIN pg_catalog.pg_namespace dn ON (dc.relnamespace=dn.oid AND dn.nspname='pg_catalog') " - + " WHERE c.relkind in ('r','v','f','m') and a.attnum > 0 AND NOT a.attisdropped "; - - if (schemaPattern != null && !"".equals(schemaPattern)) { - sql += " AND n.nspname LIKE " + escapeQuotes(schemaPattern); - } - - if (tableNamePattern != null && !"".equals(tableNamePattern)) { - sql += " AND c.relname LIKE " + escapeQuotes(tableNamePattern); - } + // a.attnum isn't decremented when preceding columns are dropped, + // so the only way to calculate the correct column number is with + // window functions, new in 8.4. + // + // We want to push as much predicate information below the window + // function as possible (schema/table names), but must leave + // column name outside so we correctly count the other columns. + // + if (connection.haveMinimumServerVersion(ServerVersion.v8_4)) { + sql = "SELECT * FROM ("; + } else { + sql = ""; + } - if (connection.haveMinimumServerVersion(ServerVersion.v8_4)) { - sql += ") c WHERE true "; - } + sql += "SELECT n.nspname,c.relname,a.attname,a.atttypid,a.attnotnull " + + "OR (t.typtype = 'd' AND t.typnotnull) AS attnotnull,a.atttypmod,a.attlen,"; - } else if (connection.haveMinimumServerVersion(ServerVersion.v7_2)) { - sql = - "SELECT NULL::text AS nspname,c.relname,a.attname,a.atttypid,a.attnotnull,a.atttypmod,a.attlen,a.attnum,pg_get_expr(def.adbin,def.adrelid) AS adsrc,dsc.description,NULL::oid AS typbasetype,t.typtype " - + " FROM pg_class c " - + " JOIN pg_attribute a ON (a.attrelid=c.oid) " - + " JOIN pg_type t ON (a.atttypid = t.oid) " - + " LEFT JOIN pg_attrdef def ON (a.attrelid=def.adrelid AND a.attnum = def.adnum) " - + " LEFT JOIN pg_description dsc ON (c.oid=dsc.objoid AND a.attnum = dsc.objsubid) " - + " LEFT JOIN pg_class dc ON (dc.oid=dsc.classoid AND dc.relname='pg_class') " - + " WHERE c.relkind in ('r','v','f','m') and a.attnum > 0 "; - } else if (connection.haveMinimumServerVersion(ServerVersion.v7_1)) { - sql = - "SELECT NULL::text AS nspname,c.relname,a.attname,a.atttypid,a.attnotnull,a.atttypmod,a.attlen,a.attnum,def.adsrc,dsc.description,NULL::oid AS typbasetype, 'b' AS typtype " - + " FROM pg_class c " - + " JOIN pg_attribute a ON (a.attrelid=c.oid) " - + " LEFT JOIN pg_attrdef def ON (a.attrelid=def.adrelid AND a.attnum = def.adnum) " - + " LEFT JOIN pg_description dsc ON (a.oid=dsc.objoid) " - + " WHERE c.relkind in ('r','v','f','m') and a.attnum > 0 "; + if (connection.haveMinimumServerVersion(ServerVersion.v8_4)) { + sql += "row_number() OVER (PARTITION BY a.attrelid ORDER BY a.attnum) AS attnum, "; } else { - // if < 7.1 then don't get defaults or descriptions. - sql = - "SELECT NULL::text AS nspname,c.relname,a.attname,a.atttypid,a.attnotnull,a.atttypmod,a.attlen,a.attnum,NULL AS adsrc,NULL AS description,NULL AS typbasetype, 'b' AS typtype " - + " FROM pg_class c, pg_attribute a " - + " WHERE c.relkind in ('r','v','f','m') and a.attrelid=c.oid AND a.attnum > 0 "; + sql += "a.attnum,"; } - if (!connection.haveMinimumServerVersion(ServerVersion.v7_3) && tableNamePattern != null - && !"".equals(tableNamePattern)) { + sql += "pg_catalog.pg_get_expr(def.adbin, def.adrelid) AS adsrc,dsc.description,t.typbasetype,t.typtype " + + " FROM pg_catalog.pg_namespace n " + + " JOIN pg_catalog.pg_class c ON (c.relnamespace = n.oid) " + + " JOIN pg_catalog.pg_attribute a ON (a.attrelid=c.oid) " + + " JOIN pg_catalog.pg_type t ON (a.atttypid = t.oid) " + + " LEFT JOIN pg_catalog.pg_attrdef def ON (a.attrelid=def.adrelid AND a.attnum = def.adnum) " + + " LEFT JOIN pg_catalog.pg_description dsc ON (c.oid=dsc.objoid AND a.attnum = dsc.objsubid) " + + " LEFT JOIN pg_catalog.pg_class dc ON (dc.oid=dsc.classoid AND dc.relname='pg_class') " + + " LEFT JOIN pg_catalog.pg_namespace dn ON (dc.relnamespace=dn.oid AND dn.nspname='pg_catalog') " + + " WHERE c.relkind in ('r','v','f','m') and a.attnum > 0 AND NOT a.attisdropped "; + + if (schemaPattern != null && !schemaPattern.isEmpty()) { + sql += " AND n.nspname LIKE " + escapeQuotes(schemaPattern); + } + if (tableNamePattern != null && !tableNamePattern.isEmpty()) { sql += " AND c.relname LIKE " + escapeQuotes(tableNamePattern); } - if (columnNamePattern != null && !"".equals(columnNamePattern)) { + if (connection.haveMinimumServerVersion(ServerVersion.v8_4)) { + sql += ") c WHERE true "; + } + if (columnNamePattern != null && !columnNamePattern.isEmpty()) { sql += " AND attname LIKE " + escapeQuotes(columnNamePattern); } sql += " ORDER BY nspname,c.relname,attnum "; @@ -1776,24 +1528,20 @@ public class PgDatabaseMetaData implements DatabaseMetaData { // Is nullable tuple[17] = connection.encodeString(rs.getBoolean("attnotnull") ? "NO" : "YES"); - if (jdbcVersion >= 3) { - int baseTypeOid = (int) rs.getLong("typbasetype"); + int baseTypeOid = (int) rs.getLong("typbasetype"); - tuple[18] = null; // SCOPE_CATLOG - tuple[19] = null; // SCOPE_SCHEMA - tuple[20] = null; // SCOPE_TABLE - tuple[21] = baseTypeOid == 0 ? null - : connection - .encodeString(Integer.toString(connection.getTypeInfo().getSQLType(baseTypeOid))); // SOURCE_DATA_TYPE - } + tuple[18] = null; // SCOPE_CATLOG + tuple[19] = null; // SCOPE_SCHEMA + tuple[20] = null; // SCOPE_TABLE + tuple[21] = baseTypeOid == 0 + ? null + : connection.encodeString(Integer.toString(connection.getTypeInfo().getSQLType(baseTypeOid))); // SOURCE_DATA_TYPE - if (jdbcVersion >= 4) { - String autoinc = "NO"; - if (defval != null && defval.contains("nextval(")) { - autoinc = "YES"; - } - tuple[22] = connection.encodeString(autoinc); + String autoinc = "NO"; + if (defval != null && defval.contains("nextval(")) { + autoinc = "YES"; } + tuple[22] = connection.encodeString(autoinc); v.add(tuple); } @@ -1803,27 +1551,12 @@ public class PgDatabaseMetaData implements DatabaseMetaData { return ((BaseStatement) createMetaDataStatement()).createDriverResultSet(f, v); } - @Override - public ResultSet getColumns(String catalog, String schemaPattern, - String tableNamePattern, String columnNamePattern) throws SQLException { - return getColumns(getJDBCMajorVersion(), catalog, schemaPattern, tableNamePattern, - columnNamePattern); - } - @Override public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern) throws SQLException { Field f[] = new Field[8]; List<byte[][]> v = new ArrayList<byte[][]>(); - if (table == null) { - table = "%"; - } - - if (columnNamePattern == null) { - columnNamePattern = "%"; - } - f[0] = new Field("TABLE_CAT", Oid.VARCHAR); f[1] = new Field("TABLE_SCHEM", Oid.VARCHAR); f[2] = new Field("TABLE_NAME", Oid.VARCHAR); @@ -1834,39 +1567,24 @@ public class PgDatabaseMetaData implements DatabaseMetaData { f[7] = new Field("IS_GRANTABLE", Oid.VARCHAR); String sql; - if (connection.haveMinimumServerVersion(ServerVersion.v8_4)) { - sql = "SELECT n.nspname,c.relname,r.rolname,c.relacl,a.attacl,a.attname " - + " FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c, pg_catalog.pg_roles r, pg_catalog.pg_attribute a " - + " WHERE c.relnamespace = n.oid " - + " AND c.relowner = r.oid " - + " AND c.oid = a.attrelid " - + " AND c.relkind = 'r' " - + " AND a.attnum > 0 AND NOT a.attisdropped "; - if (schema != null && !"".equals(schema)) { - sql += " AND n.nspname = " + escapeQuotes(schema); - } - } else if (connection.haveMinimumServerVersion(ServerVersion.v7_3)) { - sql = "SELECT n.nspname,c.relname,r.rolname,c.relacl,a.attname " - + " FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c, pg_catalog.pg_roles r, pg_catalog.pg_attribute a " + sql = "SELECT n.nspname,c.relname,r.rolname,c.relacl, " + + (connection.haveMinimumServerVersion(ServerVersion.v8_4) ? "a.attacl, " : "") + + " a.attname " + + " FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c, " + + " pg_catalog.pg_roles r, pg_catalog.pg_attribute a " + " WHERE c.relnamespace = n.oid " + " AND c.relowner = r.oid " + " AND c.oid = a.attrelid " + " AND c.relkind = 'r' " + " AND a.attnum > 0 AND NOT a.attisdropped "; - if (schema != null && !"".equals(schema)) { - sql += " AND n.nspname = " + escapeQuotes(schema); - } - } else { - sql = "SELECT NULL::text AS nspname,c.relname,u.usename,c.relacl,a.attname " - + "FROM pg_class c, pg_user u,pg_attribute a " - + " WHERE u.usesysid = c.relowner " - + " AND c.oid = a.attrelid " - + " AND a.attnum > 0 " - + " AND c.relkind = 'r' "; - } - sql += " AND c.relname = " + escapeQuotes(table); - if (columnNamePattern != null && !"".equals(columnNamePattern)) { + if (schema != null && !schema.isEmpty()) { + sql += " AND n.nspname = " + escapeQuotes(schema); + } + if (table != null && !table.isEmpty()) { + sql += " AND c.relname = " + escapeQuotes(table); + } + if (columnNamePattern != null && !columnNamePattern.isEmpty()) { sql += " AND a.attname LIKE " + escapeQuotes(columnNamePattern); } sql += " ORDER BY attname "; @@ -1933,23 +1651,17 @@ public class PgDatabaseMetaData implements DatabaseMetaData { f[6] = new Field("IS_GRANTABLE", Oid.VARCHAR); String sql; - if (connection.haveMinimumServerVersion(ServerVersion.v7_3)) { - sql = "SELECT n.nspname,c.relname,r.rolname,c.relacl " + sql = "SELECT n.nspname,c.relname,r.rolname,c.relacl " + " FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c, pg_catalog.pg_roles r " + " WHERE c.relnamespace = n.oid " + " AND c.relowner = r.oid " + " AND c.relkind = 'r' "; - if (schemaPattern != null && !"".equals(schemaPattern)) { - sql += " AND n.nspname LIKE " + escapeQuotes(schemaPattern); - } - } else { - sql = "SELECT NULL::text AS nspname,c.relname,u.usename,c.relacl " - + "FROM pg_class c, pg_user u " - + " WHERE u.usesysid = c.relowner " - + " AND c.relkind = 'r' "; + + if (schemaPattern != null && !schemaPattern.isEmpty()) { + sql += " AND n.nspname LIKE " + escapeQuotes(schemaPattern); } - if (tableNamePattern != null && !"".equals(tableNamePattern)) { + if (tableNamePattern != null && !tableNamePattern.isEmpty()) { sql += " AND c.relname LIKE " + escapeQuotes(tableNamePattern); } sql += " ORDER BY nspname, relname "; @@ -2143,15 +1855,10 @@ public class PgDatabaseMetaData implements DatabaseMetaData { */ public Map<String, Map<String, List<String[]>>> parseACL(String aclArray, String owner) { if (aclArray == null) { - // null acl is a shortcut for owner having full privs - String perms = "arwdRxt"; - if (connection.haveMinimumServerVersion(ServerVersion.v8_2)) { - // 8.2 Removed the separate RULE permission - perms = "arwdxt"; - } else if (connection.haveMinimumServerVersion(ServerVersion.v8_4)) { - // 8.4 Added a separate TRUNCATE permission - perms = "arwdDxt"; - } + // arwdxt -- 8.2 Removed the separate RULE permission + // arwdDxt -- 8.4 Added a separate TRUNCATE permission + String perms = connection.haveMinimumServerVersion(ServerVersion.v8_4) ? "arwdDxt" : "arwdxt"; + aclArray = "{" + owner + "=" + perms + "/" + owner + "}"; } @@ -2184,8 +1891,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { */ String sql; - if (connection.haveMinimumServerVersion(ServerVersion.v8_1)) { - sql = "SELECT a.attname, a.atttypid, atttypmod " + sql = "SELECT a.attname, a.atttypid, atttypmod " + "FROM pg_catalog.pg_class ct " + " JOIN pg_catalog.pg_attribute a ON (ct.oid = a.attrelid) " + " JOIN pg_catalog.pg_namespace n ON (ct.relnamespace = n.oid) " @@ -2194,27 +1900,9 @@ public class PgDatabaseMetaData implements DatabaseMetaData { + " FROM pg_catalog.pg_index i) i " + " ON (a.attnum = (i.keys).x AND a.attrelid = i.indrelid) " + "WHERE true "; - if (schema != null && !"".equals(schema)) { - sql += " AND n.nspname = " + escapeQuotes(schema); - } - } else { - String from; - String where = ""; - if (connection.haveMinimumServerVersion(ServerVersion.v7_3)) { - from = - " FROM pg_catalog.pg_namespace n, pg_catalog.pg_class ct, pg_catalog.pg_class ci, pg_catalog.pg_attribute a, pg_catalog.pg_index i "; - where = " AND ct.relnamespace = n.oid "; - if (schema != null && !"".equals(schema)) { - where += " AND n.nspname = " + escapeQuotes(schema); - } - } else { - from = " FROM pg_class ct, pg_class ci, pg_attribute a, pg_index i "; - } - sql = "SELECT a.attname, a.atttypid, a.atttypmod " - + from - + " WHERE ct.oid=i.indrelid AND ci.oid=i.indexrelid " - + " AND a.attrelid=ci.oid " - + where; + + if (schema != null && !schema.isEmpty()) { + sql += " AND n.nspname = " + escapeQuotes(schema); } sql += " AND ct.relname = " + escapeQuotes(table) @@ -2295,8 +1983,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException { String sql; - if (connection.haveMinimumServerVersion(ServerVersion.v8_1)) { - sql = "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, " + sql = "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, " + " ct.relname AS TABLE_NAME, a.attname AS COLUMN_NAME, " + " (i.keys).n AS KEY_SEQ, ci.relname AS PK_NAME " + "FROM pg_catalog.pg_class ct " @@ -2308,39 +1995,12 @@ public class PgDatabaseMetaData implements DatabaseMetaData { + " ON (a.attnum = (i.keys).x AND a.attrelid = i.indrelid) " + " JOIN pg_catalog.pg_class ci ON (ci.oid = i.indexrelid) " + "WHERE true "; - if (schema != null && !"".equals(schema)) { - sql += " AND n.nspname = " + escapeQuotes(schema); - } - } else { - String select; - String from; - String where = ""; - - if (connection.haveMinimumServerVersion(ServerVersion.v7_3)) { - select = "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, "; - from = - " FROM pg_catalog.pg_namespace n, pg_catalog.pg_class ct, pg_catalog.pg_class ci, pg_catalog.pg_attribute a, pg_catalog.pg_index i "; - where = " AND ct.relnamespace = n.oid "; - if (schema != null && !"".equals(schema)) { - where += " AND n.nspname = " + escapeQuotes(schema); - } - } else { - select = "SELECT NULL AS TABLE_CAT, NULL AS TABLE_SCHEM, "; - from = " FROM pg_class ct, pg_class ci, pg_attribute a, pg_index i "; - } - sql = select - + " ct.relname AS TABLE_NAME, " - + " a.attname AS COLUMN_NAME, " - + " a.attnum AS KEY_SEQ, " - + " ci.relname AS PK_NAME " - + from - + " WHERE ct.oid=i.indrelid AND ci.oid=i.indexrelid " - + " AND a.attrelid=ci.oid " - + where; + if (schema != null && !schema.isEmpty()) { + sql += " AND n.nspname = " + escapeQuotes(schema); } - if (table != null && !"".equals(table)) { + if (table != null && !table.isEmpty()) { sql += " AND ct.relname = " + escapeQuotes(table); } @@ -2363,27 +2023,6 @@ public class PgDatabaseMetaData implements DatabaseMetaData { protected ResultSet getImportedExportedKeys(String primaryCatalog, String primarySchema, String primaryTable, String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException { - Field f[] = new Field[14]; - - f[0] = new Field("PKTABLE_CAT", Oid.VARCHAR); - f[1] = new Field("PKTABLE_SCHEM", Oid.VARCHAR); - f[2] = new Field("PKTABLE_NAME", Oid.VARCHAR); - f[3] = new Field("PKCOLUMN_NAME", Oid.VARCHAR); - f[4] = new Field("FKTABLE_CAT", Oid.VARCHAR); - f[5] = new Field("FKTABLE_SCHEM", Oid.VARCHAR); - f[6] = new Field("FKTABLE_NAME", Oid.VARCHAR); - f[7] = new Field("FKCOLUMN_NAME", Oid.VARCHAR); - f[8] = new Field("KEY_SEQ", Oid.INT2); - f[9] = new Field("UPDATE_RULE", Oid.INT2); - f[10] = new Field("DELETE_RULE", Oid.INT2); - f[11] = new Field("FK_NAME", Oid.VARCHAR); - f[12] = new Field("PK_NAME", Oid.VARCHAR); - f[13] = new Field("DEFERRABILITY", Oid.INT2); - - - String select; - String from; - String where = ""; /* * The addition of the pg_constraint in 7.3 table should have really helped us out here, but it @@ -2393,295 +2032,60 @@ public class PgDatabaseMetaData implements DatabaseMetaData { * covering the same keys can be created which make it difficult to determine the PK_NAME field. */ - if (connection.haveMinimumServerVersion(ServerVersion.v7_4)) { - String sql = - "SELECT NULL::text AS PKTABLE_CAT, pkn.nspname AS PKTABLE_SCHEM, pkc.relname AS PKTABLE_NAME, pka.attname AS PKCOLUMN_NAME, " - + "NULL::text AS FKTABLE_CAT, fkn.nspname AS FKTABLE_SCHEM, fkc.relname AS FKTABLE_NAME, fka.attname AS FKCOLUMN_NAME, " - + "pos.n AS KEY_SEQ, " - + "CASE con.confupdtype " - + " WHEN 'c' THEN " + DatabaseMetaData.importedKeyCascade - + " WHEN 'n' THEN " + DatabaseMetaData.importedKeySetNull - + " WHEN 'd' THEN " + DatabaseMetaData.importedKeySetDefault - + " WHEN 'r' THEN " + DatabaseMetaData.importedKeyRestrict - + " WHEN 'a' THEN " + DatabaseMetaData.importedKeyNoAction - + " ELSE NULL END AS UPDATE_RULE, " - + "CASE con.confdeltype " - + " WHEN 'c' THEN " + DatabaseMetaData.importedKeyCascade - + " WHEN 'n' THEN " + DatabaseMetaData.importedKeySetNull - + " WHEN 'd' THEN " + DatabaseMetaData.importedKeySetDefault - + " WHEN 'r' THEN " + DatabaseMetaData.importedKeyRestrict - + " WHEN 'a' THEN " + DatabaseMetaData.importedKeyNoAction - + " ELSE NULL END AS DELETE_RULE, " - + "con.conname AS FK_NAME, pkic.relname AS PK_NAME, " - + "CASE " - + " WHEN con.condeferrable AND con.condeferred THEN " - + DatabaseMetaData.importedKeyInitiallyDeferred - + " WHEN con.condeferrable THEN " + DatabaseMetaData.importedKeyInitiallyImmediate - + " ELSE " + DatabaseMetaData.importedKeyNotDeferrable - + " END AS DEFERRABILITY " - + " FROM " - + " pg_catalog.pg_namespace pkn, pg_catalog.pg_class pkc, pg_catalog.pg_attribute pka, " - + " pg_catalog.pg_namespace fkn, pg_catalog.pg_class fkc, pg_catalog.pg_attribute fka, " - + " pg_catalog.pg_constraint con, "; - if (connection.haveMinimumServerVersion(ServerVersion.v8_0)) { - sql += " pg_catalog.generate_series(1, " + getMaxIndexKeys() + ") pos(n), "; - } else { - sql += " information_schema._pg_keypositions() pos(n), "; - } - sql += " pg_catalog.pg_depend dep, pg_catalog.pg_class pkic " - + " WHERE pkn.oid = pkc.relnamespace AND pkc.oid = pka.attrelid AND pka.attnum = con.confkey[pos.n] AND con.confrelid = pkc.oid " - + " AND fkn.oid = fkc.relnamespace AND fkc.oid = fka.attrelid AND fka.attnum = con.conkey[pos.n] AND con.conrelid = fkc.oid " - + " AND con.contype = 'f' AND con.oid = dep.objid AND pkic.oid = dep.refobjid AND pkic.relkind = 'i' AND dep.classid = 'pg_constraint'::regclass::oid AND dep.refclassid = 'pg_class'::regclass::oid "; - if (primarySchema != null && !"".equals(primarySchema)) { - sql += " AND pkn.nspname = " + escapeQuotes(primarySchema); - } - if (foreignSchema != null && !"".equals(foreignSchema)) { - sql += " AND fkn.nspname = " + escapeQuotes(foreignSchema); - } - if (primaryTable != null && !"".equals(primaryTable)) { - sql += " AND pkc.relname = " + escapeQuotes(primaryTable); - } - if (foreignTable != null && !"".equals(foreignTable)) { - sql += " AND fkc.relname = " + escapeQuotes(foreignTable); - } - - if (primaryTable != null) { - sql += " ORDER BY fkn.nspname,fkc.relname,con.conname,pos.n"; - } else { - sql += " ORDER BY pkn.nspname,pkc.relname, con.conname,pos.n"; - } - - return createMetaDataStatement().executeQuery(sql); - } else if (connection.haveMinimumServerVersion(ServerVersion.v7_3)) { - select = "SELECT DISTINCT n1.nspname as pnspname,n2.nspname as fnspname, "; - from = " FROM pg_catalog.pg_namespace n1 " - + " JOIN pg_catalog.pg_class c1 ON (c1.relnamespace = n1.oid) " - + " JOIN pg_catalog.pg_index i ON (c1.oid=i.indrelid) " - + " JOIN pg_catalog.pg_class ic ON (i.indexrelid=ic.oid) " - + " JOIN pg_catalog.pg_attribute a ON (ic.oid=a.attrelid), " - + " pg_catalog.pg_namespace n2 " - + " JOIN pg_catalog.pg_class c2 ON (c2.relnamespace=n2.oid), " - + " pg_catalog.pg_trigger t1 " - + " JOIN pg_catalog.pg_proc p1 ON (t1.tgfoid=p1.oid), " - + " pg_catalog.pg_trigger t2 " - + " JOIN pg_catalog.pg_proc p2 ON (t2.tgfoid=p2.oid) "; - if (primarySchema != null && !"".equals(primarySchema)) { - where += " AND n1.nspname = " + escapeQuotes(primarySchema); - } - if (foreignSchema != null && !"".equals(foreignSchema)) { - where += " AND n2.nspname = " + escapeQuotes(foreignSchema); - } - } else { - select = "SELECT DISTINCT NULL::text as pnspname, NULL::text as fnspname, "; - from = " FROM pg_class c1 " - + " JOIN pg_index i ON (c1.oid=i.indrelid) " - + " JOIN pg_class ic ON (i.indexrelid=ic.oid) " - + " JOIN pg_attribute a ON (ic.oid=a.attrelid), " - + " pg_class c2, " - + " pg_trigger t1 " - + " JOIN pg_proc p1 ON (t1.tgfoid=p1.oid), " - + " pg_trigger t2 " - + " JOIN pg_proc p2 ON (t2.tgfoid=p2.oid) "; - } - - String sql = select - + "c1.relname as prelname, " - + "c2.relname as frelname, " - + "t1.tgconstrname, " - + "a.attnum as keyseq, " - + "ic.relname as fkeyname, " - + "t1.tgdeferrable, " - + "t1.tginitdeferred, " - + "t1.tgnargs,t1.tgargs, " - + "p1.proname as updaterule, " - + "p2.proname as deleterule " - + from - + "WHERE " - // isolate the update rule - + "(t1.tgrelid=c1.oid " - + "AND t1.tgisconstraint " - + "AND t1.tgconstrrelid=c2.oid " - + "AND p1.proname ~ '^RI_FKey_.*_upd$') " - - + "AND " - // isolate the delete rule - + "(t2.tgrelid=c1.oid " - + "AND t2.tgisconstraint " - + "AND t2.tgconstrrelid=c2.oid " - + "AND p2.proname ~ '^RI_FKey_.*_del$') " - - + "AND i.indisprimary " - + where; - - if (primaryTable != null) { - sql += "AND c1.relname=" + escapeQuotes(primaryTable); + String sql = + "SELECT NULL::text AS PKTABLE_CAT, pkn.nspname AS PKTABLE_SCHEM, pkc.relname AS PKTABLE_NAME, pka.attname AS PKCOLUMN_NAME, " + + "NULL::text AS FKTABLE_CAT, fkn.nspname AS FKTABLE_SCHEM, fkc.relname AS FKTABLE_NAME, fka.attname AS FKCOLUMN_NAME, " + + "pos.n AS KEY_SEQ, " + + "CASE con.confupdtype " + + " WHEN 'c' THEN " + DatabaseMetaData.importedKeyCascade + + " WHEN 'n' THEN " + DatabaseMetaData.importedKeySetNull + + " WHEN 'd' THEN " + DatabaseMetaData.importedKeySetDefault + + " WHEN 'r' THEN " + DatabaseMetaData.importedKeyRestrict + + " WHEN 'a' THEN " + DatabaseMetaData.importedKeyNoAction + + " ELSE NULL END AS UPDATE_RULE, " + + "CASE con.confdeltype " + + " WHEN 'c' THEN " + DatabaseMetaData.importedKeyCascade + + " WHEN 'n' THEN " + DatabaseMetaData.importedKeySetNull + + " WHEN 'd' THEN " + DatabaseMetaData.importedKeySetDefault + + " WHEN 'r' THEN " + DatabaseMetaData.importedKeyRestrict + + " WHEN 'a' THEN " + DatabaseMetaData.importedKeyNoAction + + " ELSE NULL END AS DELETE_RULE, " + + "con.conname AS FK_NAME, pkic.relname AS PK_NAME, " + + "CASE " + + " WHEN con.condeferrable AND con.condeferred THEN " + + DatabaseMetaData.importedKeyInitiallyDeferred + + " WHEN con.condeferrable THEN " + DatabaseMetaData.importedKeyInitiallyImmediate + + " ELSE " + DatabaseMetaData.importedKeyNotDeferrable + + " END AS DEFERRABILITY " + + " FROM " + + " pg_catalog.pg_namespace pkn, pg_catalog.pg_class pkc, pg_catalog.pg_attribute pka, " + + " pg_catalog.pg_namespace fkn, pg_catalog.pg_class fkc, pg_catalog.pg_attribute fka, " + + " pg_catalog.pg_constraint con, " + + " pg_catalog.generate_series(1, " + getMaxIndexKeys() + ") pos(n), " + + " pg_catalog.pg_depend dep, pg_catalog.pg_class pkic " + + " WHERE pkn.oid = pkc.relnamespace AND pkc.oid = pka.attrelid AND pka.attnum = con.confkey[pos.n] AND con.confrelid = pkc.oid " + + " AND fkn.oid = fkc.relnamespace AND fkc.oid = fka.attrelid AND fka.attnum = con.conkey[pos.n] AND con.conrelid = fkc.oid " + + " AND con.contype = 'f' AND con.oid = dep.objid AND pkic.oid = dep.refobjid AND pkic.relkind = 'i' AND dep.classid = 'pg_constraint'::regclass::oid AND dep.refclassid = 'pg_class'::regclass::oid "; + if (primarySchema != null && !primarySchema.isEmpty()) { + sql += " AND pkn.nspname = " + escapeQuotes(primarySchema); + } + if (foreignSchema != null && !foreignSchema.isEmpty()) { + sql += " AND fkn.nspname = " + escapeQuotes(foreignSchema); + } + if (primaryTable != null && !primaryTable.isEmpty()) { + sql += " AND pkc.relname = " + escapeQuotes(primaryTable); + } + if (foreignTable != null && !foreignTable.isEmpty()) { + sql += " AND fkc.relname = " + escapeQuotes(foreignTable); } - if (foreignTable != null) { - sql += "AND c2.relname=" + escapeQuotes(foreignTable); - } - - sql += "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 if (primaryTable != null) { - if (connection.haveMinimumServerVersion(ServerVersion.v7_3)) { - sql += "fnspname,"; - } - sql += "frelname"; + sql += " ORDER BY fkn.nspname,fkc.relname,con.conname,pos.n"; } else { - if (connection.haveMinimumServerVersion(ServerVersion.v7_3)) { - sql += "pnspname,"; - } - sql += "prelname"; + sql += " ORDER BY pkn.nspname,pkc.relname, con.conname,pos.n"; } - sql += ",keyseq"; - - Statement stmt = connection.createStatement(); - ResultSet rs = stmt.executeQuery(sql); - - // 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 - - List<byte[][]> tuples = new ArrayList<byte[][]>(); - - while (rs.next()) { - byte tuple[][] = new byte[14][]; - - tuple[1] = rs.getBytes(1); // PKTABLE_SCHEM - tuple[5] = rs.getBytes(2); // FKTABLE_SCHEM - tuple[2] = rs.getBytes(3); // PKTABLE_NAME - tuple[6] = rs.getBytes(4); // FKTABLE_NAME - String fKeyName = rs.getString(5); - String updateRule = rs.getString(12); - - 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 ("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] = connection.encodeString(Integer.toString(action)); - - } - - String deleteRule = rs.getString(13); - - if (deleteRule != null) { - - String rule = deleteRule.substring(8, deleteRule.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; - } else if ("restrict".equals(rule)) { - action = java.sql.DatabaseMetaData.importedKeyRestrict; - } - tuple[10] = connection.encodeString(Integer.toString(action)); - } - - - int keySequence = rs.getInt(6); // KEY_SEQ - - // Parse the tgargs data - String fkeyColumn = ""; - String pkeyColumn = ""; - String fkName = ""; - // 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 separated by \000 - - String targs = rs.getString(11); - - // 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 - - List<String> tokens = tokenize(targs, "\\000"); - if (!tokens.isEmpty()) { - fkName = tokens.get(0); - } - - if (fkName.startsWith("<unnamed>")) { - fkName = targs; - } - - int element = 4 + (keySequence - 1) * 2; - if (tokens.size() > element) { - fkeyColumn = tokens.get(element); - } - - element++; - if (tokens.size() > element) { - pkeyColumn = tokens.get(element); - } - - tuple[3] = connection.encodeString(pkeyColumn); // PKCOLUMN_NAME - tuple[7] = connection.encodeString(fkeyColumn); // FKCOLUMN_NAME - - tuple[8] = rs.getBytes(6); // KEY_SEQ - // FK_NAME this will give us a unique name for the foreign key - tuple[11] = connection.encodeString(fkName); - tuple[12] = rs.getBytes(7); // PK_NAME - - // DEFERRABILITY - int deferrability = java.sql.DatabaseMetaData.importedKeyNotDeferrable; - boolean deferrable = rs.getBoolean(8); - boolean initiallyDeferred = rs.getBoolean(9); - if (deferrable) { - if (initiallyDeferred) { - deferrability = java.sql.DatabaseMetaData.importedKeyInitiallyDeferred; - } else { - deferrability = java.sql.DatabaseMetaData.importedKeyInitiallyImmediate; - } - } - tuple[13] = connection.encodeString(Integer.toString(deferrability)); - - tuples.add(tuple); - } - rs.close(); - stmt.close(); - - return ((BaseStatement) createMetaDataStatement()).createDriverResultSet(f, tuples); + return createMetaDataStatement().executeQuery(sql); } public ResultSet getImportedKeys(String catalog, String schema, String table) @@ -2726,14 +2130,9 @@ public class PgDatabaseMetaData implements DatabaseMetaData { f[17] = new Field("NUM_PREC_RADIX", Oid.INT4); String sql; - if (connection.haveMinimumServerVersion(ServerVersion.v7_3)) { - sql = "SELECT t.typname,t.oid FROM pg_catalog.pg_type t" + sql = "SELECT t.typname,t.oid FROM pg_catalog.pg_type t" + " JOIN pg_catalog.pg_namespace n ON (t.typnamespace = n.oid) " + " WHERE n.nspname != 'pg_toast'"; - } else { - sql = "SELECT typname,oid FROM pg_type" - + " WHERE NOT (typname ~ '^pg_toast_') "; - } Statement stmt = connection.createStatement(); ResultSet rs = stmt.executeQuery(sql); @@ -2820,49 +2219,48 @@ public class PgDatabaseMetaData implements DatabaseMetaData { String sql; if (connection.haveMinimumServerVersion(ServerVersion.v8_3)) { sql = "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, " - + " ct.relname AS TABLE_NAME, NOT i.indisunique AS NON_UNIQUE, " - + " NULL AS INDEX_QUALIFIER, ci.relname AS INDEX_NAME, " - + " CASE i.indisclustered " - + " WHEN true THEN " + java.sql.DatabaseMetaData.tableIndexClustered - + " ELSE CASE am.amname " - + " WHEN 'hash' THEN " + java.sql.DatabaseMetaData.tableIndexHashed - + " ELSE " + java.sql.DatabaseMetaData.tableIndexOther - + " END " - + " END AS TYPE, " - + " (i.keys).n AS ORDINAL_POSITION, " - + " trim(both '\"' from pg_catalog.pg_get_indexdef(ci.oid, (i.keys).n, false)) AS COLUMN_NAME, " - // TODO: Implement ASC_OR_DESC for PostgreSQL 9.6+ - + (connection.haveMinimumServerVersion(ServerVersion.v9_6) - ? " CASE am.amname " - + " WHEN 'btree' THEN CASE i.indoption[(i.keys).n - 1] & 1 " - + " WHEN 1 THEN 'D' " - + " ELSE 'A' " - + " END " - + " ELSE NULL " - + " END AS ASC_OR_DESC, " - : " CASE am.amcanorder " - + " WHEN true THEN CASE i.indoption[(i.keys).n - 1] & 1 " - + " WHEN 1 THEN 'D' " - + " ELSE 'A' " - + " END " - + " ELSE NULL " - + " END AS ASC_OR_DESC, ") - + " ci.reltuples AS CARDINALITY, " - + " ci.relpages AS PAGES, " - + " pg_catalog.pg_get_expr(i.indpred, i.indrelid) AS FILTER_CONDITION " - + "FROM pg_catalog.pg_class ct " - + " JOIN pg_catalog.pg_namespace n ON (ct.relnamespace = n.oid) " - + " JOIN (SELECT i.indexrelid, i.indrelid, i.indoption, " - + " i.indisunique, i.indisclustered, i.indpred, " - + " i.indexprs, " - + " information_schema._pg_expandarray(i.indkey) AS keys " - + " FROM pg_catalog.pg_index i) i " - + " ON (ct.oid = i.indrelid) " - + " JOIN pg_catalog.pg_class ci ON (ci.oid = i.indexrelid) " - + " JOIN pg_catalog.pg_am am ON (ci.relam = am.oid) " - + "WHERE true "; - - if (schema != null && !"".equals(schema)) { + + " ct.relname AS TABLE_NAME, NOT i.indisunique AS NON_UNIQUE, " + + " NULL AS INDEX_QUALIFIER, ci.relname AS INDEX_NAME, " + + " CASE i.indisclustered " + + " WHEN true THEN " + java.sql.DatabaseMetaData.tableIndexClustered + + " ELSE CASE am.amname " + + " WHEN 'hash' THEN " + java.sql.DatabaseMetaData.tableIndexHashed + + " ELSE " + java.sql.DatabaseMetaData.tableIndexOther + + " END " + + " END AS TYPE, " + + " (i.keys).n AS ORDINAL_POSITION, " + + " trim(both '\"' from pg_catalog.pg_get_indexdef(ci.oid, (i.keys).n, false)) AS COLUMN_NAME, " + + (connection.haveMinimumServerVersion(ServerVersion.v9_6) + ? " CASE am.amname " + + " WHEN 'btree' THEN CASE i.indoption[(i.keys).n - 1] & 1 " + + " WHEN 1 THEN 'D' " + + " ELSE 'A' " + + " END " + + " ELSE NULL " + + " END AS ASC_OR_DESC, " + : " CASE am.amcanorder " + + " WHEN true THEN CASE i.indoption[(i.keys).n - 1] & 1 " + + " WHEN 1 THEN 'D' " + + " ELSE 'A' " + + " END " + + " ELSE NULL " + + " END AS ASC_OR_DESC, ") + + " ci.reltuples AS CARDINALITY, " + + " ci.relpages AS PAGES, " + + " pg_catalog.pg_get_expr(i.indpred, i.indrelid) AS FILTER_CONDITION " + + "FROM pg_catalog.pg_class ct " + + " JOIN pg_catalog.pg_namespace n ON (ct.relnamespace = n.oid) " + + " JOIN (SELECT i.indexrelid, i.indrelid, i.indoption, " + + " i.indisunique, i.indisclustered, i.indpred, " + + " i.indexprs, " + + " information_schema._pg_expandarray(i.indkey) AS keys " + + " FROM pg_catalog.pg_index i) i " + + " ON (ct.oid = i.indrelid) " + + " JOIN pg_catalog.pg_class ci ON (ci.oid = i.indexrelid) " + + " JOIN pg_catalog.pg_am am ON (ci.relam = am.oid) " + + "WHERE true "; + + if (schema != null && !schema.isEmpty()) { sql += " AND n.nspname = " + escapeQuotes(schema); } } else { @@ -2870,64 +2268,35 @@ public class PgDatabaseMetaData implements DatabaseMetaData { String from; String where; - if (connection.haveMinimumServerVersion(ServerVersion.v7_3)) { - select = "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, "; - from = - " FROM pg_catalog.pg_namespace n, pg_catalog.pg_class ct, pg_catalog.pg_class ci, pg_catalog.pg_attribute a, pg_catalog.pg_am am "; - where = " AND n.oid = ct.relnamespace "; + select = "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, "; + from = " FROM pg_catalog.pg_namespace n, pg_catalog.pg_class ct, pg_catalog.pg_class ci, " + + " pg_catalog.pg_attribute a, pg_catalog.pg_am am "; + where = " AND n.oid = ct.relnamespace "; + from += ", pg_catalog.pg_index i "; - if (!connection.haveMinimumServerVersion(ServerVersion.v7_4)) { - from += - ", pg_catalog.pg_attribute ai, pg_catalog.pg_index i LEFT JOIN pg_catalog.pg_proc ip ON (i.indproc = ip.oid) "; - where += " AND ai.attnum = i.indkey[0] AND ai.attrelid = ct.oid "; - } else { - from += ", pg_catalog.pg_index i "; - } - if (schema != null && !"".equals(schema)) { - where += " AND n.nspname = " + escapeQuotes(schema); - } - } else { - select = "SELECT NULL AS TABLE_CAT, NULL AS TABLE_SCHEM, "; - from = - " FROM pg_class ct, pg_class ci, pg_attribute a, pg_am am, pg_attribute ai, pg_index i LEFT JOIN pg_proc ip ON (i.indproc = ip.oid) "; - where = " AND ai.attnum = i.indkey[0] AND ai.attrelid = ct.oid "; + if (schema != null && !schema.isEmpty()) { + where += " AND n.nspname = " + escapeQuotes(schema); } sql = select - + " ct.relname AS TABLE_NAME, NOT i.indisunique AS NON_UNIQUE, NULL AS INDEX_QUALIFIER, ci.relname AS INDEX_NAME, " - + " CASE i.indisclustered " - + " WHEN true THEN " + java.sql.DatabaseMetaData.tableIndexClustered - + " ELSE CASE am.amname " - + " WHEN 'hash' THEN " + java.sql.DatabaseMetaData.tableIndexHashed - + " ELSE " + java.sql.DatabaseMetaData.tableIndexOther - + " END " - + " END AS TYPE, " - + " a.attnum AS ORDINAL_POSITION, "; - - if (connection.haveMinimumServerVersion(ServerVersion.v7_4)) { - sql += - " CASE WHEN i.indexprs IS NULL THEN a.attname ELSE pg_catalog.pg_get_indexdef(ci.oid,a.attnum,false) END AS COLUMN_NAME, "; - } else { - sql += - " CASE i.indproc WHEN 0 THEN a.attname ELSE ip.proname || '(' || ai.attname || ')' END AS COLUMN_NAME, "; - } - - - sql += " NULL AS ASC_OR_DESC, " - + " ci.reltuples AS CARDINALITY, " - + " ci.relpages AS PAGES, "; - - if (connection.haveMinimumServerVersion(ServerVersion.v7_3)) { - sql += " pg_catalog.pg_get_expr(i.indpred, i.indrelid) AS FILTER_CONDITION "; - } else if (connection.haveMinimumServerVersion(ServerVersion.v7_2)) { - sql += " pg_get_expr(i.indpred, i.indrelid) AS FILTER_CONDITION "; - } else { - sql += " NULL AS FILTER_CONDITION "; - } - - sql += from - + " WHERE ct.oid=i.indrelid AND ci.oid=i.indexrelid AND a.attrelid=ci.oid AND ci.relam=am.oid " - + where; + + " ct.relname AS TABLE_NAME, NOT i.indisunique AS NON_UNIQUE, NULL AS INDEX_QUALIFIER, ci.relname AS INDEX_NAME, " + + " CASE i.indisclustered " + + " WHEN true THEN " + java.sql.DatabaseMetaData.tableIndexClustered + + " ELSE CASE am.amname " + + " WHEN 'hash' THEN " + java.sql.DatabaseMetaData.tableIndexHashed + + " ELSE " + java.sql.DatabaseMetaData.tableIndexOther + + " END " + + " END AS TYPE, " + + " a.attnum AS ORDINAL_POSITION, " + + " CASE WHEN i.indexprs IS NULL THEN a.attname " + + " ELSE pg_catalog.pg_get_indexdef(ci.oid,a.attnum,false) END AS COLUMN_NAME, " + + " NULL AS ASC_OR_DESC, " + + " ci.reltuples AS CARDINALITY, " + + " ci.relpages AS PAGES, " + + " pg_catalog.pg_get_expr(i.indpred, i.indrelid) AS FILTER_CONDITION " + + from + + " WHERE ct.oid=i.indrelid AND ci.oid=i.indexrelid AND a.attrelid=ci.oid AND ci.relam=am.oid " + + where; } sql += " AND ct.relname = " + escapeQuotes(tableName); @@ -2936,30 +2305,8 @@ public class PgDatabaseMetaData implements DatabaseMetaData { sql += " AND i.indisunique "; } sql += " ORDER BY NON_UNIQUE, TYPE, INDEX_NAME, ORDINAL_POSITION "; - return createMetaDataStatement().executeQuery(sql); - } - /** - * Tokenize based on words not on single characters. - */ - private static List<String> tokenize(String input, String delimiter) { - List<String> result = new ArrayList<String>(); - int start = 0; - int end = input.length(); - int delimiterSize = delimiter.length(); - - while (start < end) { - int delimiterIndex = input.indexOf(delimiter, start); - if (delimiterIndex < 0) { - result.add(input.substring(start)); - break; - } else { - String token = input.substring(start, delimiterIndex); - result.add(token); - start = delimiterIndex + delimiterSize; - } - } - return result; + return createMetaDataStatement().executeQuery(sql); } // ** JDBC 2 Extensions ** @@ -3131,11 +2478,6 @@ public class PgDatabaseMetaData implements DatabaseMetaData { throw org.postgresql.Driver.notImplemented(this.getClass(), "getRowIdLifetime()"); } - @Override - public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException { - return getSchemas(getJDBCMajorVersion(), catalog, schemaPattern); - } - @Override public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException { return true; @@ -3186,13 +2528,13 @@ public class PgDatabaseMetaData implements DatabaseMetaData { public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern) throws SQLException { - return getProcedures(getJDBCMajorVersion(), catalog, schemaPattern, functionNamePattern); + return getProcedures(catalog, schemaPattern, functionNamePattern); } public ResultSet getFunctionColumns(String catalog, String schemaPattern, - String functionNamePattern, String columnNamePattern) throws SQLException { - return getProcedureColumns(getJDBCMajorVersion(), catalog, schemaPattern, functionNamePattern, - columnNamePattern); + String functionNamePattern, String columnNamePattern) + throws SQLException { + return getProcedureColumns(catalog, schemaPattern, functionNamePattern, columnNamePattern); } public int getJDBCMajorVersion() throws SQLException { @@ -3211,7 +2553,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { } public boolean supportsSavepoints() throws SQLException { - return connection.haveMinimumServerVersion(ServerVersion.v8_0); + return true; } public boolean supportsNamedParameters() throws SQLException { @@ -3226,7 +2568,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData { // We don't support returning generated keys by column index, // but that should be a rarer case than the ones we do support. // - return connection.haveMinimumServerVersion(ServerVersion.v8_2); + return true; } public ResultSet getSuperTypes(String catalog, String schemaPattern, String typeNamePattern) diff --git a/pgjdbc/src/main/java/org/postgresql/jdbc/PgPreparedStatement.java b/pgjdbc/src/main/java/org/postgresql/jdbc/PgPreparedStatement.java index 43766441..ed29d958 100644 --- a/pgjdbc/src/main/java/org/postgresql/jdbc/PgPreparedStatement.java +++ b/pgjdbc/src/main/java/org/postgresql/jdbc/PgPreparedStatement.java @@ -257,11 +257,7 @@ class PgPreparedStatement extends PgStatement implements PreparedStatement { case Types.BINARY: case Types.VARBINARY: case Types.LONGVARBINARY: - if (connection.haveMinimumCompatibleVersion(ServerVersion.v7_2)) { - oid = Oid.BYTEA; - } else { - oid = Oid.OID; - } + oid = Oid.BYTEA; break; case Types.BLOB: case Types.CLOB: @@ -387,20 +383,10 @@ class PgPreparedStatement extends PgStatement implements PreparedStatement { return; } - if (connection.haveMinimumCompatibleVersion(ServerVersion.v7_2)) { - // Version 7.2 supports the bytea datatype for byte arrays - byte[] copy = new byte[x.length]; - System.arraycopy(x, 0, copy, 0, x.length); - preparedParameters.setBytea(parameterIndex, copy, 0, x.length); - } else { - // Version 7.1 and earlier support done as LargeObjects - LargeObjectManager lom = connection.getLargeObjectAPI(); - long oid = lom.createLO(); - LargeObject lob = lom.open(oid); - lob.write(x); - lob.close(); - setLong(parameterIndex, oid); - } + // Version 7.2 supports the bytea datatype for byte arrays + byte[] copy = new byte[x.length]; + System.arraycopy(x, 0, copy, 0, x.length); + preparedParameters.setBytea(parameterIndex, copy, 0, x.length); } public void setDate(int parameterIndex, java.sql.Date x) throws SQLException { @@ -427,7 +413,6 @@ class PgPreparedStatement extends PgStatement implements PreparedStatement { PSQLState.INVALID_PARAMETER_VALUE); } - // Version 7.2 supports AsciiStream for all PG text types (char, varchar, text) // As the spec/javadoc for this method indicate this is to be used for // large String values (i.e. LONGVARCHAR) PG doesn't have a separate @@ -463,24 +448,13 @@ class PgPreparedStatement extends PgStatement implements PreparedStatement { public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException { checkClosed(); - if (connection.haveMinimumCompatibleVersion(ServerVersion.v7_2)) { - setCharacterStreamPost71(parameterIndex, x, length, "ASCII"); - } else { - // Version 7.1 supported only LargeObjects by treating everything - // as binary data - setBinaryStream(parameterIndex, x, length); - } + setCharacterStreamPost71(parameterIndex, x, length, "ASCII"); } public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException { checkClosed(); - if (connection.haveMinimumCompatibleVersion(ServerVersion.v7_2)) { - setCharacterStreamPost71(parameterIndex, x, length, "UTF-8"); - } else { - // Version 7.1 supported only LargeObjects by treating everything - // as binary data - setBinaryStream(parameterIndex, x, length); - } + + setCharacterStreamPost71(parameterIndex, x, length, "UTF-8"); } public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException { @@ -496,41 +470,12 @@ class PgPreparedStatement extends PgStatement implements PreparedStatement { PSQLState.INVALID_PARAMETER_VALUE); } - if (connection.haveMinimumCompatibleVersion(ServerVersion.v7_2)) { - // Version 7.2 supports BinaryStream for for the PG bytea type - // As the spec/javadoc for this method indicate this is to be used for - // large binary values (i.e. LONGVARBINARY) PG doesn't have a separate - // long binary datatype, but with toast the bytea datatype is capable of - // handling very large values. - - preparedParameters.setBytea(parameterIndex, x, length); - } else { - // Version 7.1 only supported streams for LargeObjects - // but the jdbc spec indicates that streams should be - // available for LONGVARBINARY instead - LargeObjectManager lom = connection.getLargeObjectAPI(); - long oid = lom.createLO(); - LargeObject lob = lom.open(oid); - OutputStream los = lob.getOutputStream(); - try { - // could be buffered, but then the OutputStream returned by LargeObject - // is buffered internally anyhow, so there would be no performance - // boost gained, if anything it would be worse! - int c = x.read(); - int p = 0; - while (c > -1 && p < length) { - los.write(c); - c = x.read(); - p++; - } - los.close(); - } catch (IOException se) { - throw new PSQLException(GT.tr("Provided InputStream failed."), PSQLState.UNEXPECTED_ERROR, - se); - } - // lob is closed by the stream so don't call lob.close() - setLong(parameterIndex, oid); - } + // Version 7.2 supports BinaryStream for for the PG bytea type + // As the spec/javadoc for this method indicate this is to be used for + // large binary values (i.e. LONGVARBINARY) PG doesn't have a separate + // long binary datatype, but with toast the bytea datatype is capable of + // handling very large values. + preparedParameters.setBytea(parameterIndex, x, length); } public void clearParameters() throws SQLException { @@ -1067,7 +1012,6 @@ class PgPreparedStatement extends PgStatement implements PreparedStatement { return preparedQuery.query.toString(preparedParameters); } - /** * Note if s is a String it should be escaped by the caller to avoid SQL injection attacks. It is * not done here for efficiency reasons as most calls to this method do not require escaping as @@ -1252,11 +1196,7 @@ class PgPreparedStatement extends PgStatement implements PreparedStatement { checkClosed(); if (x == null) { - if (connection.haveMinimumServerVersion(ServerVersion.v7_2)) { - setNull(i, Types.VARCHAR); - } else { - setNull(i, Types.CLOB); - } + setNull(i, Types.VARCHAR); return; } @@ -1265,60 +1205,32 @@ class PgPreparedStatement extends PgStatement implements PreparedStatement { PSQLState.INVALID_PARAMETER_VALUE); } - if (connection.haveMinimumCompatibleVersion(ServerVersion.v7_2)) { - // Version 7.2 supports CharacterStream for for the PG text types - // As the spec/javadoc for this method indicate this is to be used for - // large text values (i.e. LONGVARCHAR) PG doesn't have a separate - // long varchar datatype, but with toast all the text datatypes are capable of - // handling very large values. Thus the implementation ends up calling - // setString() since there is no current way to stream the value to the server - char[] l_chars = new char[length]; - int l_charsRead = 0; - try { - while (true) { - int n = x.read(l_chars, l_charsRead, length - l_charsRead); - if (n == -1) { - break; - } + // Version 7.2 supports CharacterStream for for the PG text types + // As the spec/javadoc for this method indicate this is to be used for + // large text values (i.e. LONGVARCHAR) PG doesn't have a separate + // long varchar datatype, but with toast all the text datatypes are capable of + // handling very large values. Thus the implementation ends up calling + // setString() since there is no current way to stream the value to the server + char[] l_chars = new char[length]; + int l_charsRead = 0; + try { + while (true) { + int n = x.read(l_chars, l_charsRead, length - l_charsRead); + if (n == -1) { + break; + } - l_charsRead += n; + l_charsRead += n; - if (l_charsRead == length) { - break; - } - } - } catch (IOException l_ioe) { - throw new PSQLException(GT.tr("Provided Reader failed."), PSQLState.UNEXPECTED_ERROR, - l_ioe); - } - setString(i, new String(l_chars, 0, l_charsRead)); - } else { - // Version 7.1 only supported streams for LargeObjects - // but the jdbc spec indicates that streams should be - // available for LONGVARCHAR instead - LargeObjectManager lom = connection.getLargeObjectAPI(); - long oid = lom.createLO(); - LargeObject lob = lom.open(oid); - OutputStream los = lob.getOutputStream(); - try { - // could be buffered, but then the OutputStream returned by LargeObject - // is buffered internally anyhow, so there would be no performance - // boost gained, if anything it would be worse! - int c = x.read(); - int p = 0; - while (c > -1 && p < length) { - los.write(c); - c = x.read(); - p++; + if (l_charsRead == length) { + break; } - los.close(); - } catch (IOException se) { - throw new PSQLException(GT.tr("Unexpected error writing large object to database."), - PSQLState.UNEXPECTED_ERROR, se); } - // lob is closed by the stream so don't call lob.close() - setLong(i, oid); + } catch (IOException l_ioe) { + throw new PSQLException(GT.tr("Provided Reader failed."), PSQLState.UNEXPECTED_ERROR, + l_ioe); } + setString(i, new String(l_chars, 0, l_charsRead)); } public void setClob(int i, Clob x) throws SQLException { diff --git a/pgjdbc/src/main/java/org/postgresql/jdbc/PgResultSet.java b/pgjdbc/src/main/java/org/postgresql/jdbc/PgResultSet.java index 8adb68ac..0ae52a7e 100644 --- a/pgjdbc/src/main/java/org/postgresql/jdbc/PgResultSet.java +++ b/pgjdbc/src/main/java/org/postgresql/jdbc/PgResultSet.java @@ -14,11 +14,8 @@ import org.postgresql.core.Oid; import org.postgresql.core.Query; import org.postgresql.core.ResultCursor; import org.postgresql.core.ResultHandlerBase; -import org.postgresql.core.ServerVersion; import org.postgresql.core.TypeInfo; import org.postgresql.core.Utils; -import org.postgresql.largeobject.LargeObject; -import org.postgresql.largeobject.LargeObjectManager; import org.postgresql.util.ByteConverter; import org.postgresql.util.GT; import org.postgresql.util.HStoreConverter; @@ -432,27 +429,13 @@ public class PgResultSet implements ResultSet, org.postgresql.PGRefCursorResultS return null; } - if (connection.haveMinimumCompatibleVersion(ServerVersion.v7_2)) { - // Version 7.2 supports AsciiStream for all the PG text types - // As the spec/javadoc for this method indicate this is to be used for - // large text values (i.e. LONGVARCHAR) PG doesn't have a separate - // long string datatype, but with toast the text datatype is capable of - // handling very large values. Thus the implementation ends up calling - // getString() since there is no current way to stream the value from the server - return new CharArrayReader(getString(i).toCharArray()); - } else { - // In 7.1 Handle as BLOBS so return the LargeObject input stream - Encoding encoding = connection.getEncoding(); - InputStream input = getBinaryStream(i); - - try { - return encoding.getDecodingReader(input); - } catch (IOException ioe) { - throw new PSQLException( - GT.tr("Unexpected error while decoding character data from a large object."), - PSQLState.UNEXPECTED_ERROR, ioe); - } - } + // Version 7.2 supports AsciiStream for all the PG text types + // As the spec/javadoc for this method indicate this is to be used for + // large text values (i.e. LONGVARCHAR) PG doesn't have a separate + // long string datatype, but with toast the text datatype is capable of + // handling very large values. Thus the implementation ends up calling + // getString() since there is no current way to stream the value from the server + return new CharArrayReader(getString(i).toCharArray()); } @@ -2349,25 +2332,11 @@ public class PgResultSet implements ResultSet, org.postgresql.PGRefCursorResultS if (isBinary(columnIndex)) { // If the data is already binary then just return it return this_row[columnIndex - 1]; - } else if (connection.haveMinimumCompatibleVersion(ServerVersion.v7_2)) { - // Version 7.2 supports the bytea datatype for byte arrays - if (fields[columnIndex - 1].getOID() == Oid.BYTEA) { - return trimBytes(columnIndex, PGbytea.toBytes(this_row[columnIndex - 1])); - } else { - return trimBytes(columnIndex, this_row[columnIndex - 1]); - } + } + if (fields[columnIndex - 1].getOID() == Oid.BYTEA) { + return trimBytes(columnIndex, PGbytea.toBytes(this_row[columnIndex - 1])); } else { - // Version 7.1 and earlier supports LargeObjects for byte arrays - // Handle OID's as BLOBS - if (fields[columnIndex - 1].getOID() == Oid.OID) { - LargeObjectManager lom = connection.getLargeObjectAPI(); - LargeObject lob = lom.open(getLong(columnIndex)); - byte buf[] = lob.read(lob.size()); - lob.close(); - return trimBytes(columnIndex, buf); - } else { - return trimBytes(columnIndex, this_row[columnIndex - 1]); - } + return trimBytes(columnIndex, this_row[columnIndex - 1]); } } @@ -2389,22 +2358,17 @@ public class PgResultSet implements ResultSet, org.postgresql.PGRefCursorResultS return null; } - if (connection.haveMinimumCompatibleVersion(ServerVersion.v7_2)) { - // Version 7.2 supports AsciiStream for all the PG text types - // As the spec/javadoc for this method indicate this is to be used for - // large text values (i.e. LONGVARCHAR) PG doesn't have a separate - // long string datatype, but with toast the text datatype is capable of - // handling very large values. Thus the implementation ends up calling - // getString() since there is no current way to stream the value from the server - try { - return new ByteArrayInputStream(getString(columnIndex).getBytes("ASCII")); - } catch (UnsupportedEncodingException l_uee) { - throw new PSQLException(GT.tr("The JVM claims not to support the encoding: {0}", "ASCII"), - PSQLState.UNEXPECTED_ERROR, l_uee); - } - } else { - // In 7.1 Handle as BLOBS so return the LargeObject input stream - return getBinaryStream(columnIndex); + // Version 7.2 supports AsciiStream for all the PG text types + // As the spec/javadoc for this method indicate this is to be used for + // large text values (i.e. LONGVARCHAR) PG doesn't have a separate + // long string datatype, but with toast the text datatype is capable of + // handling very large values. Thus the implementation ends up calling + // getString() since there is no current way to stream the value from the server + try { + return new ByteArrayInputStream(getString(columnIndex).getBytes("ASCII")); + } catch (UnsupportedEncodingException l_uee) { + throw new PSQLException(GT.tr("The JVM claims not to support the encoding: {0}", "ASCII"), + PSQLState.UNEXPECTED_ERROR, l_uee); } } @@ -2414,22 +2378,17 @@ public class PgResultSet implements ResultSet, org.postgresql.PGRefCursorResultS return null; } - if (connection.haveMinimumCompatibleVersion(ServerVersion.v7_2)) { - // Version 7.2 supports AsciiStream for all the PG text types - // As the spec/javadoc for this method indicate this is to be used for - // large text values (i.e. LONGVARCHAR) PG doesn't have a separate - // long string datatype, but with toast the text datatype is capable of - // handling very large values. Thus the implementation ends up calling - // getString() since there is no current way to stream the value from the server - try { - return new ByteArrayInputStream(getString(columnIndex).getBytes("UTF-8")); - } catch (UnsupportedEncodingException l_uee) { - throw new PSQLException(GT.tr("The JVM claims not to support the encoding: {0}", "UTF-8"), - PSQLState.UNEXPECTED_ERROR, l_uee); - } - } else { - // In 7.1 Handle as BLOBS so return the LargeObject input stream - return getBinaryStream(columnIndex); + // Version 7.2 supports AsciiStream for all the PG text types + // As the spec/javadoc for this method indicate this is to be used for + // large text values (i.e. LONGVARCHAR) PG doesn't have a separate + // long string datatype, but with toast the text datatype is capable of + // handling very large values. Thus the implementation ends up calling + // getString() since there is no current way to stream the value from the server + try { + return new ByteArrayInputStream(getString(columnIndex).getBytes("UTF-8")); + } catch (UnsupportedEncodingException l_uee) { + throw new PSQLException(GT.tr("The JVM claims not to support the encoding: {0}", "UTF-8"), + PSQLState.UNEXPECTED_ERROR, l_uee); } } @@ -2439,24 +2398,15 @@ public class PgResultSet implements ResultSet, org.postgresql.PGRefCursorResultS return null; } - if (connection.haveMinimumCompatibleVersion(ServerVersion.v7_2)) { - // Version 7.2 supports BinaryStream for all PG bytea type - // As the spec/javadoc for this method indicate this is to be used for - // large binary values (i.e. LONGVARBINARY) PG doesn't have a separate - // long binary datatype, but with toast the bytea datatype is capable of - // handling very large values. Thus the implementation ends up calling - // getBytes() since there is no current way to stream the value from the server - byte b[] = getBytes(columnIndex); - if (b != null) { - return new ByteArrayInputStream(b); - } - } else { - // In 7.1 Handle as BLOBS so return the LargeObject input stream - if (fields[columnIndex - 1].getOID() == Oid.OID) { - LargeObjectManager lom = connection.getLargeObjectAPI(); - LargeObject lob = lom.open(getLong(columnIndex)); - return lob.getInputStream(); - } + // Version 7.2 supports BinaryStream for all PG bytea type + // As the spec/javadoc for this method indicate this is to be used for + // large binary values (i.e. LONGVARBINARY) PG doesn't have a separate + // long binary datatype, but with toast the bytea datatype is capable of + // handling very large values. Thus the implementation ends up calling + // getBytes() since there is no current way to stream the value from the server + byte b[] = getBytes(columnIndex); + if (b != null) { + return new ByteArrayInputStream(b); } return null; } @@ -3102,8 +3052,6 @@ public class PgResultSet implements ResultSet, org.postgresql.PGRefCursorResultS } } - ; - // // We need to specify the type of NULL when updating a column to NULL, so // NullObject is a simple extension of PGobject that always returns null @@ -3120,8 +3068,6 @@ public class PgResultSet implements ResultSet, org.postgresql.PGRefCursorResultS } } - ; - /** * Used to add rows to an already existing ResultSet that exactly match the existing rows. * Currently only used for assembling generated keys from batch statement execution. diff --git a/pgjdbc/src/main/java/org/postgresql/jdbc/TimestampUtils.java b/pgjdbc/src/main/java/org/postgresql/jdbc/TimestampUtils.java index 8207f9f1..28bc06be 100644 --- a/pgjdbc/src/main/java/org/postgresql/jdbc/TimestampUtils.java +++ b/pgjdbc/src/main/java/org/postgresql/jdbc/TimestampUtils.java @@ -107,19 +107,13 @@ public class TimestampUtils { private Calendar calCache; private int calCacheZone; - private final boolean min74; - private final boolean min82; - /** * True if the backend uses doubles for time values. False if long is used. */ private final boolean usesDouble; private final Provider<TimeZone> timeZoneProvider; - TimestampUtils(boolean min74, boolean min82, boolean usesDouble, - Provider<TimeZone> timeZoneProvider) { - this.min74 = min74; - this.min82 = min82; + TimestampUtils(boolean usesDouble, Provider<TimeZone> timeZoneProvider) { this.usesDouble = usesDouble; this.timeZoneProvider = timeZoneProvider; } @@ -314,13 +308,11 @@ public class TimestampUtils { } tzsec = 0; - if (min82) { - sep = charAt(s, start); - if (sep == ':') { - end = firstNonDigit(s, start + 1); // Skip ':' - tzsec = number(s, start + 1, end); - start = end; - } + sep = charAt(s, start); + if (sep == ':') { + end = firstNonDigit(s, start + 1); // Skip ':' + tzsec = number(s, start + 1, end); + start = end; } // Setting offset does not seem to work correctly in all @@ -562,7 +554,7 @@ public class TimestampUtils { appendTime(sbuf, cal, cal.get(Calendar.MILLISECOND) * 1000000); // The 'time' parser for <= 7.3 doesn't like timezones. - if (min74 && withTimeZone) { + if (withTimeZone) { appendTimeZone(sbuf, cal); } @@ -649,7 +641,7 @@ public class TimestampUtils { sb.append(NUMBERS[mins]); - if (min82 && secs != 0) { + if (secs != 0) { sb.append(':'); sb.append(NUMBERS[secs]); } diff --git a/pgjdbc/src/main/java/org/postgresql/jdbc/TypeInfoCache.java b/pgjdbc/src/main/java/org/postgresql/jdbc/TypeInfoCache.java index fc047cd9..74d666c6 100644 --- a/pgjdbc/src/main/java/org/postgresql/jdbc/TypeInfoCache.java +++ b/pgjdbc/src/main/java/org/postgresql/jdbc/TypeInfoCache.java @@ -9,7 +9,6 @@ import org.postgresql.core.BaseConnection; import org.postgresql.core.BaseStatement; import org.postgresql.core.Oid; import org.postgresql.core.QueryExecutor; -import org.postgresql.core.ServerVersion; import org.postgresql.core.TypeInfo; import org.postgresql.util.GT; import org.postgresql.util.PGobject; @@ -196,13 +195,12 @@ public class TypeInfoCache implements TypeInfo { // Other types use typelem that aren't actually arrays, like box. // String sql; - if (_conn.haveMinimumServerVersion(ServerVersion.v8_0)) { - // in case of multiple records (in different schemas) choose the one from the current - // schema, - // otherwise take the last version of a type that is at least more deterministic then before - // (keeping old behaviour of finding types, that should not be found without correct search - // path) - sql = "SELECT typinput='array_in'::regproc, typtype " + // in case of multiple records (in different schemas) choose the one from the current + // schema, + // otherwise take the last version of a type that is at least more deterministic then before + // (keeping old behaviour of finding types, that should not be found without correct search + // path) + sql = "SELECT typinput='array_in'::regproc, typtype " + " FROM pg_catalog.pg_type " + " LEFT " + " JOIN (select ns.oid as nspoid, ns.nspname, r.r " @@ -215,12 +213,6 @@ public class TypeInfoCache implements TypeInfo { + " ON sp.nspoid = typnamespace " + " WHERE typname = ? " + " ORDER BY sp.r, pg_type.oid DESC LIMIT 1;"; - } else if (_conn.haveMinimumServerVersion(ServerVersion.v7_3)) { - sql = - "SELECT typinput='array_in'::regproc, typtype FROM pg_catalog.pg_type WHERE typname = ? ORDER BY oid DESC LIMIT 1"; - } else { - sql = "SELECT typinput='array_in'::regproc, typtype FROM pg_type WHERE typname = ? LIMIT 1"; - } _getTypeInfoStatement = _conn.prepareStatement(sql); } @@ -267,10 +259,9 @@ public class TypeInfoCache implements TypeInfo { if (dotIndex == -1 && !hasQuote && !isArray) { if (_getOidStatementSimple == null) { String sql; - if (_conn.haveMinimumServerVersion(ServerVersion.v8_0)) { - // see comments in @getSQLType() - // -- go with older way of unnesting array to be compatible with 8.0 - sql = "SELECT pg_type.oid, typname " + // see comments in @getSQLType() + // -- go with older way of unnesting array to be compatible with 8.0 + sql = "SELECT pg_type.oid, typname " + " FROM pg_catalog.pg_type " + " LEFT " + " JOIN (select ns.oid as nspoid, ns.nspname, r.r " @@ -282,11 +273,6 @@ public class TypeInfoCache implements TypeInfo { + " ON sp.nspoid = typnamespace " + " WHERE typname = ? " + " ORDER BY sp.r, pg_type.oid DESC LIMIT 1;"; - } else if (_conn.haveMinimumServerVersion(ServerVersion.v7_3)) { - sql = "SELECT oid, typname FROM pg_catalog.pg_type WHERE typname = ? ORDER BY oid DESC LIMIT 1"; - } else { - sql = "SELECT oid, typname FROM pg_type WHERE typname = ? ORDER BY oid DESC LIMIT 1"; - } _getOidStatementSimple = _conn.prepareStatement(sql); } // coerce to lower case to handle upper case type names @@ -397,13 +383,9 @@ public class TypeInfoCache implements TypeInfo { if (_getNameStatement == null) { String sql; - if (_conn.haveMinimumServerVersion(ServerVersion.v7_3)) { - sql = - "SELECT n.nspname = ANY(current_schemas(true)), n.nspname, t.typname FROM pg_catalog.pg_type t JOIN pg_catalog.pg_namespace n ON t.typnamespace = n.oid WHERE t.oid = ?"; - } else { - sql = - "SELECT n.nspname = ANY(current_schemas(true)), n.nspname, t.typname FROM pg_type t JOIN pg_namespace n ON t.typnamespace = n.oid WHERE t.oid = ?"; - } + sql = "SELECT n.nspname = ANY(current_schemas(true)), n.nspname, t.typname " + + "FROM pg_catalog.pg_type t " + + "JOIN pg_catalog.pg_namespace n ON t.typnamespace = n.oid WHERE t.oid = ?"; _getNameStatement = _conn.prepareStatement(sql); } @@ -475,12 +457,8 @@ public class TypeInfoCache implements TypeInfo { if (_getArrayDelimiterStatement == null) { String sql; - if (_conn.haveMinimumServerVersion(ServerVersion.v7_3)) { - sql = - "SELECT e.typdelim FROM pg_catalog.pg_type t, pg_catalog.pg_type e WHERE t.oid = ? and t.typelem = e.oid"; - } else { - sql = "SELECT e.typdelim FROM pg_type t, pg_type e WHERE t.oid = ? and t.typelem = e.oid"; - } + sql = "SELECT e.typdelim FROM pg_catalog.pg_type t, pg_catalog.pg_type e " + + "WHERE t.oid = ? and t.typelem = e.oid"; _getArrayDelimiterStatement = _conn.prepareStatement(sql); } @@ -520,13 +498,9 @@ public class TypeInfoCache implements TypeInfo { if (_getArrayElementOidStatement == null) { String sql; - if (_conn.haveMinimumServerVersion(ServerVersion.v7_3)) { - sql = - "SELECT e.oid, n.nspname = ANY(current_schemas(true)), n.nspname, e.typname FROM pg_catalog.pg_type t JOIN pg_catalog.pg_type e ON t.typelem = e.oid JOIN pg_catalog.pg_namespace n ON t.typnamespace = n.oid WHERE t.oid = ?"; - } else { - sql = - "SELECT e.oid, n.nspname = ANY(current_schemas(true)), n.nspname, e.typname FROM pg_type t JOIN pg_type e ON t.typelem = e.oid JOIN pg_namespace n ON t.typnamespace = n.oid WHERE t.oid = ?"; - } + sql = "SELECT e.oid, n.nspname = ANY(current_schemas(true)), n.nspname, e.typname " + + "FROM pg_catalog.pg_type t JOIN pg_catalog.pg_type e ON t.typelem = e.oid " + + "JOIN pg_catalog.pg_namespace n ON t.typnamespace = n.oid WHERE t.oid = ?"; _getArrayElementOidStatement = _conn.prepareStatement(sql); } diff --git a/pgjdbc/src/main/java/org/postgresql/xa/PGXAConnection.java b/pgjdbc/src/main/java/org/postgresql/xa/PGXAConnection.java index 67dfeea0..d57f293d 100644 --- a/pgjdbc/src/main/java/org/postgresql/xa/PGXAConnection.java +++ b/pgjdbc/src/main/java/org/postgresql/xa/PGXAConnection.java @@ -8,7 +8,6 @@ package org.postgresql.xa; import org.postgresql.PGConnection; import org.postgresql.core.BaseConnection; import org.postgresql.core.Logger; -import org.postgresql.core.ServerVersion; import org.postgresql.core.TransactionState; import org.postgresql.ds.PGPooledConnection; import org.postgresql.util.GT; @@ -310,12 +309,6 @@ public class PGXAConnection extends PGPooledConnection implements XAConnection, state = STATE_IDLE; currentXid = null; - if (!conn.haveMinimumServerVersion(ServerVersion.v8_1)) { - throw new PGXAException( - GT.tr("Server versions prior to 8.1 do not support two-phase commit."), - XAException.XAER_RMERR); - } - try { String s = RecoveredXid.xidToString(xid); diff --git a/pgjdbc/src/test/java/org/postgresql/test/TestUtil.java b/pgjdbc/src/test/java/org/postgresql/test/TestUtil.java index c733a2ab..63feb9fb 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/TestUtil.java +++ b/pgjdbc/src/test/java/org/postgresql/test/TestUtil.java @@ -6,7 +6,6 @@ package org.postgresql.test; import org.postgresql.PGProperty; -import org.postgresql.core.ServerVersion; import org.postgresql.core.Version; import org.postgresql.jdbc.PgConnection; @@ -333,10 +332,8 @@ public class TestUtil { public static void dropSchema(Connection con, String schema) throws SQLException { Statement stmt = con.createStatement(); try { - String sql = "DROP SCHEMA " + schema; - if (haveMinimumServerVersion(con, ServerVersion.v7_3)) { - sql += " CASCADE "; - } + String sql = "DROP SCHEMA " + schema + " CASCADE "; + stmt.executeUpdate(sql); } catch (SQLException ex) { // Since every create schema issues a drop schema @@ -368,13 +365,8 @@ public class TestUtil { dropTable(con, table); // Now create the table - String sql = "CREATE TABLE " + table + " (" + columns + ") "; + String sql = "CREATE TABLE " + table + " (" + columns + ") WITH OIDS"; - // Starting with 8.0 oids may be turned off by default. - // Some tests need them, so they flag that here. - if (withOids && haveMinimumServerVersion(con, ServerVersion.v8_0)) { - sql += " WITH OIDS"; - } st.executeUpdate(sql); } finally { closeQuietly(st); @@ -507,10 +499,7 @@ public class TestUtil { public static void dropTable(Connection con, String table) throws SQLException { Statement stmt = con.createStatement(); try { - String sql = "DROP TABLE " + table; - if (haveMinimumServerVersion(con, ServerVersion.v7_3)) { - sql += " CASCADE "; - } + String sql = "DROP TABLE " + table + " CASCADE "; stmt.executeUpdate(sql); } catch (SQLException ex) { // Since every create table issues a drop table @@ -625,14 +614,6 @@ public class TestUtil { * version. This is convenient because we are working with a java.sql.Connection, not an Postgres * connection. */ - public static boolean haveMinimumServerVersion(Connection con, String version) - throws SQLException { - if (con instanceof PgConnection) { - return ((PgConnection) con).haveMinimumServerVersion(version); - } - return false; - } - public static boolean haveMinimumServerVersion(Connection con, int version) throws SQLException { if (con instanceof PgConnection) { return ((PgConnection) con).haveMinimumServerVersion(version); diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/ArrayTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/ArrayTest.java index 5f8aa77f..d35972d2 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/ArrayTest.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/ArrayTest.java @@ -252,10 +252,6 @@ public class ArrayTest extends BaseTest4 { @Test public void testNullValues() throws SQLException { - if (!TestUtil.haveMinimumServerVersion(conn, "8.2")) { - return; - } - Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT ARRAY[1,NULL,3]"); Assert.assertTrue(rs.next()); @@ -344,20 +340,14 @@ public class ArrayTest extends BaseTest4 { String s[] = (String[]) arr.getArray(); Assert.assertEquals(2, s.length); Assert.assertEquals("a", s[0]); - if (TestUtil.haveMinimumServerVersion(conn, "8.2")) { - Assert.assertNull(s[1]); - } else { - Assert.assertEquals("NULL", s[1]); - } + Assert.assertNull(s[1]); } @Test public void testEscaping() throws SQLException { Statement stmt = conn.createStatement(); String sql = "SELECT "; - if (TestUtil.haveMinimumServerVersion(conn, "8.1")) { - sql += 'E'; - } + sql += 'E'; // Uggg. Three levels of escaping: Java, string literal, array. sql += "'{{c\\\\\"d, ''}, {\"\\\\\\\\\",\"''\"}}'::text[]"; diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/BlobTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/BlobTest.java index 696c647f..8e53f40a 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/BlobTest.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/BlobTest.java @@ -5,6 +5,7 @@ package org.postgresql.test.jdbc2; +import org.postgresql.core.ServerVersion; import org.postgresql.largeobject.LargeObject; import org.postgresql.largeobject.LargeObjectManager; import org.postgresql.test.TestUtil; @@ -210,7 +211,7 @@ public class BlobTest extends TestCase { } public void testLargeLargeObject() throws Exception { - if (!TestUtil.haveMinimumServerVersion(con, "9.3")) { + if (!TestUtil.haveMinimumServerVersion(con, ServerVersion.v9_3)) { return; } diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/CallableStmtTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/CallableStmtTest.java index 5f280694..bc69602f 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/CallableStmtTest.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/CallableStmtTest.java @@ -35,36 +35,44 @@ public class CallableStmtTest extends BaseTest4 { super.setUp(); TestUtil.createTable(con, "int_table", "id int"); Statement stmt = con.createStatement(); - stmt.execute("CREATE OR REPLACE FUNCTION testspg__getString (varchar) " + stmt.execute( + "CREATE OR REPLACE FUNCTION testspg__getString (varchar) " + "RETURNS varchar AS ' DECLARE inString alias for $1; begin " + "return ''bob''; end; ' LANGUAGE plpgsql;"); - stmt.execute("CREATE OR REPLACE FUNCTION testspg__getDouble (float) " + stmt.execute( + "CREATE OR REPLACE FUNCTION testspg__getDouble (float) " + "RETURNS float AS ' DECLARE inString alias for $1; begin " + "return 42.42; end; ' LANGUAGE plpgsql;"); - if (TestUtil.haveMinimumServerVersion(con, "7.3")) { - stmt.execute("CREATE OR REPLACE FUNCTION testspg__getVoid (float) " - + "RETURNS void AS ' DECLARE inString alias for $1; begin " - + " return; end; ' LANGUAGE plpgsql;"); - } - stmt.execute("CREATE OR REPLACE FUNCTION testspg__getInt (int) RETURNS int " + stmt.execute( + "CREATE OR REPLACE FUNCTION testspg__getVoid (float) " + + "RETURNS void AS ' DECLARE inString alias for $1; begin " + + " return; end; ' LANGUAGE plpgsql;"); + stmt.execute( + "CREATE OR REPLACE FUNCTION testspg__getInt (int) RETURNS int " + " AS 'DECLARE inString alias for $1; begin " + "return 42; end;' LANGUAGE plpgsql;"); - stmt.execute("CREATE OR REPLACE FUNCTION testspg__getShort (int2) RETURNS int2 " + stmt.execute( + "CREATE OR REPLACE FUNCTION testspg__getShort (int2) RETURNS int2 " + " AS 'DECLARE inString alias for $1; begin " + "return 42; end;' LANGUAGE plpgsql;"); - stmt.execute("CREATE OR REPLACE FUNCTION testspg__getNumeric (numeric) " + stmt.execute( + "CREATE OR REPLACE FUNCTION testspg__getNumeric (numeric) " + "RETURNS numeric AS ' DECLARE inString alias for $1; " + "begin return 42; end; ' LANGUAGE plpgsql;"); - stmt.execute("CREATE OR REPLACE FUNCTION testspg__getNumericWithoutArg() " + stmt.execute( + "CREATE OR REPLACE FUNCTION testspg__getNumericWithoutArg() " + "RETURNS numeric AS ' " + "begin return 42; end; ' LANGUAGE plpgsql;"); stmt.execute( - "CREATE OR REPLACE FUNCTION testspg__getarray() RETURNS int[] as 'SELECT ''{1,2}''::int[];' LANGUAGE sql"); + "CREATE OR REPLACE FUNCTION testspg__getarray() RETURNS int[] as " + + "'SELECT ''{1,2}''::int[];' LANGUAGE sql"); stmt.execute( - "CREATE OR REPLACE FUNCTION testspg__raisenotice() RETURNS int as 'BEGIN RAISE NOTICE ''hello''; RAISE NOTICE ''goodbye''; RETURN 1; END;' LANGUAGE plpgsql"); + "CREATE OR REPLACE FUNCTION testspg__raisenotice() RETURNS int as " + + "'BEGIN RAISE NOTICE ''hello''; RAISE NOTICE ''goodbye''; RETURN 1; END;' LANGUAGE plpgsql"); stmt.execute( - "CREATE OR REPLACE FUNCTION testspg__insertInt(int) RETURNS int as 'BEGIN INSERT INTO int_table(id) VALUES ($1); RETURN 1; END;' LANGUAGE plpgsql"); + "CREATE OR REPLACE FUNCTION testspg__insertInt(int) RETURNS int as " + + "'BEGIN INSERT INTO int_table(id) VALUES ($1); RETURN 1; END;' LANGUAGE plpgsql"); stmt.close(); } @@ -74,9 +82,7 @@ public class CallableStmtTest extends BaseTest4 { TestUtil.dropTable(con, "int_table"); stmt.execute("drop FUNCTION testspg__getString (varchar);"); stmt.execute("drop FUNCTION testspg__getDouble (float);"); - if (TestUtil.haveMinimumServerVersion(con, "7.3")) { - stmt.execute("drop FUNCTION testspg__getVoid(float);"); - } + stmt.execute("drop FUNCTION testspg__getVoid(float);"); stmt.execute("drop FUNCTION testspg__getInt (int);"); stmt.execute("drop FUNCTION testspg__getShort(int2)"); stmt.execute("drop FUNCTION testspg__getNumeric (numeric);"); @@ -135,11 +141,9 @@ public class CallableStmtTest extends BaseTest4 { call.setDouble(1, 3.04); call.execute(); - if (TestUtil.haveMinimumServerVersion(con, "7.3")) { - call = con.prepareCall("{ call " + pkgName + "getVoid(?) }"); - call.setDouble(1, 3.04); - call.execute(); - } + call = con.prepareCall("{ call " + pkgName + "getVoid(?) }"); + call.setDouble(1, 3.04); + call.execute(); } @Test diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/CopyTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/CopyTest.java index 3e0feefc..261b2ab0 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/CopyTest.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/CopyTest.java @@ -104,9 +104,7 @@ public class CopyTest extends TestCase { long count1 = cp.endCopy(); long count2 = cp.getHandledRowCount(); long expectedResult = -1; - if (TestUtil.haveMinimumServerVersion(con, "8.2")) { - expectedResult = dataRows; - } + expectedResult = dataRows; assertEquals(expectedResult, count1); assertEquals(expectedResult, count2); @@ -205,9 +203,8 @@ public class CopyTest extends TestCase { long rowCount = cp.getHandledRowCount(); long expectedResult = -1; - if (TestUtil.haveMinimumServerVersion(con, "8.2")) { - expectedResult = dataRows; - } + expectedResult = dataRows; + assertEquals(expectedResult, rowCount); assertEquals(dataRows, getCount()); @@ -282,10 +279,6 @@ public class CopyTest extends TestCase { } public void testCopyQuery() throws SQLException, IOException { - if (!TestUtil.haveMinimumServerVersion(con, "8.2")) { - return; - } - testCopyInByRow(); // ensure we have some data. long count = copyAPI.copyOut("COPY (SELECT generate_series(1,1000)) TO STDOUT", diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/DatabaseEncodingTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/DatabaseEncodingTest.java index 220c38f6..1eff1c65 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/DatabaseEncodingTest.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/DatabaseEncodingTest.java @@ -80,7 +80,7 @@ public class DatabaseEncodingTest extends TestCase { rs.close(); - boolean testHighUnicode = TestUtil.haveMinimumServerVersion(con, "8.1"); + boolean testHighUnicode = true; // Create data. // NB: we avoid d800-dfff as those are reserved for surrogates in UTF-16 diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/DatabaseMetaDataPropertiesTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/DatabaseMetaDataPropertiesTest.java index 1ebe3a66..4d837e8b 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/DatabaseMetaDataPropertiesTest.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/DatabaseMetaDataPropertiesTest.java @@ -69,11 +69,7 @@ public class DatabaseMetaDataPropertiesTest { assertTrue(dbmd.supportsMinimumSQLGrammar()); assertTrue(!dbmd.supportsCoreSQLGrammar()); assertTrue(!dbmd.supportsExtendedSQLGrammar()); - if (TestUtil.haveMinimumServerVersion(con, "7.3")) { - assertTrue(dbmd.supportsANSI92EntryLevelSQL()); - } else { - assertTrue(!dbmd.supportsANSI92EntryLevelSQL()); - } + assertTrue(dbmd.supportsANSI92EntryLevelSQL()); assertTrue(!dbmd.supportsANSI92IntermediateSQL()); assertTrue(!dbmd.supportsANSI92FullSQL()); @@ -105,11 +101,7 @@ public class DatabaseMetaDataPropertiesTest { DatabaseMetaData dbmd = con.getMetaData(); assertNotNull(dbmd); int indexMaxKeys = dbmd.getMaxColumnsInIndex(); - if (TestUtil.haveMinimumServerVersion(con, "7.3")) { - assertEquals(32, indexMaxKeys); - } else { - assertEquals(16, indexMaxKeys); - } + assertEquals(32, indexMaxKeys); } @Test @@ -118,8 +110,8 @@ public class DatabaseMetaDataPropertiesTest { assertNotNull(dbmd); assertTrue(!dbmd.nullsAreSortedAtStart()); - assertTrue(dbmd.nullsAreSortedAtEnd() != TestUtil.haveMinimumServerVersion(con, "7.2")); - assertTrue(dbmd.nullsAreSortedHigh() == TestUtil.haveMinimumServerVersion(con, "7.2")); + assertTrue(dbmd.nullsAreSortedAtEnd() != true); + assertTrue(dbmd.nullsAreSortedHigh() == true); assertTrue(!dbmd.nullsAreSortedLow()); assertTrue(dbmd.nullPlusNonNullIsNull()); @@ -163,11 +155,7 @@ public class DatabaseMetaDataPropertiesTest { assertTrue(dbmd.supportsAlterTableWithAddColumn()); // we can only drop columns in >= 7.3 - if (TestUtil.haveMinimumServerVersion(con, "7.3")) { - assertTrue(dbmd.supportsAlterTableWithDropColumn()); - } else { - assertTrue(!dbmd.supportsAlterTableWithDropColumn()); - } + assertTrue(dbmd.supportsAlterTableWithDropColumn()); } @Test diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java index 22e2cbd8..1fd9babc 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java @@ -64,14 +64,10 @@ public class DatabaseMetaDataTest { stmt.execute( "CREATE OR REPLACE FUNCTION f1(int, varchar) RETURNS int AS 'SELECT 1;' LANGUAGE SQL"); - if (TestUtil.haveMinimumServerVersion(con, "8.0")) { - stmt.execute( - "CREATE OR REPLACE FUNCTION f2(a int, b varchar) RETURNS int AS 'SELECT 1;' LANGUAGE SQL"); - } - if (TestUtil.haveMinimumServerVersion(con, "8.1")) { - stmt.execute( - "CREATE OR REPLACE FUNCTION f3(IN a int, INOUT b varchar, OUT c timestamptz) AS $f$ BEGIN b := 'a'; c := now(); return; END; $f$ LANGUAGE plpgsql"); - } + stmt.execute( + "CREATE OR REPLACE FUNCTION f2(a int, b varchar) RETURNS int AS 'SELECT 1;' LANGUAGE SQL"); + stmt.execute( + "CREATE OR REPLACE FUNCTION f3(IN a int, INOUT b varchar, OUT c timestamptz) AS $f$ BEGIN b := 'a'; c := now(); return; END; $f$ LANGUAGE plpgsql"); stmt.execute( "CREATE OR REPLACE FUNCTION f4(int) RETURNS metadatatest AS 'SELECT 1, ''a''::text, now(), ''c''::text, ''q''::text' LANGUAGE SQL"); if (TestUtil.haveMinimumServerVersion(con, ServerVersion.v8_4)) { @@ -80,10 +76,8 @@ public class DatabaseMetaDataTest { "CREATE OR REPLACE FUNCTION f5() RETURNS TABLE (i int) LANGUAGE sql AS 'SELECT 1'"); } - if (TestUtil.haveMinimumServerVersion(con, "7.3")) { - TestUtil.createDomain(con, "nndom", "int not null"); - TestUtil.createTable(con, "domaintable", "id nndom"); - } + TestUtil.createDomain(con, "nndom", "int not null"); + TestUtil.createTable(con, "domaintable", "id nndom"); stmt.close(); } @@ -107,16 +101,10 @@ public class DatabaseMetaDataTest { TestUtil.dropType(con, "_custom"); stmt.execute("DROP FUNCTION f1(int, varchar)"); - if (TestUtil.haveMinimumServerVersion(con, "8.0")) { - stmt.execute("DROP FUNCTION f2(int, varchar)"); - } - if (TestUtil.haveMinimumServerVersion(con, "8.1")) { - stmt.execute("DROP FUNCTION f3(int, varchar)"); - } - if (TestUtil.haveMinimumServerVersion(con, "7.3")) { - TestUtil.dropType(con, "domaintable"); - TestUtil.dropDomain(con, "nndom"); - } + stmt.execute("DROP FUNCTION f2(int, varchar)"); + stmt.execute("DROP FUNCTION f3(int, varchar)"); + TestUtil.dropType(con, "domaintable"); + TestUtil.dropDomain(con, "nndom"); TestUtil.closeDB(con); } @@ -237,13 +225,7 @@ public class DatabaseMetaDataTest { assertTrue(fkColumnName.equals("m") || fkColumnName.equals("n")); String fkName = rs.getString("FK_NAME"); - if (TestUtil.haveMinimumServerVersion(con1, "8.0")) { - assertEquals("ww_m_fkey", fkName); - } else if (TestUtil.haveMinimumServerVersion(con1, "7.3")) { - assertTrue(fkName.startsWith("$1")); - } else { - assertTrue(fkName.startsWith("<unnamed>")); - } + assertEquals("ww_m_fkey", fkName); String pkName = rs.getString("PK_NAME"); assertEquals("vv_pkey", pkName); @@ -288,10 +270,6 @@ public class DatabaseMetaDataTest { @Test public void testForeignKeysToUniqueIndexes() throws Exception { - if (!TestUtil.haveMinimumServerVersion(con, "7.4")) { - return; - } - Connection con1 = TestUtil.openDB(); TestUtil.createTable(con1, "pkt", "a int not null, b int not null, CONSTRAINT pkt_pk_a PRIMARY KEY (a), CONSTRAINT pkt_un_b UNIQUE (b)"); @@ -482,7 +460,7 @@ public class DatabaseMetaDataTest { @Test public void testDroppedColumns() throws SQLException { - if (!TestUtil.haveMinimumServerVersion(con, "8.4")) { + if (!TestUtil.haveMinimumServerVersion(con, ServerVersion.v8_4)) { return; } @@ -589,10 +567,8 @@ public class DatabaseMetaDataTest { stmt.execute("create index idx_id on metadatatest (id)"); stmt.execute("create index idx_func_single on metadatatest (upper(colour))"); stmt.execute("create unique index idx_un_id on metadatatest(id)"); - if (TestUtil.haveMinimumServerVersion(con, "7.4")) { - stmt.execute("create index idx_func_multi on metadatatest (upper(colour), upper(quest))"); - stmt.execute("create index idx_func_mixed on metadatatest (colour, upper(quest))"); - } + stmt.execute("create index idx_func_multi on metadatatest (upper(colour), upper(quest))"); + stmt.execute("create index idx_func_mixed on metadatatest (colour, upper(quest))"); DatabaseMetaData dbmd = con.getMetaData(); assertNotNull(dbmd); @@ -604,27 +580,25 @@ public class DatabaseMetaDataTest { assertEquals("id", rs.getString("COLUMN_NAME")); assertTrue(!rs.getBoolean("NON_UNIQUE")); - if (TestUtil.haveMinimumServerVersion(con, "7.4")) { - assertTrue(rs.next()); - assertEquals("idx_func_mixed", rs.getString("INDEX_NAME")); - assertEquals(1, rs.getInt("ORDINAL_POSITION")); - assertEquals("colour", rs.getString("COLUMN_NAME")); + assertTrue(rs.next()); + assertEquals("idx_func_mixed", rs.getString("INDEX_NAME")); + assertEquals(1, rs.getInt("ORDINAL_POSITION")); + assertEquals("colour", rs.getString("COLUMN_NAME")); - assertTrue(rs.next()); - assertEquals("idx_func_mixed", rs.getString("INDEX_NAME")); - assertEquals(2, rs.getInt("ORDINAL_POSITION")); - assertEquals("upper(quest)", rs.getString("COLUMN_NAME")); + assertTrue(rs.next()); + assertEquals("idx_func_mixed", rs.getString("INDEX_NAME")); + assertEquals(2, rs.getInt("ORDINAL_POSITION")); + assertEquals("upper(quest)", rs.getString("COLUMN_NAME")); - assertTrue(rs.next()); - assertEquals("idx_func_multi", rs.getString("INDEX_NAME")); - assertEquals(1, rs.getInt("ORDINAL_POSITION")); - assertEquals("upper(colour)", rs.getString("COLUMN_NAME")); + assertTrue(rs.next()); + assertEquals("idx_func_multi", rs.getString("INDEX_NAME")); + assertEquals(1, rs.getInt("ORDINAL_POSITION")); + assertEquals("upper(colour)", rs.getString("COLUMN_NAME")); - assertTrue(rs.next()); - assertEquals("idx_func_multi", rs.getString("INDEX_NAME")); - assertEquals(2, rs.getInt("ORDINAL_POSITION")); - assertEquals("upper(quest)", rs.getString("COLUMN_NAME")); - } + assertTrue(rs.next()); + assertEquals("idx_func_multi", rs.getString("INDEX_NAME")); + assertEquals(2, rs.getInt("ORDINAL_POSITION")); + assertEquals("upper(quest)", rs.getString("COLUMN_NAME")); assertTrue(rs.next()); assertEquals("idx_func_single", rs.getString("INDEX_NAME")); @@ -644,10 +618,6 @@ public class DatabaseMetaDataTest { @Test public void testNotNullDomainColumn() throws SQLException { - if (!TestUtil.haveMinimumServerVersion(con, "7.3")) { - return; - } - DatabaseMetaData dbmd = con.getMetaData(); ResultSet rs = dbmd.getColumns("", "", "domaintable", ""); assertTrue(rs.next()); @@ -658,7 +628,7 @@ public class DatabaseMetaDataTest { @Test public void testAscDescIndexInfo() throws SQLException { - if (!TestUtil.haveMinimumServerVersion(con, "8.3")) { + if (!TestUtil.haveMinimumServerVersion(con, ServerVersion.v8_3)) { return; } @@ -736,10 +706,6 @@ public class DatabaseMetaDataTest { @Test public void testFuncWithNames() throws SQLException { - if (!TestUtil.haveMinimumServerVersion(con, "8.0")) { - return; - } - DatabaseMetaData dbmd = con.getMetaData(); ResultSet rs = dbmd.getProcedureColumns(null, null, "f2", null); @@ -758,10 +724,6 @@ public class DatabaseMetaDataTest { @Test public void testFuncWithDirection() throws SQLException { - if (!TestUtil.haveMinimumServerVersion(con, "8.1")) { - return; - } - DatabaseMetaData dbmd = con.getMetaData(); ResultSet rs = dbmd.getProcedureColumns(null, null, "f3", null); @@ -900,17 +862,10 @@ public class DatabaseMetaDataTest { } } rs.close(); - if (TestUtil.haveMinimumServerVersion(con, "7.3")) { - assertTrue(count >= 2); - assertTrue(foundPublic); - assertTrue(foundPGCatalog); - assertTrue(!foundEmpty); - } else { - assertEquals(count, 1); - assertTrue(foundEmpty); - assertTrue(!foundPublic); - assertTrue(!foundPGCatalog); - } + assertTrue(count >= 2); + assertTrue(foundPublic); + assertTrue(foundPGCatalog); + assertTrue(!foundEmpty); } @Test @@ -941,10 +896,6 @@ public class DatabaseMetaDataTest { @Test public void testGetUDTQualified() throws Exception { - if (!TestUtil.haveMinimumServerVersion(con, "7.3")) { - return; - } - Statement stmt = null; try { stmt = con.createStatement(); @@ -999,10 +950,6 @@ public class DatabaseMetaDataTest { @Test public void testGetUDT1() throws Exception { - if (!TestUtil.haveMinimumServerVersion(con, "7.3")) { - return; - } - try { Statement stmt = con.createStatement(); stmt.execute("create domain testint8 as int8"); @@ -1043,10 +990,6 @@ public class DatabaseMetaDataTest { @Test public void testGetUDT2() throws Exception { - if (!TestUtil.haveMinimumServerVersion(con, "7.3")) { - return; - } - try { Statement stmt = con.createStatement(); stmt.execute("create domain testint8 as int8"); @@ -1086,10 +1029,6 @@ public class DatabaseMetaDataTest { @Test public void testGetUDT3() throws Exception { - if (!TestUtil.haveMinimumServerVersion(con, "7.3")) { - return; - } - try { Statement stmt = con.createStatement(); stmt.execute("create domain testint8 as int8"); @@ -1129,10 +1068,6 @@ public class DatabaseMetaDataTest { @Test public void testGetUDT4() throws Exception { - if (!TestUtil.haveMinimumServerVersion(con, "7.3")) { - return; - } - try { Statement stmt = con.createStatement(); stmt.execute("create type testint8 as (i int8)"); diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/GeometricTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/GeometricTest.java index fe503605..3f80c708 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/GeometricTest.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/GeometricTest.java @@ -5,6 +5,7 @@ package org.postgresql.test.jdbc2; +import org.postgresql.core.ServerVersion; import org.postgresql.geometric.PGbox; import org.postgresql.geometric.PGcircle; import org.postgresql.geometric.PGline; @@ -111,9 +112,9 @@ public class GeometricTest extends TestCase { // PostgreSQL versions older than 9.4 support creating columns with the LINE datatype, but // not actually writing to those columns. Only try to write if the version if at least 9.4 - final boolean roundTripToDatabase = TestUtil.haveMinimumServerVersion(con, "9.4"); + final boolean roundTripToDatabase = TestUtil.haveMinimumServerVersion(con, ServerVersion.v9_4); - if (TestUtil.haveMinimumServerVersion(con, "9.4")) { + if (TestUtil.haveMinimumServerVersion(con, ServerVersion.v9_4)) { // Apparently the driver requires public no-args constructor, and postgresql doesn't accept // lines with A and B diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/IntervalTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/IntervalTest.java index 0aaaf60d..64657749 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/IntervalTest.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/IntervalTest.java @@ -119,13 +119,9 @@ public class IntervalTest { assertTrue(rs.next()); PGInterval i = (PGInterval) rs.getObject(1); // 8.1 servers store hours and days separately. - if (TestUtil.haveMinimumServerVersion(conn, "8.1")) { - assertEquals(0, i.getDays()); - assertEquals(101, i.getHours()); - } else { - assertEquals(4, i.getDays()); - assertEquals(5, i.getHours()); - } + assertEquals(0, i.getDays()); + assertEquals(101, i.getHours()); + assertEquals(12, i.getMinutes()); } diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/Jdbc2TestSuite.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/Jdbc2TestSuite.java index 899bffc6..42e80588 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/Jdbc2TestSuite.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/Jdbc2TestSuite.java @@ -6,6 +6,7 @@ package org.postgresql.test.jdbc2; import org.postgresql.core.ParserTest; +import org.postgresql.core.ServerVersion; import org.postgresql.core.v3.V3ParameterListTests; import org.postgresql.jdbc.DeepBatchedInsertStatementTest; import org.postgresql.test.CursorFetchBinaryTest; @@ -96,7 +97,6 @@ public class Jdbc2TestSuite extends TestSuite { // Fastpath/LargeObject suite.addTestSuite(BlobTest.class); - suite.addTestSuite(OID74Test.class); suite.addTestSuite(BlobTransactionTest.class); suite.addTest(new JUnit4TestAdapter(UpdateableResultTest.class)); @@ -123,11 +123,11 @@ public class Jdbc2TestSuite extends TestSuite { suite.addTestSuite(CopyTest.class); suite.addTestSuite(CopyLargeFileTest.class); } - if (TestUtil.haveMinimumServerVersion(conn, "9.3")) { + if (TestUtil.haveMinimumServerVersion(conn, ServerVersion.v9_3)) { suite.addTestSuite(ServerErrorTest.class); } - if (TestUtil.haveMinimumServerVersion(conn, "9.5")) { + if (TestUtil.haveMinimumServerVersion(conn, ServerVersion.v9_5)) { suite.addTestSuite(UpsertTest.class); suite.addTestSuite(UpsertBinaryTest.class); } diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/NotifyTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/NotifyTest.java index 4ef067be..280d1ce9 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/NotifyTest.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/NotifyTest.java @@ -6,6 +6,7 @@ package org.postgresql.test.jdbc2; import org.postgresql.PGNotification; +import org.postgresql.core.ServerVersion; import org.postgresql.test.TestUtil; import junit.framework.TestCase; @@ -44,7 +45,7 @@ public class NotifyTest extends TestCase { } public void testNotifyArgument() throws Exception { - if (!TestUtil.haveMinimumServerVersion(conn, "9.0") || TestUtil.isProtocolVersion(conn, 2)) { + if (!TestUtil.haveMinimumServerVersion(conn, ServerVersion.v9_0) || TestUtil.isProtocolVersion(conn, 2)) { return; } diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/OID74Test.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/OID74Test.java deleted file mode 100644 index fecc7415..00000000 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/OID74Test.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2004, PostgreSQL Global Development Group - * See the LICENSE file in the project root for more information. - */ - -package org.postgresql.test.jdbc2; - -import org.postgresql.test.TestUtil; - -import junit.framework.TestCase; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; -import java.util.Properties; - -/** - * User: alexei - */ -public class OID74Test extends TestCase { - private Connection conn; - - public OID74Test(String name) { - super(name); - } - - public void setUp() throws Exception { - // set up conection here - Properties props = new Properties(); - props.setProperty("compatible", "7.1"); - conn = TestUtil.openDB(props); - - TestUtil.createTable(conn, "temp", "col oid"); - conn.setAutoCommit(false); - } - - public void tearDown() throws Exception { - conn.setAutoCommit(true); - TestUtil.dropTable(conn, "temp"); - TestUtil.closeDB(conn); - } - - public void testSetNull() throws SQLException { - PreparedStatement pstmt = conn.prepareStatement("INSERT INTO temp VALUES (?)"); - pstmt.setNull(1, Types.VARBINARY); - pstmt.executeUpdate(); - pstmt.setNull(1, Types.BLOB); - pstmt.executeUpdate(); - pstmt.setNull(1, Types.CLOB); - pstmt.executeUpdate(); - pstmt.close(); - } - - public void testBinaryStream() throws Exception { - PreparedStatement pstmt = conn.prepareStatement("INSERT INTO temp VALUES (?)"); - pstmt.setBinaryStream(1, new ByteArrayInputStream(new byte[]{1, 2, 3, 4, 5}), 5); - assertTrue((pstmt.executeUpdate() == 1)); - pstmt.close(); - - pstmt = conn.prepareStatement("SELECT col FROM temp LIMIT 1"); - ResultSet rs = pstmt.executeQuery(); - - assertTrue("No results from query", rs.next()); - - InputStream in = rs.getBinaryStream(1); - int data; - int i = 1; - while ((data = in.read()) != -1) { - assertEquals(i++, data); - } - rs.close(); - pstmt.close(); - } -} diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/PreparedStatementTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/PreparedStatementTest.java index b3b38d3e..94658148 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/PreparedStatementTest.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/PreparedStatementTest.java @@ -266,83 +266,69 @@ public class PreparedStatementTest extends BaseTest4 { @Test public void testSingleQuotes() throws SQLException { String[] testStrings = new String[]{ - "bare ? question mark", - "quoted \\' single quote", - "doubled '' single quote", - "octal \\060 constant", - "escaped \\? question mark", - "double \\\\ backslash", - "double \" quote", - }; + "bare ? question mark", + "quoted \\' single quote", + "doubled '' single quote", + "octal \\060 constant", + "escaped \\? question mark", + "double \\\\ backslash", + "double \" quote",}; String[] testStringsStdConf = new String[]{ - "bare ? question mark", - "quoted '' single quote", - "doubled '' single quote", - "octal 0 constant", - "escaped ? question mark", - "double \\ backslash", - "double \" quote", - }; + "bare ? question mark", + "quoted '' single quote", + "doubled '' single quote", + "octal 0 constant", + "escaped ? question mark", + "double \\ backslash", + "double \" quote",}; String[] expected = new String[]{ - "bare ? question mark", - "quoted ' single quote", - "doubled ' single quote", - "octal 0 constant", - "escaped ? question mark", - "double \\ backslash", - "double \" quote", - }; - - if (!TestUtil.haveMinimumServerVersion(con, "8.2")) { - for (int i = 0; i < testStrings.length; ++i) { - PreparedStatement pstmt = con.prepareStatement("SELECT '" + testStrings[i] + "'"); - ResultSet rs = pstmt.executeQuery(); - assertTrue(rs.next()); - assertEquals(expected[i], rs.getString(1)); - rs.close(); - pstmt.close(); - } - } else { - boolean oldStdStrings = TestUtil.getStandardConformingStrings(con); - Statement stmt = con.createStatement(); - - // Test with standard_conforming_strings turned off. - stmt.execute("SET standard_conforming_strings TO off"); - for (int i = 0; i < testStrings.length; ++i) { - PreparedStatement pstmt = con.prepareStatement("SELECT '" + testStrings[i] + "'"); - ResultSet rs = pstmt.executeQuery(); - assertTrue(rs.next()); - assertEquals(expected[i], rs.getString(1)); - rs.close(); - pstmt.close(); - } - - // Test with standard_conforming_strings turned off... - // ... using the escape string syntax (E''). - stmt.execute("SET standard_conforming_strings TO on"); - for (int i = 0; i < testStrings.length; ++i) { - PreparedStatement pstmt = con.prepareStatement("SELECT E'" + testStrings[i] + "'"); - ResultSet rs = pstmt.executeQuery(); - assertTrue(rs.next()); - assertEquals(expected[i], rs.getString(1)); - rs.close(); - pstmt.close(); - } - // ... using standard conforming input strings. - for (int i = 0; i < testStrings.length; ++i) { - PreparedStatement pstmt = con.prepareStatement("SELECT '" + testStringsStdConf[i] + "'"); - ResultSet rs = pstmt.executeQuery(); - assertTrue(rs.next()); - assertEquals(expected[i], rs.getString(1)); - rs.close(); - pstmt.close(); - } + "bare ? question mark", + "quoted ' single quote", + "doubled ' single quote", + "octal 0 constant", + "escaped ? question mark", + "double \\ backslash", + "double \" quote",}; + + boolean oldStdStrings = TestUtil.getStandardConformingStrings(con); + Statement stmt = con.createStatement(); + + // Test with standard_conforming_strings turned off. + stmt.execute("SET standard_conforming_strings TO off"); + for (int i = 0; i < testStrings.length; ++i) { + PreparedStatement pstmt = con.prepareStatement("SELECT '" + testStrings[i] + "'"); + ResultSet rs = pstmt.executeQuery(); + assertTrue(rs.next()); + assertEquals(expected[i], rs.getString(1)); + rs.close(); + pstmt.close(); + } - stmt.execute("SET standard_conforming_strings TO " + (oldStdStrings ? "on" : "off")); - stmt.close(); + // Test with standard_conforming_strings turned off... + // ... using the escape string syntax (E''). + stmt.execute("SET standard_conforming_strings TO on"); + for (int i = 0; i < testStrings.length; ++i) { + PreparedStatement pstmt = con.prepareStatement("SELECT E'" + testStrings[i] + "'"); + ResultSet rs = pstmt.executeQuery(); + assertTrue(rs.next()); + assertEquals(expected[i], rs.getString(1)); + rs.close(); + pstmt.close(); } + // ... using standard conforming input strings. + for (int i = 0; i < testStrings.length; ++i) { + PreparedStatement pstmt = con.prepareStatement("SELECT '" + testStringsStdConf[i] + "'"); + ResultSet rs = pstmt.executeQuery(); + assertTrue(rs.next()); + assertEquals(expected[i], rs.getString(1)); + rs.close(); + pstmt.close(); + } + + stmt.execute("SET standard_conforming_strings TO " + (oldStdStrings ? "on" : "off")); + stmt.close(); } @Test @@ -370,10 +356,6 @@ public class PreparedStatementTest extends BaseTest4 { @Test public void testDollarQuotes() throws SQLException { // dollar-quotes are supported in the backend since version 8.0 - if (!TestUtil.haveMinimumServerVersion(con, "8.0")) { - return; - } - PreparedStatement st; ResultSet rs; @@ -416,10 +398,6 @@ public class PreparedStatementTest extends BaseTest4 { @Test public void testDollarQuotesAndIdentifiers() throws SQLException { // dollar-quotes are supported in the backend since version 8.0 - if (!TestUtil.haveMinimumServerVersion(con, "8.0")) { - return; - } - PreparedStatement st; con.createStatement().execute("CREATE TEMP TABLE a$b$c(a varchar, b varchar)"); diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/StatementTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/StatementTest.java index 1a67854b..079198ef 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/StatementTest.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/StatementTest.java @@ -256,7 +256,8 @@ public class StatementTest extends TestCase { public void testStringFunctions() throws SQLException { Statement stmt = con.createStatement(); - ResultSet rs = stmt.executeQuery("select {fn ascii(' test')},{fn char(32)}" + ResultSet rs = stmt.executeQuery( + "select {fn ascii(' test')},{fn char(32)}" + ",{fn concat('ab','cd')}" + ",{fn lcase('aBcD')},{fn left('1234',2)},{fn length('123 ')}" + ",{fn locate('bc','abc')},{fn locate('bc','abc',3)}"); @@ -270,20 +271,18 @@ public class StatementTest extends TestCase { assertEquals(2, rs.getInt(7)); assertEquals(0, rs.getInt(8)); - if (TestUtil.haveMinimumServerVersion(con, "7.3")) { - rs = stmt.executeQuery( - "SELECT {fn insert('abcdef',3,2,'xxxx')}" - + ",{fn replace('abcdbc','bc','x')}"); - assertTrue(rs.next()); - assertEquals("abxxxxef", rs.getString(1)); - assertEquals("axdx", rs.getString(2)); - } + rs = stmt.executeQuery( + "SELECT {fn insert('abcdef',3,2,'xxxx')}" + + ",{fn replace('abcdbc','bc','x')}"); + assertTrue(rs.next()); + assertEquals("abxxxxef", rs.getString(1)); + assertEquals("axdx", rs.getString(2)); rs = stmt.executeQuery( "select {fn ltrim(' ab')},{fn repeat('ab',2)}" - + ",{fn right('abcde',2)},{fn rtrim('ab ')}" - + ",{fn space(3)},{fn substring('abcd',2,2)}" - + ",{fn ucase('aBcD')}"); + + ",{fn right('abcde',2)},{fn rtrim('ab ')}" + + ",{fn space(3)},{fn substring('abcd',2,2)}" + + ",{fn ucase('aBcD')}"); assertTrue(rs.next()); assertEquals("ab", rs.getString(1)); assertEquals("abab", rs.getString(2)); @@ -298,9 +297,6 @@ public class StatementTest extends TestCase { // Prior to 8.0 there is not an interval + timestamp operator, // so timestampadd does not work. // - if (!TestUtil.haveMinimumServerVersion(con, "8.0")) { - return; - } PreparedStatement ps = con.prepareStatement( "SELECT {fn timestampadd(SQL_TSI_QUARTER, ? ,{fn now()})}, {fn timestampadd(SQL_TSI_MONTH, ?, {fn now()})} "); @@ -328,9 +324,6 @@ public class StatementTest extends TestCase { // Prior to 8.0 there is not an interval + timestamp operator, // so timestampadd does not work. // - if (!TestUtil.haveMinimumServerVersion(con, "8.0")) { - return; - } // second rs = stmt.executeQuery( @@ -378,16 +371,14 @@ public class StatementTest extends TestCase { Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery( "select {fn ifnull(null,'2')}" - + ",{fn user()} "); + + ",{fn user()} "); assertTrue(rs.next()); assertEquals("2", rs.getString(1)); assertEquals(TestUtil.getUser(), rs.getString(2)); - if (TestUtil.haveMinimumServerVersion(con, "7.3")) { - rs = stmt.executeQuery("select {fn database()} "); - assertTrue(rs.next()); - assertEquals(TestUtil.getDatabase(), rs.getString(1)); - } + rs = stmt.executeQuery("select {fn database()} "); + assertTrue(rs.next()); + assertEquals(TestUtil.getDatabase(), rs.getString(1)); } public void testWarningsAreCleared() throws SQLException { @@ -420,10 +411,6 @@ public class StatementTest extends TestCase { public void testParsingDollarQuotes() throws SQLException { // dollar-quotes are supported in the backend since version 8.0 - if (!TestUtil.haveMinimumServerVersion(con, "8.0")) { - return; - } - Statement st = con.createStatement(); ResultSet rs; diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/TimestampTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/TimestampTest.java index 0ec6e510..3fc7a0ca 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/TimestampTest.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/TimestampTest.java @@ -12,6 +12,7 @@ import static org.junit.Assert.fail; import org.postgresql.PGStatement; import org.postgresql.core.BaseConnection; +import org.postgresql.core.ServerVersion; import org.postgresql.jdbc.TimestampUtils; import org.postgresql.test.TestUtil; @@ -103,7 +104,7 @@ public class TimestampTest { runInfinityTests(TSWTZ_TABLE, PGStatement.DATE_NEGATIVE_INFINITY); runInfinityTests(TSWOTZ_TABLE, PGStatement.DATE_POSITIVE_INFINITY); runInfinityTests(TSWOTZ_TABLE, PGStatement.DATE_NEGATIVE_INFINITY); - if (TestUtil.haveMinimumServerVersion(con, "8.4")) { + if (TestUtil.haveMinimumServerVersion(con, ServerVersion.v8_4)) { runInfinityTests(DATE_TABLE, PGStatement.DATE_POSITIVE_INFINITY); runInfinityTests(DATE_TABLE, PGStatement.DATE_NEGATIVE_INFINITY); } diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/TimezoneTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/TimezoneTest.java index a4707772..359dfa0e 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/TimezoneTest.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/TimezoneTest.java @@ -65,9 +65,6 @@ public class TimezoneTest extends TestCase { private Calendar cGMT05; private Calendar cGMT13; - private boolean min73; - private boolean min74; - public TimezoneTest(String name) { super(name); @@ -95,9 +92,6 @@ public class TimezoneTest extends TestCase { // so will produce +03 timestamptz output con.createStatement().executeUpdate("set timezone = 'gmt-3'"); - min73 = TestUtil.haveMinimumServerVersion(con, "7.3"); - min74 = TestUtil.haveMinimumServerVersion(con, "7.4"); - // System.err.println("++++++ TESTS START (" + getName() + ") ++++++"); } @@ -345,10 +339,6 @@ public class TimezoneTest extends TestCase { */ public void testSetTimestampOnTime() throws Exception { // Pre-7.4 servers cannot convert timestamps with timezones to times. - if (!min74) { - return; - } - for (int i = 0; i < PREPARE_THRESHOLD; i++) { con.createStatement().execute("delete from testtimezone"); PreparedStatement insertTimestamp = @@ -378,12 +368,10 @@ public class TimezoneTest extends TestCase { insertTimestamp.setTimestamp(2, instant, cGMT05); // 07:00:00 insertTimestamp.executeUpdate(); - if (min73) { - // +1300 - insertTimestamp.setInt(1, seq++); - insertTimestamp.setTimestamp(2, instant, cGMT13); // 01:00:00 - insertTimestamp.executeUpdate(); - } + // +1300 + insertTimestamp.setInt(1, seq++); + insertTimestamp.setTimestamp(2, instant, cGMT13); // 01:00:00 + insertTimestamp.executeUpdate(); insertTimestamp.close(); @@ -474,15 +462,13 @@ public class TimezoneTest extends TestCase { insertTimestamp.setTimestamp(5, instant, cGMT05); // 2005-01-01 insertTimestamp.executeUpdate(); - if (min73) { - // +1300 - insertTimestamp.setInt(1, seq++); - insertTimestamp.setTimestamp(2, instant, cGMT13); // 2005-01-02 01:00:00 +1300 - insertTimestamp.setTimestamp(3, instant, cGMT13); // 2005-01-02 01:00:00 - insertTimestamp.setTimestamp(4, instant, cGMT13); // 01:00:00 +1300 - insertTimestamp.setTimestamp(5, instant, cGMT13); // 2005-01-02 - insertTimestamp.executeUpdate(); - } + // +1300 + insertTimestamp.setInt(1, seq++); + insertTimestamp.setTimestamp(2, instant, cGMT13); // 2005-01-02 01:00:00 +1300 + insertTimestamp.setTimestamp(3, instant, cGMT13); // 2005-01-02 01:00:00 + insertTimestamp.setTimestamp(4, instant, cGMT13); // 01:00:00 +1300 + insertTimestamp.setTimestamp(5, instant, cGMT13); // 2005-01-02 + insertTimestamp.executeUpdate(); insertTimestamp.close(); @@ -538,14 +524,12 @@ public class TimezoneTest extends TestCase { assertEquals(instantTime, rs.getTimestamp(4, cGMT05)); assertEquals(instantDateGMT05, rs.getTimestamp(5, cGMT05)); - if (min73) { - assertTrue(rs.next()); - assertEquals(seq++, rs.getInt(1)); - assertEquals(instant, rs.getTimestamp(2, cGMT13)); - assertEquals(instant, rs.getTimestamp(3, cGMT13)); - assertEquals(normalizeTimeOfDayPart(instantTime, cGMT13), rs.getTimestamp(4, cGMT13)); - assertEquals(instantDateGMT13, rs.getTimestamp(5, cGMT13)); - } + assertTrue(rs.next()); + assertEquals(seq++, rs.getInt(1)); + assertEquals(instant, rs.getTimestamp(2, cGMT13)); + assertEquals(instant, rs.getTimestamp(3, cGMT13)); + assertEquals(normalizeTimeOfDayPart(instantTime, cGMT13), rs.getTimestamp(4, cGMT13)); + assertEquals(instantDateGMT13, rs.getTimestamp(5, cGMT13)); assertTrue(!rs.next()); ps.close(); @@ -598,15 +582,13 @@ public class TimezoneTest extends TestCase { insertTimestamp.setDate(4, dGMT05, cGMT05); // 2005-01-01 insertTimestamp.executeUpdate(); - if (min73) { - // +1300 - dGMT13 = new Date(1104490800000L); // 2005-01-01 00:00:00 +1300 - insertTimestamp.setInt(1, seq++); - insertTimestamp.setDate(2, dGMT13, cGMT13); // 2005-01-01 00:00:00 +1300 - insertTimestamp.setDate(3, dGMT13, cGMT13); // 2005-01-01 00:00:00 - insertTimestamp.setDate(4, dGMT13, cGMT13); // 2005-01-01 - insertTimestamp.executeUpdate(); - } + // +1300 + dGMT13 = new Date(1104490800000L); // 2005-01-01 00:00:00 +1300 + insertTimestamp.setInt(1, seq++); + insertTimestamp.setDate(2, dGMT13, cGMT13); // 2005-01-01 00:00:00 +1300 + insertTimestamp.setDate(3, dGMT13, cGMT13); // 2005-01-01 00:00:00 + insertTimestamp.setDate(4, dGMT13, cGMT13); // 2005-01-01 + insertTimestamp.executeUpdate(); insertTimestamp.close(); @@ -652,13 +634,11 @@ public class TimezoneTest extends TestCase { assertEquals(dGMT05, rs.getDate(3, cGMT05)); assertEquals(dGMT05, rs.getDate(4, cGMT05)); - if (min73) { - assertTrue(rs.next()); - assertEquals(seq++, rs.getInt(1)); - assertEquals(dGMT13, rs.getDate(2, cGMT13)); - assertEquals(dGMT13, rs.getDate(3, cGMT13)); - assertEquals(dGMT13, rs.getDate(4, cGMT13)); - } + assertTrue(rs.next()); + assertEquals(seq++, rs.getInt(1)); + assertEquals(dGMT13, rs.getDate(2, cGMT13)); + assertEquals(dGMT13, rs.getDate(3, cGMT13)); + assertEquals(dGMT13, rs.getDate(4, cGMT13)); assertTrue(!rs.next()); ps.close(); @@ -666,12 +646,6 @@ public class TimezoneTest extends TestCase { } public void testSetTime() throws Exception { - if (!min74) { - // We can't do timezones properly for time/timetz values before 7.4 - System.err.println("Skipping TimezoneTest.testSetTime on a pre-7.4 server"); - return; - } - for (int i = 0; i < PREPARE_THRESHOLD; i++) { con.createStatement().execute("delete from testtimezone"); PreparedStatement insertTimestamp = @@ -781,10 +755,6 @@ public class TimezoneTest extends TestCase { } public void testTimezoneWithSeconds() throws SQLException { - if (!TestUtil.haveMinimumServerVersion(con, "8.2")) { - return; - } - Statement stmt = con.createStatement(); stmt.execute("SET TimeZone = 'Europe/Paris'"); for (int i = 0; i < PREPARE_THRESHOLD; i++) { diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc3/DatabaseMetaDataTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc3/DatabaseMetaDataTest.java index 212c42ed..25cc3a41 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc3/DatabaseMetaDataTest.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc3/DatabaseMetaDataTest.java @@ -25,27 +25,19 @@ public class DatabaseMetaDataTest extends TestCase { protected void setUp() throws Exception { _conn = TestUtil.openDB(); - if (TestUtil.haveMinimumServerVersion(_conn, "7.3")) { - Statement stmt = _conn.createStatement(); - stmt.execute("CREATE DOMAIN mydom AS int"); - stmt.execute("CREATE TABLE domtab (a mydom)"); - } + Statement stmt = _conn.createStatement(); + stmt.execute("CREATE DOMAIN mydom AS int"); + stmt.execute("CREATE TABLE domtab (a mydom)"); } protected void tearDown() throws Exception { - if (TestUtil.haveMinimumServerVersion(_conn, "7.3")) { - Statement stmt = _conn.createStatement(); - stmt.execute("DROP TABLE domtab"); - stmt.execute("DROP DOMAIN mydom"); - } + Statement stmt = _conn.createStatement(); + stmt.execute("DROP TABLE domtab"); + stmt.execute("DROP DOMAIN mydom"); TestUtil.closeDB(_conn); } public void testGetColumnsForDomain() throws Exception { - if (!TestUtil.haveMinimumServerVersion(_conn, "7.3")) { - return; - } - DatabaseMetaData dbmd = _conn.getMetaData(); ResultSet rs = dbmd.getColumns("%", "%", "domtab", "%"); diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc3/Jdbc3BlobTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc3/Jdbc3BlobTest.java index ed6a8412..16aad600 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc3/Jdbc3BlobTest.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc3/Jdbc3BlobTest.java @@ -5,6 +5,7 @@ package org.postgresql.test.jdbc3; +import org.postgresql.core.ServerVersion; import org.postgresql.test.TestUtil; import junit.framework.TestCase; @@ -98,7 +99,7 @@ public class Jdbc3BlobTest extends TestCase { } public void testTruncate() throws SQLException { - if (!TestUtil.haveMinimumServerVersion(_conn, "8.3")) { + if (!TestUtil.haveMinimumServerVersion(_conn, ServerVersion.v8_3)) { return; } diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc3/Jdbc3SavepointTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc3/Jdbc3SavepointTest.java index 5c4d784c..63282ac3 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc3/Jdbc3SavepointTest.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc3/Jdbc3SavepointTest.java @@ -37,7 +37,7 @@ public class Jdbc3SavepointTest extends TestCase { } private boolean hasSavepoints() throws SQLException { - return TestUtil.haveMinimumServerVersion(_conn, "8.0"); + return true; } private void addRow(int id) throws SQLException { diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc3/Jdbc3TestSuite.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc3/Jdbc3TestSuite.java index a1a82081..409adcb3 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc3/Jdbc3TestSuite.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc3/Jdbc3TestSuite.java @@ -23,12 +23,8 @@ public class Jdbc3TestSuite extends TestSuite { try { java.sql.Connection con = TestUtil.openDB(); - if (TestUtil.haveMinimumServerVersion(con, "8.1") && TestUtil.isProtocolVersion(con, 3)) { - suite.addTest(new JUnit4TestAdapter(Jdbc3CallableStatementTest.class)); - } - if (TestUtil.haveMinimumServerVersion(con, "8.2")) { - suite.addTest(new JUnit4TestAdapter(GeneratedKeysTest.class)); - } + suite.addTest(new JUnit4TestAdapter(Jdbc3CallableStatementTest.class)); + suite.addTest(new JUnit4TestAdapter(GeneratedKeysTest.class)); con.close(); } catch (Exception ex) { ex.printStackTrace(); diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc4/ArrayTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc4/ArrayTest.java index 2fe0b255..78bcd84f 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc4/ArrayTest.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc4/ArrayTest.java @@ -119,7 +119,7 @@ public class ArrayTest extends BaseTest4 { @Test public void testCreateArrayOfMultiJson() throws SQLException { - if (!TestUtil.haveMinimumServerVersion(_conn, "9.2")) { + if (!TestUtil.haveMinimumServerVersion(_conn, ServerVersion.v9_2)) { return; } PreparedStatement pstmt = _conn.prepareStatement("SELECT ?::json[]"); @@ -165,10 +165,6 @@ public class ArrayTest extends BaseTest4 { @Test public void testCreateArrayOfNull() throws SQLException { - if (!TestUtil.haveMinimumServerVersion(_conn, "8.2")) { - return; - } - String sql = "SELECT ?"; // We must provide the type information for V2 protocol if (preferQueryMode == PreferQueryMode.SIMPLE) { diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc4/ClientInfoTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc4/ClientInfoTest.java index 76c64b07..294024c6 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc4/ClientInfoTest.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc4/ClientInfoTest.java @@ -5,6 +5,7 @@ package org.postgresql.test.jdbc4; +import org.postgresql.core.ServerVersion; import org.postgresql.test.TestUtil; import junit.framework.TestCase; @@ -43,7 +44,7 @@ public class ClientInfoTest extends TestCase { } public void testSetAppName() throws SQLException { - if (!TestUtil.haveMinimumServerVersion(_conn, "9.0")) { + if (!TestUtil.haveMinimumServerVersion(_conn, ServerVersion.v9_0)) { return; } @@ -54,7 +55,7 @@ public class ClientInfoTest extends TestCase { } public void testExplicitSetAppNameNotificationIsParsed() throws SQLException { - if (!TestUtil.haveMinimumServerVersion(_conn, "9.0")) { + if (!TestUtil.haveMinimumServerVersion(_conn, ServerVersion.v9_0)) { return; } @@ -70,7 +71,7 @@ public class ClientInfoTest extends TestCase { } public void testSetAppNameProps() throws SQLException { - if (!TestUtil.haveMinimumServerVersion(_conn, "9.0")) { + if (!TestUtil.haveMinimumServerVersion(_conn, ServerVersion.v9_0)) { return; } @@ -98,7 +99,7 @@ public class ClientInfoTest extends TestCase { * Test that a name missing in the properties given to setClientInfo should be unset (spec) */ public void testMissingName() throws SQLException { - if (!TestUtil.haveMinimumServerVersion(_conn, "9.0")) { + if (!TestUtil.haveMinimumServerVersion(_conn, ServerVersion.v9_0)) { return; } diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc4/DatabaseMetaDataTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc4/DatabaseMetaDataTest.java index eee3114a..ee859ede 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc4/DatabaseMetaDataTest.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc4/DatabaseMetaDataTest.java @@ -5,6 +5,7 @@ package org.postgresql.test.jdbc4; +import org.postgresql.core.ServerVersion; import org.postgresql.test.TestUtil; import junit.framework.TestCase; @@ -38,7 +39,7 @@ public class DatabaseMetaDataTest extends TestCase { DatabaseMetaData dbmd = _conn.getMetaData(); ResultSet rs = dbmd.getClientInfoProperties(); - if (!TestUtil.haveMinimumServerVersion(_conn, "9.0")) { + if (!TestUtil.haveMinimumServerVersion(_conn, ServerVersion.v9_0)) { assertTrue(!rs.next()); return; } @@ -67,11 +68,6 @@ public class DatabaseMetaDataTest extends TestCase { ResultSet rs = dbmd.getSchemas("", "publ%"); - if (!TestUtil.haveMinimumServerVersion(_conn, "7.3")) { - assertTrue(!rs.next()); - return; - } - assertTrue(rs.next()); assertEquals("public", rs.getString("TABLE_SCHEM")); assertNull(rs.getString("TABLE_CATALOG")); diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc4/Jdbc4TestSuite.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc4/Jdbc4TestSuite.java index 4fa70a63..288afeb9 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc4/Jdbc4TestSuite.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc4/Jdbc4TestSuite.java @@ -5,6 +5,7 @@ package org.postgresql.test.jdbc4; +import org.postgresql.core.ServerVersion; import org.postgresql.test.TestUtil; import junit.framework.JUnit4TestAdapter; @@ -38,7 +39,7 @@ public class Jdbc4TestSuite extends TestSuite { Connection connection = TestUtil.openDB(); try { - if (TestUtil.haveMinimumServerVersion(connection, "8.3")) { + if (TestUtil.haveMinimumServerVersion(connection, ServerVersion.v8_3)) { suite.addTest(new JUnit4TestAdapter(UUIDTest.class)); if (isXmlEnabled(connection)) { suite.addTestSuite(XmlTest.class); diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc4/JsonbTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc4/JsonbTest.java index 98771f9c..85294126 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc4/JsonbTest.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc4/JsonbTest.java @@ -8,6 +8,8 @@ package org.postgresql.test.jdbc4; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import org.postgresql.core.ServerVersion; + import org.postgresql.test.TestUtil; import org.postgresql.test.jdbc2.BaseTest4; @@ -24,7 +26,7 @@ public class JsonbTest extends BaseTest4 { @Override public void setUp() throws Exception { super.setUp(); - Assume.assumeTrue("jsonb requires PostgreSQL 9.4+", TestUtil.haveMinimumServerVersion(con, "9.4")); + Assume.assumeTrue("jsonb requires PostgreSQL 9.4+", TestUtil.haveMinimumServerVersion(con, ServerVersion.v9_4)); TestUtil.createTable(con, "jsonbtest", "detail jsonb"); Statement stmt = con.createStatement(); stmt.executeUpdate("INSERT INTO jsonbtest (detail) VALUES ('{\"a\": 1}')"); diff --git a/pgjdbc/src/test/java/org/postgresql/test/sspi/SSPITestSuite.java b/pgjdbc/src/test/java/org/postgresql/test/sspi/SSPITestSuite.java index e281d60f..6e1ae338 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/sspi/SSPITestSuite.java +++ b/pgjdbc/src/test/java/org/postgresql/test/sspi/SSPITestSuite.java @@ -5,14 +5,11 @@ package org.postgresql.test.sspi; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - /* * Executes all known tests for SSPI. */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ SSPITest.class }) +//@RunWith(Suite.class) +//@Suite.SuiteClasses({ SSPITest.class }) public class SSPITestSuite { // Empty. } diff --git a/pgjdbc/src/test/java/org/postgresql/test/xa/XATestSuite.java b/pgjdbc/src/test/java/org/postgresql/test/xa/XATestSuite.java index de444a89..da8b96c2 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/xa/XATestSuite.java +++ b/pgjdbc/src/test/java/org/postgresql/test/xa/XATestSuite.java @@ -19,19 +19,17 @@ public class XATestSuite extends TestSuite { Connection connection = TestUtil.openDB(); try { - if (TestUtil.haveMinimumServerVersion(connection, "8.1")) { - Statement stmt = connection.createStatement(); - ResultSet rs = stmt.executeQuery("SHOW max_prepared_transactions"); - rs.next(); - int mpt = rs.getInt(1); - if (mpt > 0) { - suite.addTestSuite(XADataSourceTest.class); - } else { - System.out.println("Skipping XA tests because max_prepared_transactions = 0."); - } - rs.close(); - stmt.close(); + Statement stmt = connection.createStatement(); + ResultSet rs = stmt.executeQuery("SHOW max_prepared_transactions"); + rs.next(); + int mpt = rs.getInt(1); + if (mpt > 0) { + suite.addTestSuite(XADataSourceTest.class); + } else { + System.out.println("Skipping XA tests because max_prepared_transactions = 0."); } + rs.close(); + stmt.close(); } finally { connection.close(); } [parent: 63ee60e2ad93]