mirror of
https://github.com/postgres/postgres.git
synced 2025-07-02 09:02:37 +03:00
Applied patch from Paul Sorenson to correctly handle schema names in updateable result sets.
Applied patch from Rich Cullingford to fix a NPE in the absolute() method of result set. Applied patch from Tarjei Skorgenes to fix a NPE when logging is enabled. Modified Files: jdbc/org/postgresql/core/BaseResultSet.java jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java jdbc/org/postgresql/jdbc2/Array.java jdbc/org/postgresql/util/PSQLException.java
This commit is contained in:
@ -6,7 +6,7 @@
|
|||||||
* Copyright (c) 2003, PostgreSQL Global Development Group
|
* Copyright (c) 2003, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/core/Attic/BaseResultSet.java,v 1.1 2003/03/07 18:39:41 barry Exp $
|
* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/core/Attic/BaseResultSet.java,v 1.2 2003/03/08 06:06:55 barry Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -16,16 +16,19 @@ package org.postgresql.core;
|
|||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.ResultSetMetaData;
|
import java.sql.ResultSetMetaData;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
public interface BaseResultSet
|
public interface BaseResultSet
|
||||||
{
|
{
|
||||||
|
|
||||||
public BaseStatement getPGStatement();
|
public BaseStatement getPGStatement();
|
||||||
|
|
||||||
public void append(BaseResultSet r);
|
public void append(BaseResultSet r);
|
||||||
public void close() throws SQLException;
|
public void close() throws SQLException;
|
||||||
public int getColumnCount();
|
public int getColumnCount();
|
||||||
public String getCursorName() throws SQLException;
|
public String getCursorName() throws SQLException;
|
||||||
|
public SimpleDateFormat getDateFormat();
|
||||||
public String getFixedString(int col) throws SQLException;
|
public String getFixedString(int col) throws SQLException;
|
||||||
public long getLastOID();
|
public long getLastOID();
|
||||||
public ResultSetMetaData getMetaData() throws SQLException;
|
public ResultSetMetaData getMetaData() throws SQLException;
|
||||||
@ -35,6 +38,8 @@ public interface BaseResultSet
|
|||||||
public String getStatusString();
|
public String getStatusString();
|
||||||
public String getString(int columnIndex) throws SQLException;
|
public String getString(int columnIndex) throws SQLException;
|
||||||
public StringBuffer getStringBuffer();
|
public StringBuffer getStringBuffer();
|
||||||
|
public SimpleDateFormat getTimestampFormat();
|
||||||
|
public SimpleDateFormat getTimestampTZFormat();
|
||||||
public int getTupleCount();
|
public int getTupleCount();
|
||||||
public boolean next() throws SQLException;
|
public boolean next() throws SQLException;
|
||||||
public boolean reallyResultSet();
|
public boolean reallyResultSet();
|
||||||
|
@ -1,6 +1,20 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* AbstractJdbc1ResultSet.java
|
||||||
|
* This class defines methods of the jdbc1 specification. This class is
|
||||||
|
* extended by org.postgresql.jdbc2.AbstractJdbc2ResultSet which adds the
|
||||||
|
* jdbc2 methods. The real ResultSet class (for jdbc1) is
|
||||||
|
* org.postgresql.jdbc1.Jdbc1ResultSet
|
||||||
|
*
|
||||||
|
* Copyright (c) 2003, PostgreSQL Global Development Group
|
||||||
|
*
|
||||||
|
* IDENTIFICATION
|
||||||
|
* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1ResultSet.java,v 1.11 2003/03/08 06:06:55 barry Exp $
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
package org.postgresql.jdbc1;
|
package org.postgresql.jdbc1;
|
||||||
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
@ -19,11 +33,6 @@ import org.postgresql.util.PGbytea;
|
|||||||
import org.postgresql.util.PGtokenizer;
|
import org.postgresql.util.PGtokenizer;
|
||||||
import org.postgresql.util.PSQLException;
|
import org.postgresql.util.PSQLException;
|
||||||
|
|
||||||
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1ResultSet.java,v 1.10 2003/03/07 18:39:44 barry Exp $
|
|
||||||
* This class defines methods of the jdbc1 specification. This class is
|
|
||||||
* extended by org.postgresql.jdbc2.AbstractJdbc2ResultSet which adds the jdbc2
|
|
||||||
* methods. The real ResultSet class (for jdbc1) is org.postgresql.jdbc1.Jdbc1ResultSet
|
|
||||||
*/
|
|
||||||
public abstract class AbstractJdbc1ResultSet implements BaseResultSet
|
public abstract class AbstractJdbc1ResultSet implements BaseResultSet
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -47,6 +56,10 @@ public abstract class AbstractJdbc1ResultSet implements BaseResultSet
|
|||||||
private StringBuffer sbuf = null;
|
private StringBuffer sbuf = null;
|
||||||
public byte[][] rowBuffer = null;
|
public byte[][] rowBuffer = null;
|
||||||
|
|
||||||
|
private SimpleDateFormat m_tsFormat = null;
|
||||||
|
private SimpleDateFormat m_tstzFormat = null;
|
||||||
|
private SimpleDateFormat m_dateFormat = null;
|
||||||
|
|
||||||
public abstract ResultSetMetaData getMetaData() throws SQLException;
|
public abstract ResultSetMetaData getMetaData() throws SQLException;
|
||||||
|
|
||||||
public AbstractJdbc1ResultSet(BaseStatement statement,
|
public AbstractJdbc1ResultSet(BaseStatement statement,
|
||||||
@ -1020,7 +1033,7 @@ public abstract class AbstractJdbc1ResultSet implements BaseResultSet
|
|||||||
l_sbuf.append(":00");
|
l_sbuf.append(":00");
|
||||||
|
|
||||||
// we'll use this dateformat string to parse the result.
|
// we'll use this dateformat string to parse the result.
|
||||||
df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
|
df = rs.getTimestampTZFormat();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1029,11 +1042,11 @@ public abstract class AbstractJdbc1ResultSet implements BaseResultSet
|
|||||||
if (pgDataType.equals("timestamptz"))
|
if (pgDataType.equals("timestamptz"))
|
||||||
{
|
{
|
||||||
l_sbuf.append(" GMT");
|
l_sbuf.append(" GMT");
|
||||||
df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
|
df = rs.getTimestampTZFormat();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
df = rs.getTimestampFormat();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1044,11 +1057,11 @@ public abstract class AbstractJdbc1ResultSet implements BaseResultSet
|
|||||||
if (pgDataType.equals("timestamptz"))
|
if (pgDataType.equals("timestamptz"))
|
||||||
{
|
{
|
||||||
l_sbuf.append(" GMT");
|
l_sbuf.append(" GMT");
|
||||||
df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
|
df = rs.getTimestampTZFormat();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
df = rs.getTimestampFormat();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1065,7 +1078,7 @@ public abstract class AbstractJdbc1ResultSet implements BaseResultSet
|
|||||||
// We must just have a date. This case is
|
// We must just have a date. This case is
|
||||||
// needed if this method is called on a date
|
// needed if this method is called on a date
|
||||||
// column
|
// column
|
||||||
df = new SimpleDateFormat("yyyy-MM-dd");
|
df = rs.getDateFormat();
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -1075,8 +1088,7 @@ public abstract class AbstractJdbc1ResultSet implements BaseResultSet
|
|||||||
Driver.debug("the data after parsing is "
|
Driver.debug("the data after parsing is "
|
||||||
+ l_sbuf.toString() + " with " + nanos + " nanos");
|
+ l_sbuf.toString() + " with " + nanos + " nanos");
|
||||||
|
|
||||||
Timestamp result =
|
Timestamp result = new Timestamp(df.parse(l_sbuf.toString()).getTime());
|
||||||
new Timestamp(df.parse(l_sbuf.toString()).getTime());
|
|
||||||
result.setNanos(nanos);
|
result.setNanos(nanos);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1087,7 +1099,23 @@ public abstract class AbstractJdbc1ResultSet implements BaseResultSet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SimpleDateFormat getTimestampTZFormat() {
|
||||||
|
if (m_tstzFormat == null) {
|
||||||
|
m_tstzFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
|
||||||
|
}
|
||||||
|
return m_tstzFormat;
|
||||||
|
}
|
||||||
|
public SimpleDateFormat getTimestampFormat() {
|
||||||
|
if (m_tsFormat == null) {
|
||||||
|
m_tsFormat = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss");
|
||||||
|
}
|
||||||
|
return m_tsFormat;
|
||||||
|
}
|
||||||
|
public SimpleDateFormat getDateFormat() {
|
||||||
|
if (m_dateFormat == null) {
|
||||||
|
m_dateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
}
|
||||||
|
return m_dateFormat;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ import org.postgresql.util.PGbytea;
|
|||||||
import org.postgresql.util.PSQLException;
|
import org.postgresql.util.PSQLException;
|
||||||
|
|
||||||
|
|
||||||
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2ResultSet.java,v 1.15 2003/03/07 18:39:45 barry Exp $
|
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2ResultSet.java,v 1.16 2003/03/08 06:06:55 barry Exp $
|
||||||
* This class defines methods of the jdbc2 specification. This class extends
|
* This class defines methods of the jdbc2 specification. This class extends
|
||||||
* org.postgresql.jdbc1.AbstractJdbc1ResultSet which provides the jdbc1
|
* org.postgresql.jdbc1.AbstractJdbc1ResultSet which provides the jdbc1
|
||||||
* methods. The real Statement class (for jdbc2) is org.postgresql.jdbc2.Jdbc2ResultSet
|
* methods. The real Statement class (for jdbc2) is org.postgresql.jdbc2.Jdbc2ResultSet
|
||||||
@ -188,6 +188,10 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra
|
|||||||
|
|
||||||
current_row = internalIndex;
|
current_row = internalIndex;
|
||||||
this_row = (byte[][]) rows.elementAt(internalIndex);
|
this_row = (byte[][]) rows.elementAt(internalIndex);
|
||||||
|
|
||||||
|
rowBuffer = new byte[this_row.length][];
|
||||||
|
System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1319,18 +1323,10 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// otherwise go and get the primary keys and create a hashtable of keys
|
// otherwise go and get the primary keys and create a hashtable of keys
|
||||||
// if the user has supplied a quoted table name
|
String[] s = quotelessTableName(tableName);
|
||||||
// remove the quotes, but preserve the case.
|
String quotelessTableName = s[0];
|
||||||
// otherwise fold to lower case.
|
String quotelessSchemaName = s[1];
|
||||||
String quotelessTableName;
|
java.sql.ResultSet rs = ((java.sql.Connection) connection).getMetaData().getPrimaryKeys("", quotelessSchemaName, quotelessTableName);
|
||||||
if (tableName.startsWith("\"") && tableName.endsWith("\"")) {
|
|
||||||
quotelessTableName = tableName.substring(1,tableName.length()-1);
|
|
||||||
} else {
|
|
||||||
quotelessTableName = tableName.toLowerCase();
|
|
||||||
}
|
|
||||||
java.sql.ResultSet rs = ((java.sql.Connection) connection).getMetaData().getPrimaryKeys("", "", quotelessTableName);
|
|
||||||
|
|
||||||
|
|
||||||
for (; rs.next(); i++ )
|
for (; rs.next(); i++ )
|
||||||
{
|
{
|
||||||
String columnName = rs.getString(4); // get the columnName
|
String columnName = rs.getString(4); // get the columnName
|
||||||
@ -1363,7 +1359,56 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra
|
|||||||
return updateable;
|
return updateable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Cracks out the table name and schema (if it exists) from a fully
|
||||||
|
* qualified table name.
|
||||||
|
* @param fullname string that we are trying to crack. Test cases:<pre>
|
||||||
|
* Table: table ()
|
||||||
|
* "Table": Table ()
|
||||||
|
* Schema.Table: table (schema)
|
||||||
|
* "Schema"."Table": Table (Schema)
|
||||||
|
* "Schema"."Dot.Table": Dot.Table (Schema)
|
||||||
|
* Schema."Dot.Table": Dot.Table (schema)
|
||||||
|
* </pre>
|
||||||
|
* @return String array with element zero always being the tablename and
|
||||||
|
* element 1 the schema name which may be a zero length string.
|
||||||
|
*/
|
||||||
|
public static String[] quotelessTableName(String fullname) {
|
||||||
|
StringBuffer buf = new StringBuffer(fullname);
|
||||||
|
String[] parts = new String[] {null, ""};
|
||||||
|
StringBuffer acc = new StringBuffer();
|
||||||
|
boolean betweenQuotes = false;
|
||||||
|
for (int i = 0; i < buf.length(); i++) {
|
||||||
|
char c = buf.charAt(i);
|
||||||
|
switch (c) {
|
||||||
|
case '"':
|
||||||
|
if ((i < buf.length() - 1) && (buf.charAt(i+1) == '"')) {
|
||||||
|
// two consecutive quotes - keep one
|
||||||
|
i++;
|
||||||
|
acc.append(c); // keep the quote
|
||||||
|
}
|
||||||
|
else { // Discard it
|
||||||
|
betweenQuotes = !betweenQuotes;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '.':
|
||||||
|
if (betweenQuotes) { // Keep it
|
||||||
|
acc.append(c);
|
||||||
|
}
|
||||||
|
else { // Have schema name
|
||||||
|
parts[1] = acc.toString();
|
||||||
|
acc = new StringBuffer();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
acc.append((betweenQuotes) ? c : Character.toLowerCase(c));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Always put table in slot 0
|
||||||
|
parts[0] = acc.toString();
|
||||||
|
return parts;
|
||||||
|
}
|
||||||
|
|
||||||
public void parseQuery()
|
public void parseQuery()
|
||||||
{
|
{
|
||||||
String[] l_sqlFragments = ((AbstractJdbc2Statement)statement).getSqlFragments();
|
String[] l_sqlFragments = ((AbstractJdbc2Statement)statement).getSqlFragments();
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Copyright (c) 2003, PostgreSQL Global Development Group
|
* Copyright (c) 2003, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/util/Attic/PSQLException.java,v 1.9 2003/03/07 18:39:46 barry Exp $
|
* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/util/Attic/PSQLException.java,v 1.10 2003/03/08 06:06:55 barry Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -122,6 +122,6 @@ public class PSQLException extends SQLException
|
|||||||
*/
|
*/
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return message;
|
return message != null ? message : "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user