diff --git a/src/interfaces/jdbc/CHANGELOG b/src/interfaces/jdbc/CHANGELOG index b6104df13a..6ea613f277 100644 --- a/src/interfaces/jdbc/CHANGELOG +++ b/src/interfaces/jdbc/CHANGELOG @@ -1,3 +1,15 @@ +Mon May 17 23:40:00 BST 1999 + - PG_Stream.close() now attempts to send the close connection message + to the backend before closing the streams + - Added batch support in the JDBC2, supplied by Yutaka Tanida + - Removed the old datestyle code. Now the driver uses only ISO. + - Removed some files in the postgresql directory still in CVS that were + moved since 6.4.x (DatabaseMetaData.java PreparedStatement.java + ResultSetMetaData.java Statement.java) + - Internationalisation of the error messages is partially implemented, however + it's not enabled as it only works when the jar file is _not_ used, and + work needs to be done. + Sun Apr 11 17:00:00 BST 1999 - getUpdateCount() now returns the actual update count (before it simply returned 1 for everything). diff --git a/src/interfaces/jdbc/postgresql/Connection.java b/src/interfaces/jdbc/postgresql/Connection.java index 4ec6fdb177..fdbc936a66 100644 --- a/src/interfaces/jdbc/postgresql/Connection.java +++ b/src/interfaces/jdbc/postgresql/Connection.java @@ -10,7 +10,7 @@ import postgresql.largeobject.*; import postgresql.util.*; /** - * $Id: Connection.java,v 1.15 1999/04/11 18:03:00 peter Exp $ + * $Id: Connection.java,v 1.16 1999/05/17 22:43:23 peter Exp $ * * This abstract class is used by postgresql.Driver to open either the JDBC1 or * JDBC2 versions of the Connection class. @@ -67,38 +67,6 @@ public abstract class Connection // be across all connections, which could be to different backends. public Hashtable fieldCache = new Hashtable(); - /** - * This is the current date style of the backend - */ - public int currentDateStyle; - - /** - * This defines the formats for dates, according to the various date styles. - * - *

There are two strings for each entry. The first is the string to search - * for in the datestyle message, and the second the format to use. - * - *

To add a new date style, work out the format. Then with psql running - * in the date style you wish to add, type: show datestyle; - * - *

eg: - *

-   * => show datestyle;
-   * NOTICE:  Datestyle is SQL with European conventions
-   *                       ^^^^^^^^^^^^^^^^^
-   * 
The marked part of the string is the first string below. The second - * is your format. If a style (like ISO) ignores the US/European variants, - * then you can ignore the "with" part of the string. - */ - protected static final String dateStyles[] = { - "Postgres with European", "dd-MM-yyyy", - "Postgres with US", "MM-dd-yyyy", - "ISO", "yyyy-MM-dd", - "SQL with European", "dd/MM/yyyy", - "SQL with US", "MM/dd/yyyy", - "German", "dd.MM.yyyy" - }; - // Now handle notices as warnings, so things like "show" now work public SQLWarning firstWarning = null; @@ -242,22 +210,24 @@ public abstract class Connection throw new SQLException("Connection failed: " + e.toString()); } - // Find out the date style by issuing the SQL: show datestyle - // This actually issues a warning, and our own warning handling - // code handles this itself. - // - // Also, this query replaced the NULL query issued to test the - // connection. - // + // Originally we issued a SHOW DATESTYLE statement to find the databases default + // datestyle. However, this caused some problems with timestamps, so in 6.5, we + // went the way of ODBC, and set the connection to ISO. + // + // This may cause some clients to break when they assume anything other than ISO, + // but then - they should be using the proper methods ;-) + // + // firstWarning = null; - ExecSQL("show datestyle"); - - // Initialise object handling - initObjectTypes(); - - // Mark the connection as ok, and cleanup + + ExecSQL("set datestyle to 'ISO'"); + + // Initialise object handling + initObjectTypes(); + + // Mark the connection as ok, and cleanup firstWarning = null; - PG_STATUS = CONNECTION_OK; + PG_STATUS = CONNECTION_OK; } // These methods used to be in the main Connection implementation. As they @@ -280,23 +250,18 @@ public abstract class Connection // Now check for some specific messages + // This is obsolete in 6.5, but I've left it in here so if we need to use this + // technique again, we'll know where to place it. + // // This is generated by the SQL "show datestyle" - if(msg.startsWith("NOTICE:") && msg.indexOf("DateStyle")>0) { - // 13 is the length off "DateStyle is " - msg = msg.substring(msg.indexOf("DateStyle is ")+13); - - for(int i=0;i0) { + //// 13 is the length off "DateStyle is " + //msg = msg.substring(msg.indexOf("DateStyle is ")+13); + // + //for(int i=0;iMany of the methods here return lists of information in ResultSets. You - * can use the normal ResultSet methods such as getString and getInt to - * retrieve the data from these ResultSets. If a given form of metadata is - * not available, these methods should throw a SQLException. - * - *

Some of these methods take arguments that are String patterns. These - * arguments all have names such as fooPattern. Within a pattern String, - * "%" means match any substring of 0 or more characters, and "_" means - * match any one character. Only metadata entries matching the search - * pattern are returned. if a search pattern argument is set to a null - * ref, it means that argument's criteria should be dropped from the - * search. - * - *

A SQLException will be throws if a driver does not support a meta - * data method. In the case of methods that return a ResultSet, either - * a ResultSet (which may be empty) is returned or a SQLException is - * thrown. - * - * @see java.sql.DatabaseMetaData - */ -public class DatabaseMetaData implements java.sql.DatabaseMetaData -{ - Connection connection; // The connection association - - // These define various OID's. Hopefully they will stay constant. - static final int iVarcharOid = 1043; // OID for varchar - static final int iBoolOid = 16; // OID for bool - static final int iInt2Oid = 21; // OID for int2 - static final int iInt4Oid = 23; // OID for int4 - static final int VARHDRSZ = 4; // length for int4 - - // This is a default value for remarks - private static final byte defaultRemarks[]="no remarks".getBytes(); - - public DatabaseMetaData(Connection conn) - { - this.connection = conn; - } - - /** - * Can all the procedures returned by getProcedures be called - * by the current user? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean allProceduresAreCallable() throws SQLException - { - return true; // For now... - } - - /** - * Can all the tables returned by getTable be SELECTed by - * the current user? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean allTablesAreSelectable() throws SQLException - { - return true; // For now... - } - - /** - * What is the URL for this database? - * - * @return the url or null if it cannott be generated - * @exception SQLException if a database access error occurs - */ - public String getURL() throws SQLException - { - return connection.getURL(); - } - - /** - * What is our user name as known to the database? - * - * @return our database user name - * @exception SQLException if a database access error occurs - */ - public String getUserName() throws SQLException - { - return connection.getUserName(); - } - - /** - * Is the database in read-only mode? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean isReadOnly() throws SQLException - { - return connection.isReadOnly(); - } - - /** - * Are NULL values sorted high? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean nullsAreSortedHigh() throws SQLException - { - return false; - } - - /** - * Are NULL values sorted low? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean nullsAreSortedLow() throws SQLException - { - return false; - } - - /** - * Are NULL values sorted at the start regardless of sort order? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean nullsAreSortedAtStart() throws SQLException - { - return false; - } - - /** - * Are NULL values sorted at the end regardless of sort order? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean nullsAreSortedAtEnd() throws SQLException - { - return true; - } - - /** - * What is the name of this database product - we hope that it is - * PostgreSQL, so we return that explicitly. - * - * @return the database product name - * @exception SQLException if a database access error occurs - */ - public String getDatabaseProductName() throws SQLException - { - return new String("PostgreSQL"); - } - - /** - * What is the version of this database product. - * - *

Note that PostgreSQL 6.3 has a system catalog called pg_version - - * however, select * from pg_version on any database retrieves - * no rows. - * - *

For now, we will return the version 6.3 (in the hope that we change - * this driver as often as we change the database) - * - * @return the database version - * @exception SQLException if a database access error occurs - */ - public String getDatabaseProductVersion() throws SQLException - { - return ("6.4"); - } - - /** - * What is the name of this JDBC driver? If we don't know this - * we are doing something wrong! - * - * @return the JDBC driver name - * @exception SQLException why? - */ - public String getDriverName() throws SQLException - { - return new String("PostgreSQL Native Driver"); - } - - /** - * What is the version string of this JDBC driver? Again, this is - * static. - * - * @return the JDBC driver name. - * @exception SQLException why? - */ - public String getDriverVersion() throws SQLException - { - return new String(Integer.toString(connection.this_driver.getMajorVersion())+"."+Integer.toString(connection.this_driver.getMinorVersion())); - } - - /** - * What is this JDBC driver's major version number? - * - * @return the JDBC driver major version - */ - public int getDriverMajorVersion() - { - return connection.this_driver.getMajorVersion(); - } - - /** - * What is this JDBC driver's minor version number? - * - * @return the JDBC driver minor version - */ - public int getDriverMinorVersion() - { - return connection.this_driver.getMinorVersion(); - } - - /** - * Does the database store tables in a local file? No - it - * stores them in a file on the server. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean usesLocalFiles() throws SQLException - { - return false; - } - - /** - * Does the database use a file for each table? Well, not really, - * since it doesnt use local files. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean usesLocalFilePerTable() throws SQLException - { - return false; - } - - /** - * Does the database treat mixed case unquoted SQL identifiers - * as case sensitive and as a result store them in mixed case? - * A JDBC-Compliant driver will always return false. - * - *

Predicament - what do they mean by "SQL identifiers" - if it - * means the names of the tables and columns, then the answers - * given below are correct - otherwise I don't know. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsMixedCaseIdentifiers() throws SQLException - { - return false; - } - - /** - * Does the database treat mixed case unquoted SQL identifiers as - * case insensitive and store them in upper case? - * - * @return true if so - */ - public boolean storesUpperCaseIdentifiers() throws SQLException - { - return false; - } - - /** - * Does the database treat mixed case unquoted SQL identifiers as - * case insensitive and store them in lower case? - * - * @return true if so - */ - public boolean storesLowerCaseIdentifiers() throws SQLException - { - return true; - } - - /** - * Does the database treat mixed case unquoted SQL identifiers as - * case insensitive and store them in mixed case? - * - * @return true if so - */ - public boolean storesMixedCaseIdentifiers() throws SQLException - { - return false; - } - - /** - * Does the database treat mixed case quoted SQL identifiers as - * case sensitive and as a result store them in mixed case? A - * JDBC compliant driver will always return true. - * - *

Predicament - what do they mean by "SQL identifiers" - if it - * means the names of the tables and columns, then the answers - * given below are correct - otherwise I don't know. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException - { - return true; - } - - /** - * Does the database treat mixed case quoted SQL identifiers as - * case insensitive and store them in upper case? - * - * @return true if so - */ - public boolean storesUpperCaseQuotedIdentifiers() throws SQLException - { - return false; - } - - /** - * Does the database treat mixed case quoted SQL identifiers as case - * insensitive and store them in lower case? - * - * @return true if so - */ - public boolean storesLowerCaseQuotedIdentifiers() throws SQLException - { - return false; - } - - /** - * Does the database treat mixed case quoted SQL identifiers as case - * insensitive and store them in mixed case? - * - * @return true if so - */ - public boolean storesMixedCaseQuotedIdentifiers() throws SQLException - { - return false; - } - - /** - * What is the string used to quote SQL identifiers? This returns - * a space if identifier quoting isn't supported. A JDBC Compliant - * driver will always use a double quote character. - * - *

If an SQL identifier is a table name, column name, etc. then - * we do not support it. - * - * @return the quoting string - * @exception SQLException if a database access error occurs - */ - public String getIdentifierQuoteString() throws SQLException - { - return null; - } - - /** - * Get a comma separated list of all a database's SQL keywords that - * are NOT also SQL92 keywords. - * - *

Within PostgreSQL, the keywords are found in - * src/backend/parser/keywords.c - * - *

For SQL Keywords, I took the list provided at - * - * http://web.dementia.org/~shadow/sql/sql3bnf.sep93.txt - * which is for SQL3, not SQL-92, but it is close enough for - * this purpose. - * - * @return a comma separated list of keywords we use - * @exception SQLException if a database access error occurs - */ - public String getSQLKeywords() throws SQLException - { - return new String("abort,acl,add,aggregate,append,archive,arch_store,backward,binary,change,cluster,copy,database,delimiters,do,extend,explain,forward,heavy,index,inherits,isnull,light,listen,load,merge,nothing,notify,notnull,oids,purge,rename,replace,retrieve,returns,rule,recipe,setof,stdin,stdout,store,vacuum,verbose,version"); - } - - public String getNumericFunctions() throws SQLException - { - // XXX-Not Implemented - return ""; - } - - public String getStringFunctions() throws SQLException - { - // XXX-Not Implemented - return ""; - } - - public String getSystemFunctions() throws SQLException - { - // XXX-Not Implemented - return ""; - } - - public String getTimeDateFunctions() throws SQLException - { - // XXX-Not Implemented - return ""; - } - - /** - * This is the string that can be used to escape '_' and '%' in - * a search string pattern style catalog search parameters - * - * @return the string used to escape wildcard characters - * @exception SQLException if a database access error occurs - */ - public String getSearchStringEscape() throws SQLException - { - return new String("\\"); - } - - /** - * Get all the "extra" characters that can bew used in unquoted - * identifier names (those beyond a-zA-Z0-9 and _) - * - *

From the file src/backend/parser/scan.l, an identifier is - * {letter}{letter_or_digit} which makes it just those listed - * above. - * - * @return a string containing the extra characters - * @exception SQLException if a database access error occurs - */ - public String getExtraNameCharacters() throws SQLException - { - return new String(""); - } - - /** - * Is "ALTER TABLE" with an add column supported? - * Yes for PostgreSQL 6.1 - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsAlterTableWithAddColumn() throws SQLException - { - return true; - } - - /** - * Is "ALTER TABLE" with a drop column supported? - * Yes for PostgreSQL 6.1 - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsAlterTableWithDropColumn() throws SQLException - { - return true; - } - - /** - * Is column aliasing supported? - * - *

If so, the SQL AS clause can be used to provide names for - * computed columns or to provide alias names for columns as - * required. A JDBC Compliant driver always returns true. - * - *

e.g. - * - *

-   * select count(C) as C_COUNT from T group by C;
-   *
-   * 

- * should return a column named as C_COUNT instead of count(C) - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsColumnAliasing() throws SQLException - { - return true; - } - - /** - * Are concatenations between NULL and non-NULL values NULL? A - * JDBC Compliant driver always returns true - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean nullPlusNonNullIsNull() throws SQLException - { - return true; - } - - public boolean supportsConvert() throws SQLException - { - // XXX-Not Implemented - return false; - } - - public boolean supportsConvert(int fromType, int toType) throws SQLException - { - // XXX-Not Implemented - return false; - } - - public boolean supportsTableCorrelationNames() throws SQLException - { - // XXX-Not Implemented - return false; - } - - public boolean supportsDifferentTableCorrelationNames() throws SQLException - { - // XXX-Not Implemented - return false; - } - - /** - * Are expressions in "ORCER BY" lists supported? - * - *
e.g. select * from t order by a + b; - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsExpressionsInOrderBy() throws SQLException - { - return true; - } - - /** - * Can an "ORDER BY" clause use columns not in the SELECT? - * I checked it, and you can't. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsOrderByUnrelated() throws SQLException - { - return false; - } - - /** - * Is some form of "GROUP BY" clause supported? - * I checked it, and yes it is. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsGroupBy() throws SQLException - { - return true; - } - - /** - * Can a "GROUP BY" clause use columns not in the SELECT? - * I checked it - it seems to allow it - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsGroupByUnrelated() throws SQLException - { - return true; - } - - /** - * Can a "GROUP BY" clause add columns not in the SELECT provided - * it specifies all the columns in the SELECT? Does anyone actually - * understand what they mean here? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsGroupByBeyondSelect() throws SQLException - { - return true; // For now... - } - - /** - * Is the escape character in "LIKE" clauses supported? A - * JDBC compliant driver always returns true. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsLikeEscapeClause() throws SQLException - { - return true; - } - - /** - * Are multiple ResultSets from a single execute supported? - * Well, I implemented it, but I dont think this is possible from - * the back ends point of view. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsMultipleResultSets() throws SQLException - { - return false; - } - - /** - * Can we have multiple transactions open at once (on different - * connections?) - * I guess we can have, since Im relying on it. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsMultipleTransactions() throws SQLException - { - return true; - } - - /** - * Can columns be defined as non-nullable. A JDBC Compliant driver - * always returns true. - * - *

This changed from false to true in v6.2 of the driver, as this - * support was added to the backend. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsNonNullableColumns() throws SQLException - { - return true; - } - - /** - * Does this driver support the minimum ODBC SQL grammar. This - * grammar is defined at: - * - *

http://www.microsoft.com/msdn/sdk/platforms/doc/odbc/src/intropr.htm - * - *

In Appendix C. From this description, we seem to support the - * ODBC minimal (Level 0) grammar. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsMinimumSQLGrammar() throws SQLException - { - return true; - } - - /** - * Does this driver support the Core ODBC SQL grammar. We need - * SQL-92 conformance for this. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsCoreSQLGrammar() throws SQLException - { - return false; - } - - /** - * Does this driver support the Extended (Level 2) ODBC SQL - * grammar. We don't conform to the Core (Level 1), so we can't - * conform to the Extended SQL Grammar. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsExtendedSQLGrammar() throws SQLException - { - return false; - } - - /** - * Does this driver support the ANSI-92 entry level SQL grammar? - * All JDBC Compliant drivers must return true. I think we have - * to support outer joins for this to be true. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsANSI92EntryLevelSQL() throws SQLException - { - return false; - } - - /** - * Does this driver support the ANSI-92 intermediate level SQL - * grammar? Anyone who does not support Entry level cannot support - * Intermediate level. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsANSI92IntermediateSQL() throws SQLException - { - return false; - } - - /** - * Does this driver support the ANSI-92 full SQL grammar? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsANSI92FullSQL() throws SQLException - { - return false; - } - - /** - * Is the SQL Integrity Enhancement Facility supported? - * I haven't seen this mentioned anywhere, so I guess not - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsIntegrityEnhancementFacility() throws SQLException - { - return false; - } - - /** - * Is some form of outer join supported? From my knowledge, nope. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsOuterJoins() throws SQLException - { - return false; - } - - /** - * Are full nexted outer joins supported? Well, we dont support any - * form of outer join, so this is no as well - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsFullOuterJoins() throws SQLException - { - return false; - } - - /** - * Is there limited support for outer joins? (This will be true if - * supportFullOuterJoins is true) - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsLimitedOuterJoins() throws SQLException - { - return false; - } - - /** - * What is the database vendor's preferred term for "schema" - well, - * we do not provide support for schemas, so lets just use that - * term. - * - * @return the vendor term - * @exception SQLException if a database access error occurs - */ - public String getSchemaTerm() throws SQLException - { - return new String("Schema"); - } - - /** - * What is the database vendor's preferred term for "procedure" - - * I kind of like "Procedure" myself. - * - * @return the vendor term - * @exception SQLException if a database access error occurs - */ - public String getProcedureTerm() throws SQLException - { - return new String("Procedure"); - } - - /** - * What is the database vendor's preferred term for "catalog"? - - * we dont have a preferred term, so just use Catalog - * - * @return the vendor term - * @exception SQLException if a database access error occurs - */ - public String getCatalogTerm() throws SQLException - { - return new String("Catalog"); - } - - /** - * Does a catalog appear at the start of a qualified table name? - * (Otherwise it appears at the end). - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean isCatalogAtStart() throws SQLException - { - return false; - } - - /** - * What is the Catalog separator. Hmmm....well, I kind of like - * a period (so we get catalog.table definitions). - I don't think - * PostgreSQL supports catalogs anyhow, so it makes no difference. - * - * @return the catalog separator string - * @exception SQLException if a database access error occurs - */ - public String getCatalogSeparator() throws SQLException - { - // PM Sep 29 97 - changed from "." as we don't support catalogs. - return new String(""); - } - - /** - * Can a schema name be used in a data manipulation statement? Nope. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsSchemasInDataManipulation() throws SQLException - { - return false; - } - - /** - * Can a schema name be used in a procedure call statement? Nope. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsSchemasInProcedureCalls() throws SQLException - { - return false; - } - - /** - * Can a schema be used in a table definition statement? Nope. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsSchemasInTableDefinitions() throws SQLException - { - return false; - } - - /** - * Can a schema name be used in an index definition statement? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsSchemasInIndexDefinitions() throws SQLException - { - return false; - } - - /** - * Can a schema name be used in a privilege definition statement? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException - { - return false; - } - - /** - * Can a catalog name be used in a data manipulation statement? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsCatalogsInDataManipulation() throws SQLException - { - return false; - } - - /** - * Can a catalog name be used in a procedure call statement? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsCatalogsInProcedureCalls() throws SQLException - { - return false; - } - - /** - * Can a catalog name be used in a table definition statement? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsCatalogsInTableDefinitions() throws SQLException - { - return false; - } - - /** - * Can a catalog name be used in an index definition? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsCatalogsInIndexDefinitions() throws SQLException - { - return false; - } - - /** - * Can a catalog name be used in a privilege definition statement? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException - { - return false; - } - - /** - * We support cursors for gets only it seems. I dont see a method - * to get a positioned delete. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsPositionedDelete() throws SQLException - { - return false; // For now... - } - - /** - * Is positioned UPDATE supported? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsPositionedUpdate() throws SQLException - { - return false; // For now... - } - - public boolean supportsSelectForUpdate() throws SQLException - { - // XXX-Not Implemented - return false; - } - - public boolean supportsStoredProcedures() throws SQLException - { - // XXX-Not Implemented - return false; - } - - public boolean supportsSubqueriesInComparisons() throws SQLException - { - // XXX-Not Implemented - return false; - } - - public boolean supportsSubqueriesInExists() throws SQLException - { - // XXX-Not Implemented - return false; - } - - public boolean supportsSubqueriesInIns() throws SQLException - { - // XXX-Not Implemented - return false; - } - - public boolean supportsSubqueriesInQuantifieds() throws SQLException - { - // XXX-Not Implemented - return false; - } - - public boolean supportsCorrelatedSubqueries() throws SQLException - { - // XXX-Not Implemented - return false; - } - - /** - * Is SQL UNION supported? Nope. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsUnion() throws SQLException - { - return false; - } - - /** - * Is SQL UNION ALL supported? Nope. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsUnionAll() throws SQLException - { - return false; - } - - /** - * In PostgreSQL, Cursors are only open within transactions. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsOpenCursorsAcrossCommit() throws SQLException - { - return false; - } - - /** - * Do we support open cursors across multiple transactions? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsOpenCursorsAcrossRollback() throws SQLException - { - return false; - } - - /** - * Can statements remain open across commits? They may, but - * this driver cannot guarentee that. In further reflection. - * we are talking a Statement object jere, so the answer is - * yes, since the Statement is only a vehicle to ExecSQL() - * - * @return true if they always remain open; false otherwise - * @exception SQLException if a database access error occurs - */ - public boolean supportsOpenStatementsAcrossCommit() throws SQLException - { - return true; - } - - /** - * Can statements remain open across rollbacks? They may, but - * this driver cannot guarentee that. In further contemplation, - * we are talking a Statement object here, so the answer is yes, - * since the Statement is only a vehicle to ExecSQL() in Connection - * - * @return true if they always remain open; false otherwise - * @exception SQLException if a database access error occurs - */ - public boolean supportsOpenStatementsAcrossRollback() throws SQLException - { - return true; - } - - /** - * How many hex characters can you have in an inline binary literal - * - * @return the max literal length - * @exception SQLException if a database access error occurs - */ - public int getMaxBinaryLiteralLength() throws SQLException - { - return 0; // For now... - } - - /** - * What is the maximum length for a character literal - * I suppose it is 8190 (8192 - 2 for the quotes) - * - * @return the max literal length - * @exception SQLException if a database access error occurs - */ - public int getMaxCharLiteralLength() throws SQLException - { - return 8190; - } - - /** - * Whats the limit on column name length. The description of - * pg_class would say '32' (length of pg_class.relname) - we - * should probably do a query for this....but.... - * - * @return the maximum column name length - * @exception SQLException if a database access error occurs - */ - public int getMaxColumnNameLength() throws SQLException - { - return 32; - } - - /** - * What is the maximum number of columns in a "GROUP BY" clause? - * - * @return the max number of columns - * @exception SQLException if a database access error occurs - */ - public int getMaxColumnsInGroupBy() throws SQLException - { - return getMaxColumnsInTable(); - } - - /** - * What's the maximum number of columns allowed in an index? - * 6.0 only allowed one column, but 6.1 introduced multi-column - * indices, so, theoretically, its all of them. - * - * @return max number of columns - * @exception SQLException if a database access error occurs - */ - public int getMaxColumnsInIndex() throws SQLException - { - return getMaxColumnsInTable(); - } - - /** - * What's the maximum number of columns in an "ORDER BY clause? - * Theoretically, all of them! - * - * @return the max columns - * @exception SQLException if a database access error occurs - */ - public int getMaxColumnsInOrderBy() throws SQLException - { - return getMaxColumnsInTable(); - } - - /** - * What is the maximum number of columns in a "SELECT" list? - * Theoretically, all of them! - * - * @return the max columns - * @exception SQLException if a database access error occurs - */ - public int getMaxColumnsInSelect() throws SQLException - { - return getMaxColumnsInTable(); - } - - /** - * What is the maximum number of columns in a table? From the - * create_table(l) manual page... - * - *

"The new class is created as a heap with no initial data. A - * class can have no more than 1600 attributes (realistically, - * this is limited by the fact that tuple sizes must be less than - * 8192 bytes)..." - * - * @return the max columns - * @exception SQLException if a database access error occurs - */ - public int getMaxColumnsInTable() throws SQLException - { - return 1600; - } - - /** - * How many active connection can we have at a time to this - * database? Well, since it depends on postmaster, which just - * does a listen() followed by an accept() and fork(), its - * basically very high. Unless the system runs out of processes, - * it can be 65535 (the number of aux. ports on a TCP/IP system). - * I will return 8192 since that is what even the largest system - * can realistically handle, - * - * @return the maximum number of connections - * @exception SQLException if a database access error occurs - */ - public int getMaxConnections() throws SQLException - { - return 8192; - } - - /** - * What is the maximum cursor name length (the same as all - * the other F***** identifiers!) - * - * @return max cursor name length in bytes - * @exception SQLException if a database access error occurs - */ - public int getMaxCursorNameLength() throws SQLException - { - return 32; - } - - /** - * What is the maximum length of an index (in bytes)? Now, does - * the spec. mean name of an index (in which case its 32, the - * same as a table) or does it mean length of an index element - * (in which case its 8192, the size of a row) or does it mean - * the number of rows it can access (in which case it 2^32 - - * a 4 byte OID number)? I think its the length of an index - * element, personally, so Im setting it to 8192. - * - * @return max index length in bytes - * @exception SQLException if a database access error occurs - */ - public int getMaxIndexLength() throws SQLException - { - return 8192; - } - - public int getMaxSchemaNameLength() throws SQLException - { - // XXX-Not Implemented - return 0; - } - - /** - * What is the maximum length of a procedure name? - * (length of pg_proc.proname used) - again, I really - * should do a query here to get it. - * - * @return the max name length in bytes - * @exception SQLException if a database access error occurs - */ - public int getMaxProcedureNameLength() throws SQLException - { - return 32; - } - - public int getMaxCatalogNameLength() throws SQLException - { - // XXX-Not Implemented - return 0; - } - - /** - * What is the maximum length of a single row? (not including - * blobs). 8192 is defined in PostgreSQL. - * - * @return max row size in bytes - * @exception SQLException if a database access error occurs - */ - public int getMaxRowSize() throws SQLException - { - return 8192; - } - - /** - * Did getMaxRowSize() include LONGVARCHAR and LONGVARBINARY - * blobs? We don't handle blobs yet - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean doesMaxRowSizeIncludeBlobs() throws SQLException - { - return false; - } - - /** - * What is the maximum length of a SQL statement? - * - * @return max length in bytes - * @exception SQLException if a database access error occurs - */ - public int getMaxStatementLength() throws SQLException - { - return 8192; - } - - /** - * How many active statements can we have open at one time to - * this database? Basically, since each Statement downloads - * the results as the query is executed, we can have many. However, - * we can only really have one statement per connection going - * at once (since they are executed serially) - so we return - * one. - * - * @return the maximum - * @exception SQLException if a database access error occurs - */ - public int getMaxStatements() throws SQLException - { - return 1; - } - - /** - * What is the maximum length of a table name? This was found - * from pg_class.relname length - * - * @return max name length in bytes - * @exception SQLException if a database access error occurs - */ - public int getMaxTableNameLength() throws SQLException - { - return 32; - } - - /** - * What is the maximum number of tables that can be specified - * in a SELECT? Theoretically, this is the same number as the - * number of tables allowable. In practice tho, it is much smaller - * since the number of tables is limited by the statement, we - * return 1024 here - this is just a number I came up with (being - * the number of tables roughly of three characters each that you - * can fit inside a 8192 character buffer with comma separators). - * - * @return the maximum - * @exception SQLException if a database access error occurs - */ - public int getMaxTablesInSelect() throws SQLException - { - return 1024; - } - - /** - * What is the maximum length of a user name? Well, we generally - * use UNIX like user names in PostgreSQL, so I think this would - * be 8. However, showing the schema for pg_user shows a length - * for username of 32. - * - * @return the max name length in bytes - * @exception SQLException if a database access error occurs - */ - public int getMaxUserNameLength() throws SQLException - { - return 32; - } - - - /** - * What is the database's default transaction isolation level? We - * do not support this, so all transactions are SERIALIZABLE. - * - * @return the default isolation level - * @exception SQLException if a database access error occurs - * @see Connection - */ - public int getDefaultTransactionIsolation() throws SQLException - { - return Connection.TRANSACTION_SERIALIZABLE; - } - - /** - * Are transactions supported? If not, commit and rollback are noops - * and the isolation level is TRANSACTION_NONE. We do support - * transactions. - * - * @return true if transactions are supported - * @exception SQLException if a database access error occurs - */ - public boolean supportsTransactions() throws SQLException - { - return true; - } - - /** - * Does the database support the given transaction isolation level? - * We only support TRANSACTION_SERIALIZABLE - * - * @param level the values are defined in java.sql.Connection - * @return true if so - * @exception SQLException if a database access error occurs - * @see Connection - */ - public boolean supportsTransactionIsolationLevel(int level) throws SQLException - { - if (level == Connection.TRANSACTION_SERIALIZABLE) - return true; - else - return false; - } - - /** - * Are both data definition and data manipulation transactions - * supported? I checked it, and could not do a CREATE TABLE - * within a transaction, so I am assuming that we don't - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException - { - return false; - } - - /** - * Are only data manipulation statements withing a transaction - * supported? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsDataManipulationTransactionsOnly() throws SQLException - { - return true; - } - - /** - * Does a data definition statement within a transaction force - * the transaction to commit? I think this means something like: - * - *

-   * CREATE TABLE T (A INT);
-   * INSERT INTO T (A) VALUES (2);
-   * BEGIN;
-   * UPDATE T SET A = A + 1;
-   * CREATE TABLE X (A INT);
-   * SELECT A FROM T INTO X;
-   * COMMIT;
-   * 

- * - * does the CREATE TABLE call cause a commit? The answer is no. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean dataDefinitionCausesTransactionCommit() throws SQLException - { - return false; - } - - /** - * Is a data definition statement within a transaction ignored? - * It seems to be (from experiment in previous method) - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean dataDefinitionIgnoredInTransactions() throws SQLException - { - return true; - } - - /** - * Get a description of stored procedures available in a catalog - * - *

Only procedure descriptions matching the schema and procedure - * name criteria are returned. They are ordered by PROCEDURE_SCHEM - * and PROCEDURE_NAME - * - *

Each procedure description has the following columns: - *

    - *
  1. PROCEDURE_CAT String => procedure catalog (may be null) - *
  2. PROCEDURE_SCHEM String => procedure schema (may be null) - *
  3. PROCEDURE_NAME String => procedure name - *
  4. Field 4 reserved (make it null) - *
  5. Field 5 reserved (make it null) - *
  6. Field 6 reserved (make it null) - *
  7. REMARKS String => explanatory comment on the procedure - *
  8. PROCEDURE_TYPE short => kind of procedure - *
      - *
    • procedureResultUnknown - May return a result - *
    • procedureNoResult - Does not return a result - *
    • procedureReturnsResult - Returns a result - *
    - *
- * - * @param catalog - a catalog name; "" retrieves those without a - * catalog; null means drop catalog name from criteria - * @param schemaParrern - a schema name pattern; "" retrieves those - * without a schema - we ignore this parameter - * @param procedureNamePattern - a procedure name pattern - * @return ResultSet - each row is a procedure description - * @exception SQLException if a database access error occurs - */ - public java.sql.ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern) throws SQLException - { - // the field descriptors for the new ResultSet - Field f[] = new Field[8]; - ResultSet r; // ResultSet for the SQL query that we need to do - Vector v = new Vector(); // The new ResultSet tuple stuff - - byte remarks[] = defaultRemarks; - - f[0] = new Field(connection, "PROCEDURE_CAT", iVarcharOid, 32); - f[1] = new Field(connection, "PROCEDURE_SCHEM", iVarcharOid, 32); - f[2] = new Field(connection, "PROCEDURE_NAME", iVarcharOid, 32); - f[3] = f[4] = f[5] = null; // reserved, must be null for now - f[6] = new Field(connection, "REMARKS", iVarcharOid, 8192); - f[7] = new Field(connection, "PROCEDURE_TYPE", iInt2Oid, 2); - - // If the pattern is null, then set it to the default - if(procedureNamePattern==null) - procedureNamePattern="%"; - - r = connection.ExecSQL("select proname, proretset from pg_proc where proname like '"+procedureNamePattern.toLowerCase()+"' order by proname"); - - while (r.next()) - { - byte[][] tuple = new byte[8][0]; - - tuple[0] = null; // Catalog name - tuple[1] = null; // Schema name - tuple[2] = r.getBytes(1); // Procedure name - tuple[3] = tuple[4] = tuple[5] = null; // Reserved - tuple[6] = remarks; // Remarks - - if (r.getBoolean(2)) - tuple[7] = Integer.toString(java.sql.DatabaseMetaData.procedureReturnsResult).getBytes(); - else - tuple[7] = Integer.toString(java.sql.DatabaseMetaData.procedureNoResult).getBytes(); - - v.addElement(tuple); - } - return new ResultSet(connection, f, v, "OK", 1); - } - - /** - * Get a description of a catalog's stored procedure parameters - * and result columns. - * - *

Only descriptions matching the schema, procedure and parameter - * name criteria are returned. They are ordered by PROCEDURE_SCHEM - * and PROCEDURE_NAME. Within this, the return value, if any, is - * first. Next are the parameter descriptions in call order. The - * column descriptions follow in column number order. - * - *

Each row in the ResultSet is a parameter description or column - * description with the following fields: - *

    - *
  1. PROCEDURE_CAT String => procedure catalog (may be null) - *
  2. PROCEDURE_SCHEM String => procedure schema (may be null) - *
  3. PROCEDURE_NAME String => procedure name - *
  4. COLUMN_NAME String => column/parameter name - *
  5. COLUMN_TYPE Short => kind of column/parameter: - *
    • procedureColumnUnknown - nobody knows - *
    • procedureColumnIn - IN parameter - *
    • procedureColumnInOut - INOUT parameter - *
    • procedureColumnOut - OUT parameter - *
    • procedureColumnReturn - procedure return value - *
    • procedureColumnResult - result column in ResultSet - *
    - *
  6. DATA_TYPE short => SQL type from java.sql.Types - *
  7. TYPE_NAME String => SQL type name - *
  8. PRECISION int => precision - *
  9. LENGTH int => length in bytes of data - *
  10. SCALE short => scale - *
  11. RADIX short => radix - *
  12. NULLABLE short => can it contain NULL? - *
    • procedureNoNulls - does not allow NULL values - *
    • procedureNullable - allows NULL values - *
    • procedureNullableUnknown - nullability unknown - *
    • REMARKS String => comment describing parameter/column - *
- * @param catalog This is ignored in postgresql, advise this is set to null - * @param schemaPattern This is ignored in postgresql, advise this is set to null - * @param procedureNamePattern a procedure name pattern - * @param columnNamePattern a column name pattern - * @return each row is a stored procedure parameter or column description - * @exception SQLException if a database-access error occurs - * @see #getSearchStringEscape - */ - // Implementation note: This is required for Borland's JBuilder to work - public java.sql.ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern) throws SQLException - { - if(procedureNamePattern==null) - procedureNamePattern="%"; - - if(columnNamePattern==null) - columnNamePattern="%"; - - // for now, this returns an empty result set. - Field f[] = new Field[13]; - ResultSet r; // ResultSet for the SQL query that we need to do - Vector v = new Vector(); // The new ResultSet tuple stuff - - f[0] = new Field(connection, new String("PROCEDURE_CAT"), iVarcharOid, 32); - f[1] = new Field(connection, new String("PROCEDURE_SCHEM"), iVarcharOid, 32); - f[2] = new Field(connection, new String("PROCEDURE_NAME"), iVarcharOid, 32); - f[3] = new Field(connection, new String("COLUMN_NAME"), iVarcharOid, 32); - f[4] = new Field(connection, new String("COLUMN_TYPE"), iInt2Oid, 2); - f[5] = new Field(connection, new String("DATA_TYPE"), iInt2Oid, 2); - f[6] = new Field(connection, new String("TYPE_NAME"), iVarcharOid, 32); - f[7] = new Field(connection, new String("PRECISION"), iInt4Oid, 4); - f[8] = new Field(connection, new String("LENGTH"), iInt4Oid, 4); - f[9] = new Field(connection, new String("SCALE"), iInt2Oid, 2); - f[10] = new Field(connection, new String("RADIX"), iInt2Oid, 2); - f[11] = new Field(connection, new String("NULLABLE"), iInt2Oid, 2); - f[12] = new Field(connection, new String("REMARKS"), iVarcharOid, 32); - - // add query loop here - - return new ResultSet(connection, f, v, "OK", 1); - } - - /** - * Get a description of tables available in a catalog. - * - *

Only table descriptions matching the catalog, schema, table - * name and type criteria are returned. They are ordered by - * TABLE_TYPE, TABLE_SCHEM and TABLE_NAME. - * - *

Each table description has the following columns: - * - *

    - *
  1. TABLE_CAT String => table catalog (may be null) - *
  2. TABLE_SCHEM String => table schema (may be null) - *
  3. TABLE_NAME String => table name - *
  4. TABLE_TYPE String => table type. Typical types are "TABLE", - * "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY", "LOCAL - * TEMPORARY", "ALIAS", "SYNONYM". - *
  5. REMARKS String => explanatory comment on the table - *
- * - *

The valid values for the types parameter are: - * "TABLE", "INDEX", "LARGE OBJECT", "SEQUENCE", "SYSTEM TABLE" and - * "SYSTEM INDEX" - * - * @param catalog a catalog name; For postgresql, this is ignored, and - * should be set to null - * @param schemaPattern a schema name pattern; For postgresql, this is ignored, and - * should be set to null - * @param tableNamePattern a table name pattern. For all tables this should be "%" - * @param types a list of table types to include; null returns - * all types - * @return each row is a table description - * @exception SQLException if a database-access error occurs. - */ - public java.sql.ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String types[]) throws SQLException - { - // Handle default value for types - if(types==null) - types = defaultTableTypes; - - if(tableNamePattern==null) - tableNamePattern="%"; - - // the field descriptors for the new ResultSet - Field f[] = new Field[5]; - ResultSet r; // ResultSet for the SQL query that we need to do - Vector v = new Vector(); // The new ResultSet tuple stuff - - f[0] = new Field(connection, new String("TABLE_CAT"), iVarcharOid, 32); - f[1] = new Field(connection, new String("TABLE_SCHEM"), iVarcharOid, 32); - f[2] = new Field(connection, new String("TABLE_NAME"), iVarcharOid, 32); - f[3] = new Field(connection, new String("TABLE_TYPE"), iVarcharOid, 32); - f[4] = new Field(connection, new String("REMARKS"), iVarcharOid, 32); - - // Now form the query - StringBuffer sql = new StringBuffer("select relname,oid from pg_class where ("); - boolean notFirst=false; - for(int i=0;i - // Now take the pattern into account - sql.append(") and relname like '"); - sql.append(tableNamePattern.toLowerCase()); - sql.append("'"); - - // Now run the query - r = connection.ExecSQL(sql.toString()); - - byte remarks[]; - - while (r.next()) - { - byte[][] tuple = new byte[5][0]; - - // Fetch the description for the table (if any) - ResultSet dr = connection.ExecSQL("select description from pg_description where objoid="+r.getInt(2)); - if(dr.getTupleCount()==1) { - dr.next(); - remarks = dr.getBytes(1); - } else - remarks = defaultRemarks; - dr.close(); - - tuple[0] = null; // Catalog name - tuple[1] = null; // Schema name - tuple[2] = r.getBytes(1); // Table name - tuple[3] = null; // Table type - tuple[4] = remarks; // Remarks - v.addElement(tuple); - } - r.close(); - return new ResultSet(connection, f, v, "OK", 1); - } - - // This array contains the valid values for the types argument - // in getTables(). - // - // Each supported type consists of it's name, and the sql where - // clause to retrieve that value. - // - // IMPORTANT: the query must be enclosed in ( ) - private static final String getTableTypes[][] = { - {"TABLE", "(relkind='r' and relname !~ '^pg_' and relname !~ '^xinv')"}, - {"INDEX", "(relkind='i' and relname !~ '^pg_' and relname !~ '^xinx')"}, - {"LARGE OBJECT", "(relkind='r' and relname ~ '^xinv')"}, - {"SEQUENCE", "(relkind='S' and relname !~ '^pg_')"}, - {"SYSTEM TABLE", "(relkind='r' and relname ~ '^pg_')"}, - {"SYSTEM INDEX", "(relkind='i' and relname ~ '^pg_')"} - }; - - // These are the default tables, used when NULL is passed to getTables - // The choice of these provide the same behaviour as psql's \d - private static final String defaultTableTypes[] = { - "TABLE","INDEX","SEQUENCE" - }; - - /** - * Get the schema names available in this database. The results - * are ordered by schema name. - * - *

The schema column is: - *

    - *
  1. TABLE_SCHEM String => schema name - *
- * - * @return ResultSet each row has a single String column that is a - * schema name - */ - public java.sql.ResultSet getSchemas() throws SQLException - { - // We don't use schemas, so we simply return a single schema name "". - // - Field f[] = new Field[1]; - Vector v = new Vector(); - byte[][] tuple = new byte[1][0]; - f[0] = new Field(connection,new String("TABLE_SCHEM"),iVarcharOid,32); - tuple[0] = "".getBytes(); - v.addElement(tuple); - return new ResultSet(connection,f,v,"OK",1); - } - - /** - * Get the catalog names available in this database. The results - * are ordered by catalog name. - * - *

The catalog column is: - *

    - *
  1. TABLE_CAT String => catalog name - *
- * - * @return ResultSet each row has a single String column that is a - * catalog name - */ - public java.sql.ResultSet getCatalogs() throws SQLException - { - // We don't use catalogs, so we simply return a single catalog name "". - Field f[] = new Field[1]; - Vector v = new Vector(); - byte[][] tuple = new byte[1][0]; - f[0] = new Field(connection,new String("TABLE_CAT"),iVarcharOid,32); - tuple[0] = "".getBytes(); - v.addElement(tuple); - return new ResultSet(connection,f,v,"OK",1); - } - - /** - * Get the table types available in this database. The results - * are ordered by table type. - * - *

The table type is: - *

    - *
  1. TABLE_TYPE String => table type. Typical types are "TABLE", - * "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY", - * "LOCAL TEMPORARY", "ALIAS", "SYNONYM". - *
- * - * @return ResultSet each row has a single String column that is a - * table type - */ - public java.sql.ResultSet getTableTypes() throws SQLException - { - Field f[] = new Field[1]; - Vector v = new Vector(); - byte[][] tuple = new byte[1][0]; - f[0] = new Field(connection,new String("TABLE_TYPE"),iVarcharOid,32); - for(int i=0;iOnly column descriptions matching the catalog, schema, table - * and column name criteria are returned. They are ordered by - * TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION. - * - *

Each column description has the following columns: - *

    - *
  1. TABLE_CAT String => table catalog (may be null) - *
  2. TABLE_SCHEM String => table schema (may be null) - *
  3. TABLE_NAME String => table name - *
  4. COLUMN_NAME String => column name - *
  5. DATA_TYPE short => SQL type from java.sql.Types - *
  6. TYPE_NAME String => Data source dependent type name - *
  7. COLUMN_SIZE int => column size. For char or date - * types this is the maximum number of characters, for numeric or - * decimal types this is precision. - *
  8. BUFFER_LENGTH is not used. - *
  9. DECIMAL_DIGITS int => the number of fractional digits - *
  10. NUM_PREC_RADIX int => Radix (typically either 10 or 2) - *
  11. NULLABLE int => is NULL allowed? - *
      - *
    • columnNoNulls - might not allow NULL values - *
    • columnNullable - definitely allows NULL values - *
    • columnNullableUnknown - nullability unknown - *
    - *
  12. REMARKS String => comment describing column (may be null) - *
  13. COLUMN_DEF String => default value (may be null) - *
  14. SQL_DATA_TYPE int => unused - *
  15. SQL_DATETIME_SUB int => unused - *
  16. CHAR_OCTET_LENGTH int => for char types the - * maximum number of bytes in the column - *
  17. ORDINAL_POSITION int => index of column in table - * (starting at 1) - *
  18. IS_NULLABLE String => "NO" means column definitely - * does not allow NULL values; "YES" means the column might - * allow NULL values. An empty string means nobody knows. - *
- * - * @param catalog a catalog name; "" retrieves those without a catalog - * @param schemaPattern a schema name pattern; "" retrieves those - * without a schema - * @param tableNamePattern a table name pattern - * @param columnNamePattern a column name pattern - * @return ResultSet each row is a column description - * @see #getSearchStringEscape - */ - public java.sql.ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException - { - // the field descriptors for the new ResultSet - Field f[] = new Field[18]; - ResultSet r; // ResultSet for the SQL query that we need to do - Vector v = new Vector(); // The new ResultSet tuple stuff - - f[0] = new Field(connection, new String("TABLE_CAT"), iVarcharOid, 32); - f[1] = new Field(connection, new String("TABLE_SCHEM"), iVarcharOid, 32); - f[2] = new Field(connection, new String("TABLE_NAME"), iVarcharOid, 32); - f[3] = new Field(connection, new String("COLUMN_NAME"), iVarcharOid, 32); - f[4] = new Field(connection, new String("DATA_TYPE"), iInt2Oid, 2); - f[5] = new Field(connection, new String("TYPE_NAME"), iVarcharOid, 32); - f[6] = new Field(connection, new String("COLUMN_SIZE"), iInt4Oid, 4); - f[7] = new Field(connection, new String("BUFFER_LENGTH"), iVarcharOid, 32); - f[8] = new Field(connection, new String("DECIMAL_DIGITS"), iInt4Oid, 4); - f[9] = new Field(connection, new String("NUM_PREC_RADIX"), iInt4Oid, 4); - f[10] = new Field(connection, new String("NULLABLE"), iInt4Oid, 4); - f[11] = new Field(connection, new String("REMARKS"), iVarcharOid, 32); - f[12] = new Field(connection, new String("COLUMN_DEF"), iVarcharOid, 32); - f[13] = new Field(connection, new String("SQL_DATA_TYPE"), iInt4Oid, 4); - f[14] = new Field(connection, new String("SQL_DATETIME_SUB"), iInt4Oid, 4); - f[15] = new Field(connection, new String("CHAR_OCTET_LENGTH"), iVarcharOid, 32); - f[16] = new Field(connection, new String("ORDINAL_POSITION"), iInt4Oid,4); - f[17] = new Field(connection, new String("IS_NULLABLE"), iVarcharOid, 32); - - // Added by Stefan Andreasen - // If the pattern are null then set them to % - if (tableNamePattern == null) tableNamePattern="%"; - if (columnNamePattern == null) columnNamePattern="%"; - - // Now form the query - // Modified by Stefan Andreasen - r = connection.ExecSQL("select a.oid,c.relname,a.attname,a.atttypid,a.attnum,a.attnotnull,a.attlen,a.atttypmod from pg_class c, pg_attribute a where a.attrelid=c.oid and c.relname like '"+tableNamePattern.toLowerCase()+"' and a.attname like '"+columnNamePattern.toLowerCase()+"' and a.attnum>0 order by c.relname,a.attnum"); - - byte remarks[]; - - while(r.next()) { - byte[][] tuple = new byte[18][0]; - - // Fetch the description for the table (if any) - ResultSet dr = connection.ExecSQL("select description from pg_description where objoid="+r.getInt(1)); - if(dr.getTupleCount()==1) { - dr.next(); - tuple[11] = dr.getBytes(1); - } else - tuple[11] = defaultRemarks; - - dr.close(); - - tuple[0] = "".getBytes(); // Catalog name - tuple[1] = "".getBytes(); // Schema name - tuple[2] = r.getBytes(2); // Table name - tuple[3] = r.getBytes(3); // Column name - - dr = connection.ExecSQL("select typname from pg_type where oid = "+r.getString(4)); - dr.next(); - String typname=dr.getString(1); - dr.close(); - tuple[4] = Integer.toString(Field.getSQLType(typname)).getBytes(); // Data type - tuple[5] = typname.getBytes(); // Type name - - // Column size - // Looking at the psql source, - // I think the length of a varchar as specified when the table was created - // should be extracted from atttypmod which contains this length + sizeof(int32) - if (typname.equals("bpchar") || typname.equals("varchar")) { - int atttypmod = r.getInt(8); - tuple[6] = Integer.toString(atttypmod != -1 ? atttypmod - VARHDRSZ : 0).getBytes(); - } else - tuple[6] = r.getBytes(7); - - tuple[7] = null; // Buffer length - - tuple[8] = "0".getBytes(); // Decimal Digits - how to get this? - tuple[9] = "10".getBytes(); // Num Prec Radix - assume decimal - - // tuple[10] is below - // tuple[11] is above - - tuple[12] = null; // column default - - tuple[13] = null; // sql data type (unused) - tuple[14] = null; // sql datetime sub (unused) - - tuple[15] = tuple[6]; // char octet length - - tuple[16] = r.getBytes(5); // ordinal position - - String nullFlag = r.getString(6); - tuple[10] = Integer.toString(nullFlag.equals("f")?java.sql.DatabaseMetaData.columnNullable:java.sql.DatabaseMetaData.columnNoNulls).getBytes(); // Nullable - tuple[17] = (nullFlag.equals("f")?"YES":"NO").getBytes(); // is nullable - - v.addElement(tuple); - } - r.close(); - return new ResultSet(connection, f, v, "OK", 1); - } - - /** - * Get a description of the access rights for a table's columns. - * - *

Only privileges matching the column name criteria are - * returned. They are ordered by COLUMN_NAME and PRIVILEGE. - * - *

Each privilige description has the following columns: - *

    - *
  1. TABLE_CAT String => table catalog (may be null) - *
  2. TABLE_SCHEM String => table schema (may be null) - *
  3. TABLE_NAME String => table name - *
  4. COLUMN_NAME String => column name - *
  5. GRANTOR => grantor of access (may be null) - *
  6. GRANTEE String => grantee of access - *
  7. PRIVILEGE String => name of access (SELECT, - * INSERT, UPDATE, REFRENCES, ...) - *
  8. IS_GRANTABLE String => "YES" if grantee is permitted - * to grant to others; "NO" if not; null if unknown - *
- * - * @param catalog a catalog name; "" retrieves those without a catalog - * @param schema a schema name; "" retrieves those without a schema - * @param table a table name - * @param columnNamePattern a column name pattern - * @return ResultSet each row is a column privilege description - * @see #getSearchStringEscape - */ - public java.sql.ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern) throws SQLException - { - Field f[] = new Field[8]; - Vector v = new Vector(); - - if(table==null) - table="%"; - - if(columnNamePattern==null) - columnNamePattern="%"; - else - columnNamePattern=columnNamePattern.toLowerCase(); - - f[0] = new Field(connection,new String("TABLE_CAT"),iVarcharOid,32); - f[1] = new Field(connection,new String("TABLE_SCHEM"),iVarcharOid,32); - f[2] = new Field(connection,new String("TABLE_NAME"),iVarcharOid,32); - f[3] = new Field(connection,new String("COLUMN_NAME"),iVarcharOid,32); - f[4] = new Field(connection,new String("GRANTOR"),iVarcharOid,32); - f[5] = new Field(connection,new String("GRANTEE"),iVarcharOid,32); - f[6] = new Field(connection,new String("PRIVILEGE"),iVarcharOid,32); - f[7] = new Field(connection,new String("IS_GRANTABLE"),iVarcharOid,32); - - // This is taken direct from the psql source - ResultSet r = connection.ExecSQL("SELECT relname, relacl FROM pg_class, pg_user WHERE ( relkind = 'r' OR relkind = 'i') and relname !~ '^pg_' and relname !~ '^xin[vx][0-9]+' and usesysid = relowner and relname like '"+table.toLowerCase()+"' ORDER BY relname"); - while(r.next()) { - byte[][] tuple = new byte[8][0]; - tuple[0] = tuple[1]= "".getBytes(); - DriverManager.println("relname=\""+r.getString(1)+"\" relacl=\""+r.getString(2)+"\""); - - // For now, don't add to the result as relacl needs to be processed. - //v.addElement(tuple); - } - - return new ResultSet(connection,f,v,"OK",1); - } - - /** - * Get a description of the access rights for each table available - * in a catalog. - * - *

Only privileges matching the schema and table name - * criteria are returned. They are ordered by TABLE_SCHEM, - * TABLE_NAME, and PRIVILEGE. - * - *

Each privilige description has the following columns: - *

    - *
  1. TABLE_CAT String => table catalog (may be null) - *
  2. TABLE_SCHEM String => table schema (may be null) - *
  3. TABLE_NAME String => table name - *
  4. COLUMN_NAME String => column name - *
  5. GRANTOR => grantor of access (may be null) - *
  6. GRANTEE String => grantee of access - *
  7. PRIVILEGE String => name of access (SELECT, - * INSERT, UPDATE, REFRENCES, ...) - *
  8. IS_GRANTABLE String => "YES" if grantee is permitted - * to grant to others; "NO" if not; null if unknown - *
- * - * @param catalog a catalog name; "" retrieves those without a catalog - * @param schemaPattern a schema name pattern; "" retrieves those - * without a schema - * @param tableNamePattern a table name pattern - * @return ResultSet each row is a table privilege description - * @see #getSearchStringEscape - */ - public java.sql.ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) throws SQLException - { - // XXX-Not Implemented - return null; - } - - /** - * Get a description of a table's optimal set of columns that - * uniquely identifies a row. They are ordered by SCOPE. - * - *

Each column description has the following columns: - *

    - *
  1. SCOPE short => actual scope of result - *
      - *
    • bestRowTemporary - very temporary, while using row - *
    • bestRowTransaction - valid for remainder of current transaction - *
    • bestRowSession - valid for remainder of current session - *
    - *
  2. COLUMN_NAME String => column name - *
  3. DATA_TYPE short => SQL data type from java.sql.Types - *
  4. TYPE_NAME String => Data source dependent type name - *
  5. COLUMN_SIZE int => precision - *
  6. BUFFER_LENGTH int => not used - *
  7. DECIMAL_DIGITS short => scale - *
  8. PSEUDO_COLUMN short => is this a pseudo column - * like an Oracle ROWID - *
      - *
    • bestRowUnknown - may or may not be pseudo column - *
    • bestRowNotPseudo - is NOT a pseudo column - *
    • bestRowPseudo - is a pseudo column - *
    - *
- * - * @param catalog a catalog name; "" retrieves those without a catalog - * @param schema a schema name; "" retrieves those without a schema - * @param table a table name - * @param scope the scope of interest; use same values as SCOPE - * @param nullable include columns that are nullable? - * @return ResultSet each row is a column description - */ - // Implementation note: This is required for Borland's JBuilder to work - public java.sql.ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) throws SQLException - { - // for now, this returns an empty result set. - Field f[] = new Field[8]; - ResultSet r; // ResultSet for the SQL query that we need to do - Vector v = new Vector(); // The new ResultSet tuple stuff - - f[0] = new Field(connection, new String("SCOPE"), iInt2Oid, 2); - f[1] = new Field(connection, new String("COLUMN_NAME"), iVarcharOid, 32); - f[2] = new Field(connection, new String("DATA_TYPE"), iInt2Oid, 2); - f[3] = new Field(connection, new String("TYPE_NAME"), iVarcharOid, 32); - f[4] = new Field(connection, new String("COLUMN_SIZE"), iInt4Oid, 4); - f[5] = new Field(connection, new String("BUFFER_LENGTH"), iInt4Oid, 4); - f[6] = new Field(connection, new String("DECIMAL_DIGITS"), iInt2Oid, 2); - f[7] = new Field(connection, new String("PSEUDO_COLUMN"), iInt2Oid, 2); - - return new ResultSet(connection, f, v, "OK", 1); - } - - /** - * Get a description of a table's columns that are automatically - * updated when any value in a row is updated. They are - * unordered. - * - *

Each column description has the following columns: - *

    - *
  1. SCOPE short => is not used - *
  2. COLUMN_NAME String => column name - *
  3. DATA_TYPE short => SQL data type from java.sql.Types - *
  4. TYPE_NAME String => Data source dependent type name - *
  5. COLUMN_SIZE int => precision - *
  6. BUFFER_LENGTH int => length of column value in bytes - *
  7. DECIMAL_DIGITS short => scale - *
  8. PSEUDO_COLUMN short => is this a pseudo column - * like an Oracle ROWID - *
      - *
    • versionColumnUnknown - may or may not be pseudo column - *
    • versionColumnNotPseudo - is NOT a pseudo column - *
    • versionColumnPseudo - is a pseudo column - *
    - *
- * - * @param catalog a catalog name; "" retrieves those without a catalog - * @param schema a schema name; "" retrieves those without a schema - * @param table a table name - * @return ResultSet each row is a column description - */ - public java.sql.ResultSet getVersionColumns(String catalog, String schema, String table) throws SQLException - { - // XXX-Not Implemented - return null; - } - - /** - * Get a description of a table's primary key columns. They - * are ordered by COLUMN_NAME. - * - *

Each column description has the following columns: - *

    - *
  1. TABLE_CAT String => table catalog (may be null) - *
  2. TABLE_SCHEM String => table schema (may be null) - *
  3. TABLE_NAME String => table name - *
  4. COLUMN_NAME String => column name - *
  5. KEY_SEQ short => sequence number within primary key - *
  6. PK_NAME String => primary key name (may be null) - *
- * - * @param catalog a catalog name; "" retrieves those without a catalog - * @param schema a schema name pattern; "" retrieves those - * without a schema - * @param table a table name - * @return ResultSet each row is a primary key column description - */ - public java.sql.ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException - { - return connection.createStatement().executeQuery("SELECT " + - "'' as TABLE_CAT," + - "'' AS TABLE_SCHEM," + - "bc.relname AS TABLE_NAME," + - "ic.relname AS COLUMN_NAME," + - "'1' as KEY_SEQ,"+ // -- fake it as a String for now - "t.typname as PK_NAME " + - " FROM pg_class bc, pg_class ic, pg_index i, pg_attribute a, pg_type t " + - " WHERE bc.relkind = 'r' " + // -- not indices - " and bc.relname ~ '"+table+"'" + - " and i.indrelid = bc.oid" + - " and i.indexrelid = ic.oid" + - " and i.indkey[0] = a.attnum" + - " and i.indproc = '0'::oid" + - " and a.attrelid = bc.oid" + - " ORDER BY TABLE_NAME, COLUMN_NAME;" - ); - } - - /** - * Get a description of the primary key columns that are - * referenced by a table's foreign key columns (the primary keys - * imported by a table). They are ordered by PKTABLE_CAT, - * PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ. - * - *

Each primary key column description has the following columns: - *

    - *
  1. PKTABLE_CAT String => primary key table catalog - * being imported (may be null) - *
  2. PKTABLE_SCHEM String => primary key table schema - * being imported (may be null) - *
  3. PKTABLE_NAME String => primary key table name - * being imported - *
  4. PKCOLUMN_NAME String => primary key column name - * being imported - *
  5. FKTABLE_CAT String => foreign key table catalog (may be null) - *
  6. FKTABLE_SCHEM String => foreign key table schema (may be null) - *
  7. FKTABLE_NAME String => foreign key table name - *
  8. FKCOLUMN_NAME String => foreign key column name - *
  9. KEY_SEQ short => sequence number within foreign key - *
  10. UPDATE_RULE short => What happens to - * foreign key when primary is updated: - *
      - *
    • importedKeyCascade - change imported key to agree - * with primary key update - *
    • importedKeyRestrict - do not allow update of primary - * key if it has been imported - *
    • importedKeySetNull - change imported key to NULL if - * its primary key has been updated - *
    - *
  11. DELETE_RULE short => What happens to - * the foreign key when primary is deleted. - *
      - *
    • importedKeyCascade - delete rows that import a deleted key - *
    • importedKeyRestrict - do not allow delete of primary - * key if it has been imported - *
    • importedKeySetNull - change imported key to NULL if - * its primary key has been deleted - *
    - *
  12. FK_NAME String => foreign key name (may be null) - *
  13. PK_NAME String => primary key name (may be null) - *
- * - * @param catalog a catalog name; "" retrieves those without a catalog - * @param schema a schema name pattern; "" retrieves those - * without a schema - * @param table a table name - * @return ResultSet each row is a primary key column description - * @see #getExportedKeys - */ - public java.sql.ResultSet getImportedKeys(String catalog, String schema, String table) throws SQLException - { - // XXX-Not Implemented - return null; - } - - /** - * Get a description of a foreign key columns that reference a - * table's primary key columns (the foreign keys exported by a - * table). They are ordered by FKTABLE_CAT, FKTABLE_SCHEM, - * FKTABLE_NAME, and KEY_SEQ. - * - *

Each foreign key column description has the following columns: - *

    - *
  1. PKTABLE_CAT String => primary key table catalog (may be null) - *
  2. PKTABLE_SCHEM String => primary key table schema (may be null) - *
  3. PKTABLE_NAME String => primary key table name - *
  4. PKCOLUMN_NAME String => primary key column name - *
  5. FKTABLE_CAT String => foreign key table catalog (may be null) - * being exported (may be null) - *
  6. FKTABLE_SCHEM String => foreign key table schema (may be null) - * being exported (may be null) - *
  7. FKTABLE_NAME String => foreign key table name - * being exported - *
  8. FKCOLUMN_NAME String => foreign key column name - * being exported - *
  9. KEY_SEQ short => sequence number within foreign key - *
  10. UPDATE_RULE short => What happens to - * foreign key when primary is updated: - *
      - *
    • importedKeyCascade - change imported key to agree - * with primary key update - *
    • importedKeyRestrict - do not allow update of primary - * key if it has been imported - *
    • importedKeySetNull - change imported key to NULL if - * its primary key has been updated - *
    - *
  11. DELETE_RULE short => What happens to - * the foreign key when primary is deleted. - *
      - *
    • importedKeyCascade - delete rows that import a deleted key - *
    • importedKeyRestrict - do not allow delete of primary - * key if it has been imported - *
    • importedKeySetNull - change imported key to NULL if - * its primary key has been deleted - *
    - *
  12. FK_NAME String => foreign key identifier (may be null) - *
  13. PK_NAME String => primary key identifier (may be null) - *
- * - * @param catalog a catalog name; "" retrieves those without a catalog - * @param schema a schema name pattern; "" retrieves those - * without a schema - * @param table a table name - * @return ResultSet each row is a foreign key column description - * @see #getImportedKeys - */ - public java.sql.ResultSet getExportedKeys(String catalog, String schema, String table) throws SQLException - { - // XXX-Not Implemented - return null; - } - - /** - * Get a description of the foreign key columns in the foreign key - * table that reference the primary key columns of the primary key - * table (describe how one table imports another's key.) This - * should normally return a single foreign key/primary key pair - * (most tables only import a foreign key from a table once.) They - * are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and - * KEY_SEQ. - * - *

Each foreign key column description has the following columns: - *

    - *
  1. PKTABLE_CAT String => primary key table catalog (may be null) - *
  2. PKTABLE_SCHEM String => primary key table schema (may be null) - *
  3. PKTABLE_NAME String => primary key table name - *
  4. PKCOLUMN_NAME String => primary key column name - *
  5. FKTABLE_CAT String => foreign key table catalog (may be null) - * being exported (may be null) - *
  6. FKTABLE_SCHEM String => foreign key table schema (may be null) - * being exported (may be null) - *
  7. FKTABLE_NAME String => foreign key table name - * being exported - *
  8. FKCOLUMN_NAME String => foreign key column name - * being exported - *
  9. KEY_SEQ short => sequence number within foreign key - *
  10. UPDATE_RULE short => What happens to - * foreign key when primary is updated: - *
      - *
    • importedKeyCascade - change imported key to agree - * with primary key update - *
    • importedKeyRestrict - do not allow update of primary - * key if it has been imported - *
    • importedKeySetNull - change imported key to NULL if - * its primary key has been updated - *
    - *
  11. DELETE_RULE short => What happens to - * the foreign key when primary is deleted. - *
      - *
    • importedKeyCascade - delete rows that import a deleted key - *
    • importedKeyRestrict - do not allow delete of primary - * key if it has been imported - *
    • importedKeySetNull - change imported key to NULL if - * its primary key has been deleted - *
    - *
  12. FK_NAME String => foreign key identifier (may be null) - *
  13. PK_NAME String => primary key identifier (may be null) - *
- * - * @param catalog a catalog name; "" retrieves those without a catalog - * @param schema a schema name pattern; "" retrieves those - * without a schema - * @param table a table name - * @return ResultSet each row is a foreign key column description - * @see #getImportedKeys - */ - public java.sql.ResultSet getCrossReference(String primaryCatalog, String primarySchema, String primaryTable, String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException - { - // XXX-Not Implemented - return null; - } - - /** - * Get a description of all the standard SQL types supported by - * this database. They are ordered by DATA_TYPE and then by how - * closely the data type maps to the corresponding JDBC SQL type. - * - *

Each type description has the following columns: - *

    - *
  1. TYPE_NAME String => Type name - *
  2. DATA_TYPE short => SQL data type from java.sql.Types - *
  3. PRECISION int => maximum precision - *
  4. LITERAL_PREFIX String => prefix used to quote a literal - * (may be null) - *
  5. LITERAL_SUFFIX String => suffix used to quote a literal - (may be null) - *
  6. CREATE_PARAMS String => parameters used in creating - * the type (may be null) - *
  7. NULLABLE short => can you use NULL for this type? - *
      - *
    • typeNoNulls - does not allow NULL values - *
    • typeNullable - allows NULL values - *
    • typeNullableUnknown - nullability unknown - *
    - *
  8. CASE_SENSITIVE boolean=> is it case sensitive? - *
  9. SEARCHABLE short => can you use "WHERE" based on this type: - *
      - *
    • typePredNone - No support - *
    • typePredChar - Only supported with WHERE .. LIKE - *
    • typePredBasic - Supported except for WHERE .. LIKE - *
    • typeSearchable - Supported for all WHERE .. - *
    - *
  10. UNSIGNED_ATTRIBUTE boolean => is it unsigned? - *
  11. FIXED_PREC_SCALE boolean => can it be a money value? - *
  12. AUTO_INCREMENT boolean => can it be used for an - * auto-increment value? - *
  13. LOCAL_TYPE_NAME String => localized version of type name - * (may be null) - *
  14. MINIMUM_SCALE short => minimum scale supported - *
  15. MAXIMUM_SCALE short => maximum scale supported - *
  16. SQL_DATA_TYPE int => unused - *
  17. SQL_DATETIME_SUB int => unused - *
  18. NUM_PREC_RADIX int => usually 2 or 10 - *
- * - * @return ResultSet each row is a SQL type description - */ - public java.sql.ResultSet getTypeInfo() throws SQLException - { - ResultSet rs = connection.ExecSQL("select typname from pg_type"); - if(rs!=null) { - Field f[] = new Field[18]; - ResultSet r; // ResultSet for the SQL query that we need to do - Vector v = new Vector(); // The new ResultSet tuple stuff - - f[0] = new Field(connection, new String("TYPE_NAME"), iVarcharOid, 32); - f[1] = new Field(connection, new String("DATA_TYPE"), iInt2Oid, 2); - f[2] = new Field(connection, new String("PRECISION"), iInt4Oid, 4); - f[3] = new Field(connection, new String("LITERAL_PREFIX"), iVarcharOid, 32); - f[4] = new Field(connection, new String("LITERAL_SUFFIX"), iVarcharOid, 32); - f[5] = new Field(connection, new String("CREATE_PARAMS"), iVarcharOid, 32); - f[6] = new Field(connection, new String("NULLABLE"), iInt2Oid, 2); - f[7] = new Field(connection, new String("CASE_SENSITIVE"), iBoolOid, 1); - f[8] = new Field(connection, new String("SEARCHABLE"), iInt2Oid, 2); - f[9] = new Field(connection, new String("UNSIGNED_ATTRIBUTE"), iBoolOid, 1); - f[10] = new Field(connection, new String("FIXED_PREC_SCALE"), iBoolOid, 1); - f[11] = new Field(connection, new String("AUTO_INCREMENT"), iBoolOid, 1); - f[12] = new Field(connection, new String("LOCAL_TYPE_NAME"), iVarcharOid, 32); - f[13] = new Field(connection, new String("MINIMUM_SCALE"), iInt2Oid, 2); - f[14] = new Field(connection, new String("MAXIMUM_SCALE"), iInt2Oid, 2); - f[15] = new Field(connection, new String("SQL_DATA_TYPE"), iInt4Oid, 4); - f[16] = new Field(connection, new String("SQL_DATETIME_SUB"), iInt4Oid, 4); - f[17] = new Field(connection, new String("NUM_PREC_RADIX"), iInt4Oid, 4); - - // cache some results, this will keep memory useage down, and speed - // things up a little. - byte b9[] = "9".getBytes(); - byte b10[] = "10".getBytes(); - byte bf[] = "f".getBytes(); - byte bnn[] = Integer.toString(typeNoNulls).getBytes(); - byte bts[] = Integer.toString(typeSearchable).getBytes(); - - while(rs.next()) { - byte[][] tuple = new byte[18][]; - String typname=rs.getString(1); - tuple[0] = typname.getBytes(); - tuple[1] = Integer.toString(Field.getSQLType(typname)).getBytes(); - tuple[2] = b9; // for now - tuple[6] = bnn; // for now - tuple[7] = bf; // false for now - not case sensitive - tuple[8] = bts; - tuple[9] = bf; // false for now - it's signed - tuple[10] = bf; // false for now - must handle money - tuple[11] = bf; // false for now - handle autoincrement - // 12 - LOCAL_TYPE_NAME is null - // 13 & 14 ? - // 15 & 16 are unused so we return null - tuple[17] = b10; // everything is base 10 - v.addElement(tuple); - } - rs.close(); - return new ResultSet(connection, f, v, "OK", 1); - } - - return null; - } - - /** - * Get a description of a table's indices and statistics. They are - * ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION. - * - *

Each index column description has the following columns: - *

    - *
  1. TABLE_CAT String => table catalog (may be null) - *
  2. TABLE_SCHEM String => table schema (may be null) - *
  3. TABLE_NAME String => table name - *
  4. NON_UNIQUE boolean => Can index values be non-unique? - * false when TYPE is tableIndexStatistic - *
  5. INDEX_QUALIFIER String => index catalog (may be null); - * null when TYPE is tableIndexStatistic - *
  6. INDEX_NAME String => index name; null when TYPE is - * tableIndexStatistic - *
  7. TYPE short => index type: - *
      - *
    • tableIndexStatistic - this identifies table statistics that are - * returned in conjuction with a table's index descriptions - *
    • tableIndexClustered - this is a clustered index - *
    • tableIndexHashed - this is a hashed index - *
    • tableIndexOther - this is some other style of index - *
    - *
  8. ORDINAL_POSITION short => column sequence number - * within index; zero when TYPE is tableIndexStatistic - *
  9. COLUMN_NAME String => column name; null when TYPE is - * tableIndexStatistic - *
  10. ASC_OR_DESC String => column sort sequence, "A" => ascending - * "D" => descending, may be null if sort sequence is not supported; - * null when TYPE is tableIndexStatistic - *
  11. CARDINALITY int => When TYPE is tableIndexStatisic then - * this is the number of rows in the table; otherwise it is the - * number of unique values in the index. - *
  12. PAGES int => When TYPE is tableIndexStatisic then - * this is the number of pages used for the table, otherwise it - * is the number of pages used for the current index. - *
  13. FILTER_CONDITION String => Filter condition, if any. - * (may be null) - *
- * - * @param catalog a catalog name; "" retrieves those without a catalog - * @param schema a schema name pattern; "" retrieves those without a schema - * @param table a table name - * @param unique when true, return only indices for unique values; - * when false, return indices regardless of whether unique or not - * @param approximate when true, result is allowed to reflect approximate - * or out of data values; when false, results are requested to be - * accurate - * @return ResultSet each row is an index column description - */ - // Implementation note: This is required for Borland's JBuilder to work - public java.sql.ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate) throws SQLException - { - // for now, this returns an empty result set. - Field f[] = new Field[13]; - ResultSet r; // ResultSet for the SQL query that we need to do - Vector v = new Vector(); // The new ResultSet tuple stuff - - f[0] = new Field(connection, new String("TABLE_CAT"), iVarcharOid, 32); - f[1] = new Field(connection, new String("TABLE_SCHEM"), iVarcharOid, 32); - f[2] = new Field(connection, new String("TABLE_NAME"), iVarcharOid, 32); - f[3] = new Field(connection, new String("NON_UNIQUE"), iBoolOid, 1); - f[4] = new Field(connection, new String("INDEX_QUALIFIER"), iVarcharOid, 32); - f[5] = new Field(connection, new String("INDEX_NAME"), iVarcharOid, 32); - f[6] = new Field(connection, new String("TYPE"), iInt2Oid, 2); - f[7] = new Field(connection, new String("ORDINAL_POSITION"), iInt2Oid, 2); - f[8] = new Field(connection, new String("COLUMN_NAME"), iVarcharOid, 32); - f[9] = new Field(connection, new String("ASC_OR_DESC"), iVarcharOid, 32); - f[10] = new Field(connection, new String("CARDINALITY"), iInt4Oid, 4); - f[11] = new Field(connection, new String("PAGES"), iInt4Oid, 4); - f[12] = new Field(connection, new String("FILTER_CONDITION"), iVarcharOid, 32); - - return new ResultSet(connection, f, v, "OK", 1); - } -} - diff --git a/src/interfaces/jdbc/postgresql/Driver.java b/src/interfaces/jdbc/postgresql/Driver.java index b3cc57f4f2..d563a2697c 100644 --- a/src/interfaces/jdbc/postgresql/Driver.java +++ b/src/interfaces/jdbc/postgresql/Driver.java @@ -3,6 +3,13 @@ package postgresql; import java.sql.*; import java.util.*; +// You will find some mentions to a PSQLException class. This was intended +// to allow internationalisation of error messages. However, this is not +// working quite to plan, so the class exists in the source, but it's not +// quite implemented yet. Peter May 17 1999. +// +//import postgresql.util.PSQLException; + /** * The Java SQL framework allows for multiple database drivers. Each * driver should supply a class that implements the Driver interface @@ -101,8 +108,10 @@ public class Driver implements java.sql.Driver con.openConnection (host(), port(), props, database(), url, this); return (java.sql.Connection)con; } catch(ClassNotFoundException ex) { + //throw new PSQLException("postgresql.jvm.version",ex); throw new SQLException("The postgresql.jar file does not contain the correct JDBC classes for this JVM. Try rebuilding.\nException thrown was "+ex.toString()); } catch(Exception ex2) { + //throw new PSQLException("postgresql.unusual",ex2); throw new SQLException("Something unusual has occured to cause the driver to fail. Please report this exception: "+ex2.toString()); } // The old call - remove before posting @@ -346,6 +355,7 @@ public class Driver implements java.sql.Driver */ public static SQLException notImplemented() { + //return new PSQLException("postgresql.unimplemented"); return new SQLException("This method is not yet implemented."); } } diff --git a/src/interfaces/jdbc/postgresql/PG_Stream.java b/src/interfaces/jdbc/postgresql/PG_Stream.java index 9002ccda7b..37870cf52a 100644 --- a/src/interfaces/jdbc/postgresql/PG_Stream.java +++ b/src/interfaces/jdbc/postgresql/PG_Stream.java @@ -378,6 +378,8 @@ public class PG_Stream */ public void close() throws IOException { + pg_output.write("X\0".getBytes()); + pg_output.flush(); pg_output.close(); pg_input.close(); connection.close(); diff --git a/src/interfaces/jdbc/postgresql/PreparedStatement.java b/src/interfaces/jdbc/postgresql/PreparedStatement.java deleted file mode 100644 index 85ee2f67d9..0000000000 --- a/src/interfaces/jdbc/postgresql/PreparedStatement.java +++ /dev/null @@ -1,595 +0,0 @@ -package postgresql; - -import java.io.*; -import java.math.*; -import java.sql.*; -import java.text.*; -import java.util.*; -import postgresql.largeobject.*; -import postgresql.util.*; - -/** - * A SQL Statement is pre-compiled and stored in a PreparedStatement object. - * This object can then be used to efficiently execute this statement multiple - * times. - * - *

Note: The setXXX methods for setting IN parameter values must - * specify types that are compatible with the defined SQL type of the input - * parameter. For instance, if the IN parameter has SQL type Integer, then - * setInt should be used. - * - *

If arbitrary parameter type conversions are required, then the setObject - * method should be used with a target SQL type. - * - * @see ResultSet - * @see java.sql.PreparedStatement - */ -public class PreparedStatement extends Statement implements java.sql.PreparedStatement -{ - String sql; - String[] templateStrings; - String[] inStrings; - Connection connection; - - /** - * Constructor for the PreparedStatement class. - * Split the SQL statement into segments - separated by the arguments. - * When we rebuild the thing with the arguments, we can substitute the - * args and join the whole thing together. - * - * @param conn the instanatiating connection - * @param sql the SQL statement with ? for IN markers - * @exception SQLException if something bad occurs - */ - public PreparedStatement(Connection connection, String sql) throws SQLException - { - super(connection); - - Vector v = new Vector(); - boolean inQuotes = false; - int lastParmEnd = 0, i; - - this.sql = sql; - this.connection = connection; - for (i = 0; i < sql.length(); ++i) - { - int c = sql.charAt(i); - - if (c == '\'') - inQuotes = !inQuotes; - if (c == '?' && !inQuotes) - { - v.addElement(sql.substring (lastParmEnd, i)); - lastParmEnd = i + 1; - } - } - v.addElement(sql.substring (lastParmEnd, sql.length())); - - templateStrings = new String[v.size()]; - inStrings = new String[v.size() - 1]; - clearParameters(); - - for (i = 0 ; i < templateStrings.length; ++i) - templateStrings[i] = (String)v.elementAt(i); - } - - /** - * A Prepared SQL query is executed and its ResultSet is returned - * - * @return a ResultSet that contains the data produced by the - * query - never null - * @exception SQLException if a database access error occurs - */ - public java.sql.ResultSet executeQuery() throws SQLException - { - StringBuffer s = new StringBuffer(); - int i; - - for (i = 0 ; i < inStrings.length ; ++i) - { - if (inStrings[i] == null) - throw new SQLException("No value specified for parameter " + (i + 1)); - s.append (templateStrings[i]); - s.append (inStrings[i]); - } - s.append(templateStrings[inStrings.length]); - return super.executeQuery(s.toString()); // in Statement class - } - - /** - * Execute a SQL INSERT, UPDATE or DELETE statement. In addition, - * SQL statements that return nothing such as SQL DDL statements can - * be executed. - * - * @return either the row count for INSERT, UPDATE or DELETE; or - * 0 for SQL statements that return nothing. - * @exception SQLException if a database access error occurs - */ - public int executeUpdate() throws SQLException - { - StringBuffer s = new StringBuffer(); - int i; - - for (i = 0 ; i < inStrings.length ; ++i) - { - if (inStrings[i] == null) - throw new SQLException("No value specified for parameter " + (i + 1)); - s.append (templateStrings[i]); - s.append (inStrings[i]); - } - s.append(templateStrings[inStrings.length]); - return super.executeUpdate(s.toString()); // in Statement class - } - - /** - * Set a parameter to SQL NULL - * - *

Note: You must specify the parameters SQL type (although - * PostgreSQL ignores it) - * - * @param parameterIndex the first parameter is 1, etc... - * @param sqlType the SQL type code defined in java.sql.Types - * @exception SQLException if a database access error occurs - */ - public void setNull(int parameterIndex, int sqlType) throws SQLException - { - set(parameterIndex, "null"); - } - - /** - * Set a parameter to a Java boolean value. The driver converts this - * to a SQL BIT value when it sends it to the database. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setBoolean(int parameterIndex, boolean x) throws SQLException - { - set(parameterIndex, x ? "'t'" : "'f'"); - } - - /** - * Set a parameter to a Java byte value. The driver converts this to - * a SQL TINYINT value when it sends it to the database. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setByte(int parameterIndex, byte x) throws SQLException - { - set(parameterIndex, (new Integer(x)).toString()); - } - - /** - * Set a parameter to a Java short value. The driver converts this - * to a SQL SMALLINT value when it sends it to the database. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setShort(int parameterIndex, short x) throws SQLException - { - set(parameterIndex, (new Integer(x)).toString()); - } - - /** - * Set a parameter to a Java int value. The driver converts this to - * a SQL INTEGER value when it sends it to the database. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setInt(int parameterIndex, int x) throws SQLException - { - set(parameterIndex, (new Integer(x)).toString()); - } - - /** - * Set a parameter to a Java long value. The driver converts this to - * a SQL BIGINT value when it sends it to the database. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setLong(int parameterIndex, long x) throws SQLException - { - set(parameterIndex, (new Long(x)).toString()); - } - - /** - * Set a parameter to a Java float value. The driver converts this - * to a SQL FLOAT value when it sends it to the database. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setFloat(int parameterIndex, float x) throws SQLException - { - set(parameterIndex, (new Float(x)).toString()); - } - - /** - * Set a parameter to a Java double value. The driver converts this - * to a SQL DOUBLE value when it sends it to the database - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setDouble(int parameterIndex, double x) throws SQLException - { - set(parameterIndex, (new Double(x)).toString()); - } - - /** - * Set a parameter to a java.lang.BigDecimal value. The driver - * converts this to a SQL NUMERIC value when it sends it to the - * database. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException - { - set(parameterIndex, x.toString()); - } - - /** - * Set a parameter to a Java String value. The driver converts this - * to a SQL VARCHAR or LONGVARCHAR value (depending on the arguments - * size relative to the driver's limits on VARCHARs) when it sends it - * to the database. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setString(int parameterIndex, String x) throws SQLException - { - // if the passed string is null, then set this column to null - if(x==null) - set(parameterIndex,"null"); - else { - StringBuffer b = new StringBuffer(); - int i; - - b.append('\''); - for (i = 0 ; i < x.length() ; ++i) - { - char c = x.charAt(i); - if (c == '\\' || c == '\'') - b.append((char)'\\'); - b.append(c); - } - b.append('\''); - set(parameterIndex, b.toString()); - } - } - - /** - * Set a parameter to a Java array of bytes. The driver converts this - * to a SQL VARBINARY or LONGVARBINARY (depending on the argument's - * size relative to the driver's limits on VARBINARYs) when it sends - * it to the database. - * - *

Implementation note: - *
With postgresql, this creates a large object, and stores the - * objects oid in this column. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setBytes(int parameterIndex, byte x[]) throws SQLException - { - LargeObjectManager lom = connection.getLargeObjectAPI(); - int oid = lom.create(); - LargeObject lob = lom.open(oid); - lob.write(x); - lob.close(); - setInt(parameterIndex,oid); - } - - /** - * Set a parameter to a java.sql.Date value. The driver converts this - * to a SQL DATE value when it sends it to the database. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setDate(int parameterIndex, java.sql.Date x) throws SQLException - { - SimpleDateFormat df = new SimpleDateFormat("''"+connection.getDateStyle()+"''"); - - set(parameterIndex, df.format(x)); - - // The above is how the date should be handled. - // - // However, in JDK's prior to 1.1.6 (confirmed with the - // Linux jdk1.1.3 and the Win95 JRE1.1.5), SimpleDateFormat seems - // to format a date to the previous day. So the fix is to add a day - // before formatting. - // - // PS: 86400000 is one day - // - //set(parameterIndex, df.format(new java.util.Date(x.getTime()+86400000))); - } - - /** - * Set a parameter to a java.sql.Time value. The driver converts - * this to a SQL TIME value when it sends it to the database. - * - * @param parameterIndex the first parameter is 1...)); - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setTime(int parameterIndex, Time x) throws SQLException - { - set(parameterIndex, "'" + x.toString() + "'"); - } - - /** - * Set a parameter to a java.sql.Timestamp value. The driver converts - * this to a SQL TIMESTAMP value when it sends it to the database. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException - { - set(parameterIndex, "'" + x.toString() + "'"); - } - - /** - * When a very large ASCII value is input to a LONGVARCHAR parameter, - * it may be more practical to send it via a java.io.InputStream. - * JDBC will read the data from the stream as needed, until it reaches - * end-of-file. The JDBC driver will do any necessary conversion from - * ASCII to the database char format. - * - *

Note: This stream object can either be a standard Java - * stream object or your own subclass that implements the standard - * interface. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @param length the number of bytes in the stream - * @exception SQLException if a database access error occurs - */ - public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException - { - setBinaryStream(parameterIndex, x, length); - } - - /** - * When a very large Unicode value is input to a LONGVARCHAR parameter, - * it may be more practical to send it via a java.io.InputStream. - * JDBC will read the data from the stream as needed, until it reaches - * end-of-file. The JDBC driver will do any necessary conversion from - * UNICODE to the database char format. - * - *

Note: This stream object can either be a standard Java - * stream object or your own subclass that implements the standard - * interface. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException - { - setBinaryStream(parameterIndex, x, length); - } - - /** - * When a very large binary value is input to a LONGVARBINARY parameter, - * it may be more practical to send it via a java.io.InputStream. - * JDBC will read the data from the stream as needed, until it reaches - * end-of-file. - * - *

Note: This stream object can either be a standard Java - * stream object or your own subclass that implements the standard - * interface. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException - { - throw new SQLException("InputStream as parameter not supported"); - } - - /** - * In general, parameter values remain in force for repeated used of a - * Statement. Setting a parameter value automatically clears its - * previous value. However, in coms cases, it is useful to immediately - * release the resources used by the current parameter values; this - * can be done by calling clearParameters - * - * @exception SQLException if a database access error occurs - */ - public void clearParameters() throws SQLException - { - int i; - - for (i = 0 ; i < inStrings.length ; i++) - inStrings[i] = null; - } - - /** - * Set the value of a parameter using an object; use the java.lang - * equivalent objects for integral values. - * - *

The given Java object will be converted to the targetSqlType before - * being sent to the database. - * - *

note that this method may be used to pass database-specific - * abstract data types. This is done by using a Driver-specific - * Java type and using a targetSqlType of java.sql.Types.OTHER - * - * @param parameterIndex the first parameter is 1... - * @param x the object containing the input parameter value - * @param targetSqlType The SQL type to be send to the database - * @param scale For java.sql.Types.DECIMAL or java.sql.Types.NUMERIC - * types this is the number of digits after the decimal. For - * all other types this value will be ignored. - * @exception SQLException if a database access error occurs - */ - public void setObject(int parameterIndex, Object x, int targetSqlType, int scale) throws SQLException - { - switch (targetSqlType) - { - case Types.TINYINT: - case Types.SMALLINT: - case Types.INTEGER: - case Types.BIGINT: - case Types.REAL: - case Types.FLOAT: - case Types.DOUBLE: - case Types.DECIMAL: - case Types.NUMERIC: - if (x instanceof Boolean) - set(parameterIndex, ((Boolean)x).booleanValue() ? "1" : "0"); - else - set(parameterIndex, x.toString()); - break; - case Types.CHAR: - case Types.VARCHAR: - case Types.LONGVARCHAR: - setString(parameterIndex, x.toString()); - break; - case Types.DATE: - setDate(parameterIndex, (java.sql.Date)x); - break; - case Types.TIME: - setTime(parameterIndex, (Time)x); - break; - case Types.TIMESTAMP: - setTimestamp(parameterIndex, (Timestamp)x); - break; - case Types.OTHER: - setString(parameterIndex, ((PGobject)x).getValue()); - break; - default: - throw new SQLException("Unknown Types value"); - } - } - - public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException - { - setObject(parameterIndex, x, targetSqlType, 0); - } - - /** - * This stores an Object into a parameter. - *

New for 6.4, if the object is not recognised, but it is - * Serializable, then the object is serialised using the - * postgresql.util.Serialize class. - */ - public void setObject(int parameterIndex, Object x) throws SQLException - { - if (x instanceof String) - setString(parameterIndex, (String)x); - else if (x instanceof BigDecimal) - setBigDecimal(parameterIndex, (BigDecimal)x); - else if (x instanceof Short) - setShort(parameterIndex, ((Short)x).shortValue()); - else if (x instanceof Integer) - setInt(parameterIndex, ((Integer)x).intValue()); - else if (x instanceof Long) - setLong(parameterIndex, ((Long)x).longValue()); - else if (x instanceof Float) - setFloat(parameterIndex, ((Float)x).floatValue()); - else if (x instanceof Double) - setDouble(parameterIndex, ((Double)x).doubleValue()); - else if (x instanceof byte[]) - setBytes(parameterIndex, (byte[])x); - else if (x instanceof java.sql.Date) - setDate(parameterIndex, (java.sql.Date)x); - else if (x instanceof Time) - setTime(parameterIndex, (Time)x); - else if (x instanceof Timestamp) - setTimestamp(parameterIndex, (Timestamp)x); - else if (x instanceof Boolean) - setBoolean(parameterIndex, ((Boolean)x).booleanValue()); - else if (x instanceof PGobject) - setString(parameterIndex, ((PGobject)x).getValue()); - else - setLong(parameterIndex, connection.putObject(x)); - } - - /** - * Some prepared statements return multiple results; the execute method - * handles these complex statements as well as the simpler form of - * statements handled by executeQuery and executeUpdate - * - * @return true if the next result is a ResultSet; false if it is an - * update count or there are no more results - * @exception SQLException if a database access error occurs - */ - public boolean execute() throws SQLException - { - StringBuffer s = new StringBuffer(); - int i; - - for (i = 0 ; i < inStrings.length ; ++i) - { - if (inStrings[i] == null) - throw new SQLException("No value specified for parameter " + (i + 1)); - s.append (templateStrings[i]); - s.append (inStrings[i]); - } - s.append(templateStrings[inStrings.length]); - return super.execute(s.toString()); // in Statement class - } - - /** - * Returns the SQL statement with the current template values - * substituted. - */ - public String toString() { - StringBuffer s = new StringBuffer(); - int i; - - for (i = 0 ; i < inStrings.length ; ++i) - { - if (inStrings[i] == null) - s.append( '?' ); - else - s.append (templateStrings[i]); - s.append (inStrings[i]); - } - s.append(templateStrings[inStrings.length]); - return s.toString(); - } - - // ************************************************************** - // END OF PUBLIC INTERFACE - // ************************************************************** - - /** - * There are a lot of setXXX classes which all basically do - * the same thing. We need a method which actually does the - * set for us. - * - * @param paramIndex the index into the inString - * @param s a string to be stored - * @exception SQLException if something goes wrong - */ - private void set(int paramIndex, String s) throws SQLException - { - if (paramIndex < 1 || paramIndex > inStrings.length) - throw new SQLException("Parameter index out of range"); - inStrings[paramIndex - 1] = s; - } -} diff --git a/src/interfaces/jdbc/postgresql/ResultSetMetaData.java b/src/interfaces/jdbc/postgresql/ResultSetMetaData.java deleted file mode 100644 index 6532534b10..0000000000 --- a/src/interfaces/jdbc/postgresql/ResultSetMetaData.java +++ /dev/null @@ -1,421 +0,0 @@ -package postgresql; - -import java.lang.*; -import java.sql.*; -import java.util.*; -import postgresql.*; - -/** - * A ResultSetMetaData object can be used to find out about the types and - * properties of the columns in a ResultSet - * - * @see java.sql.ResultSetMetaData - */ -public class ResultSetMetaData implements java.sql.ResultSetMetaData -{ - Vector rows; - Field[] fields; - - /** - * Initialise for a result with a tuple set and - * a field descriptor set - * - * @param rows the Vector of rows returned by the ResultSet - * @param fields the array of field descriptors - */ - public ResultSetMetaData(Vector rows, Field[] fields) - { - this.rows = rows; - this.fields = fields; - } - - /** - * Whats the number of columns in the ResultSet? - * - * @return the number - * @exception SQLException if a database access error occurs - */ - public int getColumnCount() throws SQLException - { - return fields.length; - } - - /** - * Is the column automatically numbered (and thus read-only) - * I believe that PostgreSQL does not support this feature. - * - * @param column the first column is 1, the second is 2... - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean isAutoIncrement(int column) throws SQLException - { - return false; - } - - /** - * Does a column's case matter? ASSUMPTION: Any field that is - * not obviously case insensitive is assumed to be case sensitive - * - * @param column the first column is 1, the second is 2... - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean isCaseSensitive(int column) throws SQLException - { - int sql_type = getField(column).getSQLType(); - - switch (sql_type) - { - case Types.SMALLINT: - case Types.INTEGER: - case Types.FLOAT: - case Types.REAL: - case Types.DOUBLE: - case Types.DATE: - case Types.TIME: - case Types.TIMESTAMP: - return false; - default: - return true; - } - } - - /** - * Can the column be used in a WHERE clause? Basically for - * this, I split the functions into two types: recognised - * types (which are always useable), and OTHER types (which - * may or may not be useable). The OTHER types, for now, I - * will assume they are useable. We should really query the - * catalog to see if they are useable. - * - * @param column the first column is 1, the second is 2... - * @return true if they can be used in a WHERE clause - * @exception SQLException if a database access error occurs - */ - public boolean isSearchable(int column) throws SQLException - { - int sql_type = getField(column).getSQLType(); - - // This switch is pointless, I know - but it is a set-up - // for further expansion. - switch (sql_type) - { - case Types.OTHER: - return true; - default: - return true; - } - } - - /** - * Is the column a cash value? 6.1 introduced the cash/money - * type, which haven't been incorporated as of 970414, so I - * just check the type name for both 'cash' and 'money' - * - * @param column the first column is 1, the second is 2... - * @return true if its a cash column - * @exception SQLException if a database access error occurs - */ - public boolean isCurrency(int column) throws SQLException - { - String type_name = getField(column).getTypeName(); - - return type_name.equals("cash") || type_name.equals("money"); - } - - /** - * Can you put a NULL in this column? I think this is always - * true in 6.1's case. It would only be false if the field had - * been defined NOT NULL (system catalogs could be queried?) - * - * @param column the first column is 1, the second is 2... - * @return one of the columnNullable values - * @exception SQLException if a database access error occurs - */ - public int isNullable(int column) throws SQLException - { - return columnNullable; // We can always put NULL in - } - - /** - * Is the column a signed number? In PostgreSQL, all numbers - * are signed, so this is trivial. However, strings are not - * signed (duh!) - * - * @param column the first column is 1, the second is 2... - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean isSigned(int column) throws SQLException - { - int sql_type = getField(column).getSQLType(); - - switch (sql_type) - { - case Types.SMALLINT: - case Types.INTEGER: - case Types.FLOAT: - case Types.REAL: - case Types.DOUBLE: - return true; - case Types.DATE: - case Types.TIME: - case Types.TIMESTAMP: - return false; // I don't know about these? - default: - return false; - } - } - - /** - * What is the column's normal maximum width in characters? - * - * @param column the first column is 1, the second is 2, etc. - * @return the maximum width - * @exception SQLException if a database access error occurs - */ - public int getColumnDisplaySize(int column) throws SQLException - { - int max = getColumnLabel(column).length(); - int i; - - for (i = 0 ; i < rows.size(); ++i) - { - byte[][] x = (byte[][])(rows.elementAt(i)); - if(x[column-1]!=null) { - int xl = x[column - 1].length; - if (xl > max) - max = xl; - } - } - return max; - } - - /** - * What is the suggested column title for use in printouts and - * displays? We suggest the ColumnName! - * - * @param column the first column is 1, the second is 2, etc. - * @return the column label - * @exception SQLException if a database access error occurs - */ - public String getColumnLabel(int column) throws SQLException - { - return getColumnName(column); - } - - /** - * What's a column's name? - * - * @param column the first column is 1, the second is 2, etc. - * @return the column name - * @exception SQLException if a database access error occurs - */ - public String getColumnName(int column) throws SQLException - { - Field f = getField(column); - if(f!=null) - return f.name; - return "field"+column; - } - - /** - * What is a column's table's schema? This relies on us knowing - * the table name....which I don't know how to do as yet. The - * JDBC specification allows us to return "" if this is not - * applicable. - * - * @param column the first column is 1, the second is 2... - * @return the Schema - * @exception SQLException if a database access error occurs - */ - public String getSchemaName(int column) throws SQLException - { - return ""; - } - - /** - * What is a column's number of decimal digits. - * - * @param column the first column is 1, the second is 2... - * @return the precision - * @exception SQLException if a database access error occurs - */ - public int getPrecision(int column) throws SQLException - { - int sql_type = getField(column).getSQLType(); - - switch (sql_type) - { - case Types.SMALLINT: - return 5; - case Types.INTEGER: - return 10; - case Types.REAL: - return 8; - case Types.FLOAT: - return 16; - case Types.DOUBLE: - return 16; - case Types.VARCHAR: - return 0; - default: - return 0; - } - } - - /** - * What is a column's number of digits to the right of the - * decimal point? - * - * @param column the first column is 1, the second is 2... - * @return the scale - * @exception SQLException if a database access error occurs - */ - public int getScale(int column) throws SQLException - { - int sql_type = getField(column).getSQLType(); - - switch (sql_type) - { - case Types.SMALLINT: - return 0; - case Types.INTEGER: - return 0; - case Types.REAL: - return 8; - case Types.FLOAT: - return 16; - case Types.DOUBLE: - return 16; - case Types.VARCHAR: - return 0; - default: - return 0; - } - } - - /** - * Whats a column's table's name? How do I find this out? Both - * getSchemaName() and getCatalogName() rely on knowing the table - * Name, so we need this before we can work on them. - * - * @param column the first column is 1, the second is 2... - * @return column name, or "" if not applicable - * @exception SQLException if a database access error occurs - */ - public String getTableName(int column) throws SQLException - { - return ""; - } - - /** - * What's a column's table's catalog name? As with getSchemaName(), - * we can say that if getTableName() returns n/a, then we can too - - * otherwise, we need to work on it. - * - * @param column the first column is 1, the second is 2... - * @return catalog name, or "" if not applicable - * @exception SQLException if a database access error occurs - */ - public String getCatalogName(int column) throws SQLException - { - return ""; - } - - /** - * What is a column's SQL Type? (java.sql.Type int) - * - * @param column the first column is 1, the second is 2, etc. - * @return the java.sql.Type value - * @exception SQLException if a database access error occurs - * @see postgresql.Field#getSQLType - * @see java.sql.Types - */ - public int getColumnType(int column) throws SQLException - { - return getField(column).getSQLType(); - } - - /** - * Whats is the column's data source specific type name? - * - * @param column the first column is 1, the second is 2, etc. - * @return the type name - * @exception SQLException if a database access error occurs - */ - public String getColumnTypeName(int column) throws SQLException - { - return getField(column).getTypeName(); - } - - /** - * Is the column definitely not writable? In reality, we would - * have to check the GRANT/REVOKE stuff for this to be effective, - * and I haven't really looked into that yet, so this will get - * re-visited. - * - * @param column the first column is 1, the second is 2, etc. - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean isReadOnly(int column) throws SQLException - { - return false; - } - - /** - * Is it possible for a write on the column to succeed? Again, we - * would in reality have to check the GRANT/REVOKE stuff, which - * I haven't worked with as yet. However, if it isn't ReadOnly, then - * it is obviously writable. - * - * @param column the first column is 1, the second is 2, etc. - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean isWritable(int column) throws SQLException - { - if (isReadOnly(column)) - return false; - else - return true; - } - - /** - * Will a write on this column definately succeed? Hmmm...this - * is a bad one, since the two preceding functions have not been - * really defined. I cannot tell is the short answer. I thus - * return isWritable() just to give us an idea. - * - * @param column the first column is 1, the second is 2, etc.. - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean isDefinitelyWritable(int column) throws SQLException - { - return isWritable(column); - } - - // ******************************************************** - // END OF PUBLIC INTERFACE - // ******************************************************** - - /** - * For several routines in this package, we need to convert - * a columnIndex into a Field[] descriptor. Rather than do - * the same code several times, here it is. - * - * @param columnIndex the first column is 1, the second is 2... - * @return the Field description - * @exception SQLException if a database access error occurs - */ - private Field getField(int columnIndex) throws SQLException - { - if (columnIndex < 1 || columnIndex > fields.length) - throw new SQLException("Column index out of range"); - return fields[columnIndex - 1]; - } -} - diff --git a/src/interfaces/jdbc/postgresql/Statement.java b/src/interfaces/jdbc/postgresql/Statement.java deleted file mode 100644 index 3b6c20c9a4..0000000000 --- a/src/interfaces/jdbc/postgresql/Statement.java +++ /dev/null @@ -1,315 +0,0 @@ -package postgresql; - -import java.sql.*; - -/** - * A Statement object is used for executing a static SQL statement and - * obtaining the results produced by it. - * - *

Only one ResultSet per Statement can be open at any point in time. - * Therefore, if the reading of one ResultSet is interleaved with the - * reading of another, each must have been generated by different - * Statements. All statement execute methods implicitly close a - * statement's current ResultSet if an open one exists. - * - * @see java.sql.Statement - * @see ResultSet - */ -public class Statement implements java.sql.Statement -{ - Connection connection; // The connection who created us - ResultSet result = null; // The current results - SQLWarning warnings = null; // The warnings chain. - int timeout = 0; // The timeout for a query (not used) - boolean escapeProcessing = true;// escape processing flag - - /** - * Constructor for a Statement. It simply sets the connection - * that created us. - * - * @param c the Connection instantation that creates us - */ - public Statement (Connection c) - { - connection = c; - } - - /** - * Execute a SQL statement that returns a single ResultSet - * - * @param sql typically a static SQL SELECT statement - * @return a ResulSet that contains the data produced by the query - * @exception SQLException if a database access error occurs - */ - public java.sql.ResultSet executeQuery(String sql) throws SQLException - { - this.execute(sql); - while (result != null && !result.reallyResultSet()) - result = result.getNext(); - if (result == null) - throw new SQLException("no results returned"); - return result; - } - - /** - * Execute a SQL INSERT, UPDATE or DELETE statement. In addition - * SQL statements that return nothing such as SQL DDL statements - * can be executed - * - * @param sql a SQL statement - * @return either a row count, or 0 for SQL commands - * @exception SQLException if a database access error occurs - */ - public int executeUpdate(String sql) throws SQLException - { - this.execute(sql); - if (result.reallyResultSet()) - throw new SQLException("results returned"); - return this.getUpdateCount(); - } - - /** - * In many cases, it is desirable to immediately release a - * Statement's database and JDBC resources instead of waiting - * for this to happen when it is automatically closed. The - * close method provides this immediate release. - * - *

Note: A Statement is automatically closed when it is - * garbage collected. When a Statement is closed, its current - * ResultSet, if one exists, is also closed. - * - * @exception SQLException if a database access error occurs (why?) - */ - public void close() throws SQLException - { - result = null; - } - - /** - * The maxFieldSize limit (in bytes) is the maximum amount of - * data returned for any column value; it only applies to - * BINARY, VARBINARY, LONGVARBINARY, CHAR, VARCHAR and LONGVARCHAR - * columns. If the limit is exceeded, the excess data is silently - * discarded. - * - * @return the current max column size limit; zero means unlimited - * @exception SQLException if a database access error occurs - */ - public int getMaxFieldSize() throws SQLException - { - return 8192; // We cannot change this - } - - /** - * Sets the maxFieldSize - NOT! - We throw an SQLException just - * to inform them to stop doing this. - * - * @param max the new max column size limit; zero means unlimited - * @exception SQLException if a database access error occurs - */ - public void setMaxFieldSize(int max) throws SQLException - { - throw new SQLException("Attempt to setMaxFieldSize failed - compile time default"); - } - - /** - * The maxRows limit is set to limit the number of rows that - * any ResultSet can contain. If the limit is exceeded, the - * excess rows are silently dropped. - * - * @return the current maximum row limit; zero means unlimited - * @exception SQLException if a database access error occurs - */ - public int getMaxRows() throws SQLException - { - return connection.maxrows; - } - - /** - * Set the maximum number of rows - * - * @param max the new max rows limit; zero means unlimited - * @exception SQLException if a database access error occurs - * @see getMaxRows - */ - public void setMaxRows(int max) throws SQLException - { - connection.maxrows = max; - } - - /** - * If escape scanning is on (the default), the driver will do escape - * substitution before sending the SQL to the database. - * - * @param enable true to enable; false to disable - * @exception SQLException if a database access error occurs - */ - public void setEscapeProcessing(boolean enable) throws SQLException - { - escapeProcessing = enable; - } - - /** - * The queryTimeout limit is the number of seconds the driver - * will wait for a Statement to execute. If the limit is - * exceeded, a SQLException is thrown. - * - * @return the current query timeout limit in seconds; 0 = unlimited - * @exception SQLException if a database access error occurs - */ - public int getQueryTimeout() throws SQLException - { - return timeout; - } - - /** - * Sets the queryTimeout limit - * - * @param seconds - the new query timeout limit in seconds - * @exception SQLException if a database access error occurs - */ - public void setQueryTimeout(int seconds) throws SQLException - { - timeout = seconds; - } - - /** - * Cancel can be used by one thread to cancel a statement that - * is being executed by another thread. However, PostgreSQL is - * a sync. sort of thing, so this really has no meaning - we - * define it as a no-op (i.e. you can't cancel, but there is no - * error if you try.) - * - * @exception SQLException only because thats the spec. - */ - public void cancel() throws SQLException - { - // No-op - } - - /** - * The first warning reported by calls on this Statement is - * returned. A Statement's execute methods clear its SQLWarning - * chain. Subsequent Statement warnings will be chained to this - * SQLWarning. - * - *

The Warning chain is automatically cleared each time a statement - * is (re)executed. - * - *

Note: If you are processing a ResultSet then any warnings - * associated with ResultSet reads will be chained on the ResultSet - * object. - * - * @return the first SQLWarning on null - * @exception SQLException if a database access error occurs - */ - public SQLWarning getWarnings() throws SQLException - { - return warnings; - } - - /** - * After this call, getWarnings returns null until a new warning - * is reported for this Statement. - * - * @exception SQLException if a database access error occurs (why?) - */ - public void clearWarnings() throws SQLException - { - warnings = null; - } - - /** - * setCursorName defines the SQL cursor name that will be used by - * subsequent execute methods. This name can then be used in SQL - * positioned update/delete statements to identify the current row - * in the ResultSet generated by this statement. If a database - * doesn't support positioned update/delete, this method is a - * no-op. - * - *

Note: By definition, positioned update/delete execution - * must be done by a different Statement than the one which - * generated the ResultSet being used for positioning. Also, cursor - * names must be unique within a Connection. - * - *

We throw an additional constriction. There can only be one - * cursor active at any one time. - * - * @param name the new cursor name - * @exception SQLException if a database access error occurs - */ - public void setCursorName(String name) throws SQLException - { - connection.setCursorName(name); - } - - /** - * Execute a SQL statement that may return multiple results. We - * don't have to worry about this since we do not support multiple - * ResultSets. You can use getResultSet or getUpdateCount to - * retrieve the result. - * - * @param sql any SQL statement - * @return true if the next result is a ResulSet, false if it is - * an update count or there are no more results - * @exception SQLException if a database access error occurs - */ - public boolean execute(String sql) throws SQLException - { - result = connection.ExecSQL(sql); - return (result != null && result.reallyResultSet()); - } - - /** - * getResultSet returns the current result as a ResultSet. It - * should only be called once per result. - * - * @return the current result set; null if there are no more - * @exception SQLException if a database access error occurs (why?) - */ - public java.sql.ResultSet getResultSet() throws SQLException - { - return result; - } - - /** - * getUpdateCount returns the current result as an update count, - * if the result is a ResultSet or there are no more results, -1 - * is returned. It should only be called once per result. - * - * @return the current result as an update count. - * @exception SQLException if a database access error occurs - */ - public int getUpdateCount() throws SQLException - { - if (result == null) return -1; - if (result.reallyResultSet()) return -1; - return result.getResultCount(); - } - - /** - * getMoreResults moves to a Statement's next result. If it returns - * true, this result is a ResulSet. - * - * @return true if the next ResultSet is valid - * @exception SQLException if a database access error occurs - */ - public boolean getMoreResults() throws SQLException - { - result = result.getNext(); - return (result != null && result.reallyResultSet()); - } - - /** - * Returns the status message from the current Result.

- * This is used internally by the driver. - * - * @return status message from backend - */ - public String getResultStatusString() - { - if(result == null) - return null; - return result.getStatusString(); - } -} diff --git a/src/interfaces/jdbc/postgresql/errors.properties b/src/interfaces/jdbc/postgresql/errors.properties new file mode 100644 index 0000000000..2733a256de --- /dev/null +++ b/src/interfaces/jdbc/postgresql/errors.properties @@ -0,0 +1,4 @@ +# This is the default errors +postgresql.jvm.version:The postgresql.jar file does not contain the correct JDBC classes for this JVM. Try rebuilding.\nException thrown was {1} +postgresql.unusual:Something unusual has occured to cause the driver to fail. Please report this exception: {1} +postgresql.unimplemented:This method is not yet implemented. diff --git a/src/interfaces/jdbc/postgresql/errors_fr.properties b/src/interfaces/jdbc/postgresql/errors_fr.properties new file mode 100644 index 0000000000..8db1d3df21 --- /dev/null +++ b/src/interfaces/jdbc/postgresql/errors_fr.properties @@ -0,0 +1,4 @@ +# This is the default errors +postgresql.jvm.version:Le fichier de postgresql.jar ne contient pas les classes correctes de JDBC pour ce JVM. Try que rebuilding.\nException jetées était {1} +postgresql.unusual:Quelque chose de peu commun s'est produit pour faire échouer le gestionnaire. Veuillez enregistrer cette exception: {1} +postgresql.unimplemented:Cette méthode n'est pas encore appliquée. diff --git a/src/interfaces/jdbc/postgresql/jdbc1/PreparedStatement.java b/src/interfaces/jdbc/postgresql/jdbc1/PreparedStatement.java index 78eaf3db35..f56ca20cc1 100644 --- a/src/interfaces/jdbc/postgresql/jdbc1/PreparedStatement.java +++ b/src/interfaces/jdbc/postgresql/jdbc1/PreparedStatement.java @@ -312,7 +312,7 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta */ public void setDate(int parameterIndex, java.sql.Date x) throws SQLException { - SimpleDateFormat df = new SimpleDateFormat("''"+connection.getDateStyle()+"''"); + SimpleDateFormat df = new SimpleDateFormat("''yyyy-MM-dd''"); set(parameterIndex, df.format(x)); diff --git a/src/interfaces/jdbc/postgresql/jdbc1/ResultSet.java b/src/interfaces/jdbc/postgresql/jdbc1/ResultSet.java index 5d5e0334ac..05dd010c8f 100644 --- a/src/interfaces/jdbc/postgresql/jdbc1/ResultSet.java +++ b/src/interfaces/jdbc/postgresql/jdbc1/ResultSet.java @@ -386,7 +386,7 @@ public class ResultSet extends postgresql.ResultSet implements java.sql.ResultSe String s = getString(columnIndex); if(s==null) return null; - SimpleDateFormat df = new SimpleDateFormat(connection.getDateStyle()); + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); try { return new java.sql.Date(df.parse(s).getTime()); } catch (ParseException e) { @@ -443,7 +443,7 @@ public class ResultSet extends postgresql.ResultSet implements java.sql.ResultSe TimeZone zone = TimeZone.getDefault(); zone.setRawOffset(TZ); String nm = zone.getID(); - s = s.substring(0,18) + nm; + s = s.substring(0,19) + nm; try { java.util.Date d = df.parse(s); return new Timestamp(d.getTime()); diff --git a/src/interfaces/jdbc/postgresql/jdbc2/PreparedStatement.java b/src/interfaces/jdbc/postgresql/jdbc2/PreparedStatement.java index 7a835a8193..ef18bbaa9a 100644 --- a/src/interfaces/jdbc/postgresql/jdbc2/PreparedStatement.java +++ b/src/interfaces/jdbc/postgresql/jdbc2/PreparedStatement.java @@ -312,7 +312,7 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta */ public void setDate(int parameterIndex, java.sql.Date x) throws SQLException { - SimpleDateFormat df = new SimpleDateFormat("''"+connection.getDateStyle()+"''"); + SimpleDateFormat df = new SimpleDateFormat("''yyyy-MM-dd''"); set(parameterIndex, df.format(x)); diff --git a/src/interfaces/jdbc/postgresql/jdbc2/ResultSet.java b/src/interfaces/jdbc/postgresql/jdbc2/ResultSet.java index 54e1081a8e..2be4ddba5f 100644 --- a/src/interfaces/jdbc/postgresql/jdbc2/ResultSet.java +++ b/src/interfaces/jdbc/postgresql/jdbc2/ResultSet.java @@ -388,7 +388,7 @@ public class ResultSet extends postgresql.ResultSet implements java.sql.ResultSe String s = getString(columnIndex); if(s==null) return null; - SimpleDateFormat df = new SimpleDateFormat(connection.getDateStyle()); + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); try { return new java.sql.Date(df.parse(s).getTime()); } catch (ParseException e) { @@ -445,7 +445,7 @@ public class ResultSet extends postgresql.ResultSet implements java.sql.ResultSe TimeZone zone = TimeZone.getDefault(); zone.setRawOffset(TZ); String nm = zone.getID(); - s = s.substring(0,18) + nm; + s = s.substring(0,19) + nm; try { java.util.Date d = df.parse(s); return new Timestamp(d.getTime()); diff --git a/src/interfaces/jdbc/postgresql/jdbc2/Statement.java b/src/interfaces/jdbc/postgresql/jdbc2/Statement.java index 427efe14df..4c9c8c9e01 100644 --- a/src/interfaces/jdbc/postgresql/jdbc2/Statement.java +++ b/src/interfaces/jdbc/postgresql/jdbc2/Statement.java @@ -6,6 +6,7 @@ package postgresql.jdbc2; // postgresql.jdbc1 package. import java.sql.*; +import java.util.Vector; /** * A Statement object is used for executing a static SQL statement and @@ -27,6 +28,7 @@ public class Statement implements java.sql.Statement SQLWarning warnings = null; // The warnings chain. int timeout = 0; // The timeout for a query (not used) boolean escapeProcessing = true;// escape processing flag + private Vector batch=null; /** * Constructor for a Statement. It simply sets the connection @@ -325,17 +327,35 @@ public class Statement implements java.sql.Statement public void addBatch(String sql) throws SQLException { - throw postgresql.Driver.notImplemented(); + if(batch==null) + batch=new Vector(); + batch.addElement(sql); } public void clearBatch() throws SQLException { - throw postgresql.Driver.notImplemented(); + if(batch!=null) + batch.removeAllElements(); } public int[] executeBatch() throws SQLException { - throw postgresql.Driver.notImplemented(); + if(batch==null || batch.isEmpty()) + throw new SQLException("The batch is empty."); + + int size=batch.size(); + int[] result=new int[size]; + int i=0; + this.execute("begin"); // PTM: check this when autoCommit is false + try { + for(i=0;i