Oliver Jowett wrote:
> I am currently cleaning up a few places where OID 0 could get used as a
> parameter type (causing the backend to try to infer a type).
Here is a patch to do this, including the PGobject changes to handle SQL
NULLs.
The PGobject / geometric type changes are a bit ugly in places, mostly
because those types are mutable (unnecessarily, IMO).
-O
Index: org/postgresql/errors.properties
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/errors.properties,v
retrieving revision 1.38
diff -u -c -r1.38 errors.properties
*** org/postgresql/errors.properties 9 Oct 2004 06:02:58 -0000 1.38
--- org/postgresql/errors.properties 9 Oct 2004 10:13:41 -0000
***************
*** 73,78 ****
--- 73,80 ----
postgresql.prep.type:Unknown Types value.
postgresql.prep.typenotfound:Unknown type {0}.
postgresql.prep.zeroinstring:Zero bytes may not occur in string parameters.
+ postgresql.prep.untypedsetnull:setNull(i,Types.OTHER) and setObject(i,null,Types.OTHER) are not supported. Instead,
usesetObject(i,object,Types.OTHER) where 'object' is an appropriate PGobject subclass instance representing a NULL.
+ postgresql.prep.untypedsetobject:setObject(i,null) is not supported. Instead, use setNull(i,type) or
setObject(i,null,type).
postgresql.res.badbigdec:Bad BigDecimal {0}
postgresql.res.badbyte:Bad Byte {0}
postgresql.res.baddate:Bad Date Format {0}
Index: org/postgresql/geometric/PGbox.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/geometric/PGbox.java,v
retrieving revision 1.8
diff -u -c -r1.8 PGbox.java
*** org/postgresql/geometric/PGbox.java 29 Jun 2004 06:43:26 -0000 1.8
--- org/postgresql/geometric/PGbox.java 9 Oct 2004 10:13:41 -0000
***************
*** 23,31 ****
public class PGbox extends PGobject implements Serializable, Cloneable
{
/**
! * These are the two points.
*/
! public PGpoint point[] = new PGpoint[2];
/**
* @param x1 first x coordinate
--- 23,31 ----
public class PGbox extends PGobject implements Serializable, Cloneable
{
/**
! * These are the two points, or null for a SQL NULL.
*/
! public PGpoint point[];
/**
* @param x1 first x coordinate
***************
*** 35,43 ****
*/
public PGbox(double x1, double y1, double x2, double y2)
{
! this();
! this.point[0] = new PGpoint(x1, y1);
! this.point[1] = new PGpoint(x2, y2);
}
/**
--- 35,41 ----
*/
public PGbox(double x1, double y1, double x2, double y2)
{
! this(new PGpoint(x1, y1), new PGpoint(x2, y2));
}
/**
***************
*** 47,54 ****
public PGbox(PGpoint p1, PGpoint p2)
{
this();
! this.point[0] = p1;
! this.point[1] = p2;
}
/**
--- 45,51 ----
public PGbox(PGpoint p1, PGpoint p2)
{
this();
! this.point = new PGpoint[] { p1, p2 };
}
/**
***************
*** 82,89 ****
if (t.getSize() != 2)
throw new PSQLException("postgresql.geo.box", PSQLState.DATA_TYPE_MISMATCH, value);
! point[0] = new PGpoint(t.getToken(0));
! point[1] = new PGpoint(t.getToken(1));
}
/**
--- 79,88 ----
if (t.getSize() != 2)
throw new PSQLException("postgresql.geo.box", PSQLState.DATA_TYPE_MISMATCH, value);
! point = new PGpoint[] {
! new PGpoint(t.getToken(0)),
! new PGpoint(t.getToken(1))
! };
}
/**
***************
*** 96,101 ****
--- 95,106 ----
{
PGbox p = (PGbox)obj;
+ if (point == p.point)
+ return true;
+
+ if (point == null || p.point == null)
+ return false;
+
// Same points.
if (p.point[0].equals(point[0]) && p.point[1].equals(point[1]))
return true;
***************
*** 126,136 ****
--- 131,148 ----
// its X and Y components; we end up with an exclusive-OR of the two X and
// two Y components, which is equal whenever equals() would return true
// since xor is commutative.
+
+ if (point == null)
+ return 0;
+
return point[0].hashCode() ^ point[1].hashCode();
}
public Object clone()
{
+ if (point == null)
+ return new PGbox();
+
return new PGbox((PGpoint)point[0].clone(), (PGpoint)point[1].clone());
}
***************
*** 139,144 ****
--- 151,161 ----
*/
public String getValue()
{
+ if (point == null)
+ return null;
+
return point[0].toString() + "," + point[1].toString();
}
+
+ public final static PGbox NULL = new PGbox();
}
Index: org/postgresql/geometric/PGcircle.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/geometric/PGcircle.java,v
retrieving revision 1.10
diff -u -c -r1.10 PGcircle.java
*** org/postgresql/geometric/PGcircle.java 29 Jun 2004 06:43:26 -0000 1.10
--- org/postgresql/geometric/PGcircle.java 9 Oct 2004 10:13:41 -0000
***************
*** 24,30 ****
public class PGcircle extends PGobject implements Serializable, Cloneable
{
/**
! * This is the center point
*/
public PGpoint center;
--- 24,30 ----
public class PGcircle extends PGobject implements Serializable, Cloneable
{
/**
! * This is the center point, or null for a NULL value
*/
public PGpoint center;
***************
*** 102,107 ****
--- 102,114 ----
if (obj instanceof PGcircle)
{
PGcircle p = (PGcircle)obj;
+
+ if (center == null && p.center == null)
+ return true;
+
+ if (center == null || p.center == null)
+ return false;
+
return p.center.equals(center) && p.radius == radius;
}
return false;
***************
*** 109,120 ****
--- 116,133 ----
public int hashCode()
{
+ if (center == null)
+ return 0;
+
long v = Double.doubleToLongBits(radius);
return (int) (center.hashCode() ^ v ^ (v>>>32));
}
public Object clone()
{
+ if (center == null)
+ return new PGcircle();
+
return new PGcircle((PGpoint)center.clone(), radius);
}
***************
*** 123,128 ****
--- 136,146 ----
*/
public String getValue()
{
+ if (center == null)
+ return null;
+
return "<" + center + "," + radius + ">";
}
+
+ public final static PGcircle NULL = new PGcircle();
}
Index: org/postgresql/geometric/PGline.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/geometric/PGline.java,v
retrieving revision 1.8
diff -u -c -r1.8 PGline.java
*** org/postgresql/geometric/PGline.java 29 Jun 2004 06:43:26 -0000 1.8
--- org/postgresql/geometric/PGline.java 9 Oct 2004 10:13:41 -0000
***************
*** 26,34 ****
public class PGline extends PGobject implements Serializable, Cloneable
{
/**
! * These are the two points.
*/
! public PGpoint point[] = new PGpoint[2];
/**
* @param x1 coordinate for first point
--- 26,34 ----
public class PGline extends PGobject implements Serializable, Cloneable
{
/**
! * These are the two points, or null for a SQL NULL.
*/
! public PGpoint point[];
/**
* @param x1 coordinate for first point
***************
*** 48,55 ****
public PGline(PGpoint p1, PGpoint p2)
{
this();
! this.point[0] = p1;
! this.point[1] = p2;
}
/**
--- 48,54 ----
public PGline(PGpoint p1, PGpoint p2)
{
this();
! this.point = new PGpoint[] { p1, p2 };
}
/**
***************
*** 80,87 ****
if (t.getSize() != 2)
throw new PSQLException("postgresql.geo.line", PSQLState.DATA_TYPE_MISMATCH, s);
! point[0] = new PGpoint(t.getToken(0));
! point[1] = new PGpoint(t.getToken(1));
}
/**
--- 79,88 ----
if (t.getSize() != 2)
throw new PSQLException("postgresql.geo.line", PSQLState.DATA_TYPE_MISMATCH, s);
! point = new PGpoint[] {
! new PGpoint(t.getToken(0)),
! new PGpoint(t.getToken(1))
! };
}
/**
***************
*** 93,98 ****
--- 94,106 ----
if (obj instanceof PGline)
{
PGline p = (PGline)obj;
+
+ if (point == p.point)
+ return true;
+
+ if (point == null || p.point == null)
+ return false;
+
return (p.point[0].equals(point[0]) && p.point[1].equals(point[1])) ||
(p.point[0].equals(point[1]) && p.point[1].equals(point[0]));
}
***************
*** 100,110 ****
--- 108,124 ----
}
public int hashCode() {
+ if (point == null)
+ return 0;
+
return point[0].hashCode() ^ point[1].hashCode();
}
public Object clone()
{
+ if (point == null)
+ return new PGline();
+
return new PGline((PGpoint)point[0].clone(), (PGpoint)point[1].clone());
}
***************
*** 113,118 ****
--- 127,137 ----
*/
public String getValue()
{
+ if (point == null)
+ return null;
+
return "[" + point[0] + "," + point[1] + "]";
}
+
+ public static final PGline NULL = new PGline();
}
Index: org/postgresql/geometric/PGlseg.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/geometric/PGlseg.java,v
retrieving revision 1.8
diff -u -c -r1.8 PGlseg.java
*** org/postgresql/geometric/PGlseg.java 29 Jun 2004 06:43:26 -0000 1.8
--- org/postgresql/geometric/PGlseg.java 9 Oct 2004 10:13:41 -0000
***************
*** 23,31 ****
public class PGlseg extends PGobject implements Serializable, Cloneable
{
/**
! * These are the two points.
*/
! public PGpoint point[] = new PGpoint[2];
/**
* @param x1 coordinate for first point
--- 23,31 ----
public class PGlseg extends PGobject implements Serializable, Cloneable
{
/**
! * These are the two points, or null for a SQL NULL.
*/
! public PGpoint point[];
/**
* @param x1 coordinate for first point
***************
*** 45,52 ****
public PGlseg(PGpoint p1, PGpoint p2)
{
this();
! this.point[0] = p1;
! this.point[1] = p2;
}
/**
--- 45,51 ----
public PGlseg(PGpoint p1, PGpoint p2)
{
this();
! this.point = new PGpoint[] { p1, p2 };
}
/**
***************
*** 77,84 ****
if (t.getSize() != 2)
throw new PSQLException("postgresql.geo.lseg", PSQLState.DATA_TYPE_MISMATCH);
! point[0] = new PGpoint(t.getToken(0));
! point[1] = new PGpoint(t.getToken(1));
}
/**
--- 76,85 ----
if (t.getSize() != 2)
throw new PSQLException("postgresql.geo.lseg", PSQLState.DATA_TYPE_MISMATCH);
! point = new PGpoint[] {
! new PGpoint(t.getToken(0)),
! new PGpoint(t.getToken(1))
! };
}
/**
***************
*** 90,95 ****
--- 91,103 ----
if (obj instanceof PGlseg)
{
PGlseg p = (PGlseg)obj;
+
+ if (point == p.point)
+ return true;
+
+ if (point == null || p.point == null)
+ return false;
+
return (p.point[0].equals(point[0]) && p.point[1].equals(point[1])) ||
(p.point[0].equals(point[1]) && p.point[1].equals(point[0]));
}
***************
*** 98,108 ****
--- 106,122 ----
public int hashCode()
{
+ if (point == null)
+ return 0;
+
return point[0].hashCode() ^ point[1].hashCode();
}
public Object clone()
{
+ if (point == null)
+ return new PGlseg();
+
return new PGlseg((PGpoint)point[0].clone(), (PGpoint)point[1].clone());
}
***************
*** 111,116 ****
--- 125,135 ----
*/
public String getValue()
{
+ if (point == null)
+ return null;
+
return "[" + point[0] + "," + point[1] + "]";
}
+
+ public final static PGlseg NULL = new PGlseg();
}
Index: org/postgresql/geometric/PGpath.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/geometric/PGpath.java,v
retrieving revision 1.9
diff -u -c -r1.9 PGpath.java
*** org/postgresql/geometric/PGpath.java 29 Jun 2004 06:43:26 -0000 1.9
--- org/postgresql/geometric/PGpath.java 9 Oct 2004 10:13:41 -0000
***************
*** 28,34 ****
public boolean open;
/**
! * The points defining this path
*/
public PGpoint points[];
--- 28,34 ----
public boolean open;
/**
! * The points defining this path, or null for a SQL NULL.
*/
public PGpoint points[];
***************
*** 98,103 ****
--- 98,109 ----
{
PGpath p = (PGpath)obj;
+ if (points == null && p.points == null)
+ return true;
+
+ if (points == null || p.points == null)
+ return false;
+
if (p.points.length != points.length)
return false;
***************
*** 115,120 ****
--- 121,130 ----
public int hashCode() {
// XXX not very good..
+
+ if (points == null)
+ return 0;
+
int hash = 0;
for (int i = 0; i < points.length && i < 5; ++i) {
hash = hash ^ points[i].hashCode();
***************
*** 124,129 ****
--- 134,142 ----
public Object clone()
{
+ if (points == null)
+ return new PGpath();
+
PGpoint ary[] = new PGpoint[points.length];
for (int i = 0;i < points.length;i++)
ary[i] = (PGpoint)points[i].clone();
***************
*** 135,140 ****
--- 148,156 ----
*/
public String getValue()
{
+ if (points == null)
+ return null;
+
StringBuffer b = new StringBuffer(open ? "[" : "(");
for (int p = 0;p < points.length;p++)
***************
*** 167,170 ****
--- 183,188 ----
{
open = true;
}
+
+ public final static PGpath NULL = new PGpath();
}
Index: org/postgresql/geometric/PGpoint.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/geometric/PGpoint.java,v
retrieving revision 1.9
diff -u -c -r1.9 PGpoint.java
*** org/postgresql/geometric/PGpoint.java 29 Jun 2004 06:43:26 -0000 1.9
--- org/postgresql/geometric/PGpoint.java 9 Oct 2004 10:13:41 -0000
***************
*** 94,99 ****
--- 94,106 ----
if (obj instanceof PGpoint)
{
PGpoint p = (PGpoint)obj;
+
+ if (this == NULL && p == NULL)
+ return true;
+
+ if (this == NULL || p == NULL)
+ return false;
+
return x == p.x && y == p.y;
}
return false;
***************
*** 101,106 ****
--- 108,116 ----
public int hashCode()
{
+ if (this == NULL)
+ return 0;
+
long v1 = Double.doubleToLongBits(x);
long v2 = Double.doubleToLongBits(y);
return (int) (v1 ^ v2 ^ (v1>>>32) ^ (v2>>>32));
***************
*** 108,113 ****
--- 118,126 ----
public Object clone()
{
+ if (this == NULL)
+ return NULL;
+
return new PGpoint(x, y);
}
***************
*** 116,121 ****
--- 129,137 ----
*/
public String getValue()
{
+ if (this == NULL)
+ return null;
+
return "(" + x + "," + y + ")";
}
***************
*** 184,187 ****
--- 200,207 ----
setLocation(p.x, p.y);
}
+ // Ugly hack -- this unique object, by object identity, is a SQL NULL.
+ // Cloning NULL gives you NULL. You can mutate NULL, but it doesn't
+ // affect its NULL-ness.
+ public final static PGpoint NULL = new PGpoint();
}
Index: org/postgresql/geometric/PGpolygon.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/geometric/PGpolygon.java,v
retrieving revision 1.8
diff -u -c -r1.8 PGpolygon.java
*** org/postgresql/geometric/PGpolygon.java 29 Jun 2004 06:43:26 -0000 1.8
--- org/postgresql/geometric/PGpolygon.java 9 Oct 2004 10:13:41 -0000
***************
*** 20,26 ****
public class PGpolygon extends PGobject implements Serializable, Cloneable
{
/**
! * The points defining the polygon
*/
public PGpoint points[];
--- 20,26 ----
public class PGpolygon extends PGobject implements Serializable, Cloneable
{
/**
! * The points defining the polygon, or null if this is a SQL NULL.
*/
public PGpoint points[];
***************
*** 76,81 ****
--- 76,87 ----
{
PGpolygon p = (PGpolygon)obj;
+ if (points == p.points)
+ return true;
+
+ if (points == null || p.points == null)
+ return false;
+
if (p.points.length != points.length)
return false;
***************
*** 89,94 ****
--- 95,103 ----
}
public int hashCode() {
+ if (points == null)
+ return 0;
+
// XXX not very good..
int hash = 0;
for (int i = 0; i < points.length && i < 5; ++i) {
***************
*** 99,104 ****
--- 108,116 ----
public Object clone()
{
+ if (points == null)
+ return new PGpolygon();
+
PGpoint ary[] = new PGpoint[points.length];
for (int i = 0;i < points.length;i++)
ary[i] = (PGpoint)points[i].clone();
***************
*** 110,115 ****
--- 122,130 ----
*/
public String getValue()
{
+ if (points == null)
+ return null;
+
StringBuffer b = new StringBuffer();
b.append("(");
for (int p = 0;p < points.length;p++)
***************
*** 121,124 ****
--- 136,141 ----
b.append(")");
return b.toString();
}
+
+ public final static PGpolygon NULL = new PGpolygon();
}
Index: org/postgresql/jdbc2/AbstractJdbc2ResultSet.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java,v
retrieving revision 1.48
diff -u -c -r1.48 AbstractJdbc2ResultSet.java
*** org/postgresql/jdbc2/AbstractJdbc2ResultSet.java 30 Sep 2004 18:16:52 -0000 1.48
--- org/postgresql/jdbc2/AbstractJdbc2ResultSet.java 9 Oct 2004 10:13:42 -0000
***************
*** 31,36 ****
--- 31,37 ----
import org.postgresql.Driver;
import org.postgresql.core.*;
import org.postgresql.largeobject.*;
+ import org.postgresql.util.PGobject;
import org.postgresql.util.PGbytea;
import org.postgresql.util.PGtokenizer;
import org.postgresql.util.PSQLException;
***************
*** 766,775 ****
{
String key = (String) keys.nextElement();
Object o = updateValues.get(key);
! if (o instanceof NullObject)
! insertStatement.setNull(i,java.sql.Types.NULL);
! else
! insertStatement.setObject(i, o);
}
insertStatement.executeUpdate();
--- 767,773 ----
{
String key = (String) keys.nextElement();
Object o = updateValues.get(key);
! insertStatement.setObject(i, o);
}
insertStatement.executeUpdate();
***************
*** 1084,1090 ****
public synchronized void updateNull(int columnIndex)
throws SQLException
{
! updateValue(columnIndex, new NullObject());
}
--- 1082,1089 ----
public synchronized void updateNull(int columnIndex)
throws SQLException
{
! String columnTypeName = connection.getPGType(fields[columnIndex - 1].getOID());
! updateValue(columnIndex, new NullObject(columnTypeName));
}
***************
*** 1245,1254 ****
for (; iterator.hasNext(); i++)
{
Object o = iterator.next();
! if (o instanceof NullObject)
! updateStatement.setNull(i+1,java.sql.Types.NULL);
! else
! updateStatement.setObject( i + 1, o );
}
for ( int j = 0; j < numKeys; j++, i++)
--- 1244,1250 ----
for (; iterator.hasNext(); i++)
{
Object o = iterator.next();
! updateStatement.setObject( i + 1, o );
}
for ( int j = 0; j < numKeys; j++, i++)
***************
*** 2613,2620 ****
}
};
! class NullObject {
! };
}
--- 2609,2628 ----
}
};
! //
! // We need to specify the type of NULL when updating a column to NULL, so
! // NullObject is a simple extension of PGobject that always returns null
! // values but retains column type info.
! //
+ class NullObject extends PGobject {
+ NullObject(String type) {
+ setType(type);
+ }
+
+ public String getValue() {
+ return null;
+ }
+ };
}
Index: org/postgresql/jdbc2/AbstractJdbc2Statement.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java,v
retrieving revision 1.32
diff -u -c -r1.32 AbstractJdbc2Statement.java
*** org/postgresql/jdbc2/AbstractJdbc2Statement.java 9 Oct 2004 06:02:58 -0000 1.32
--- org/postgresql/jdbc2/AbstractJdbc2Statement.java 9 Oct 2004 10:13:42 -0000
***************
*** 816,824 ****
oid = Oid.BYTEA;
break;
case Types.OTHER:
default:
! oid = 0;
! break;
}
preparedParameters.setNull(adjustParamIndex(parameterIndex), oid);
--- 816,826 ----
oid = Oid.BYTEA;
break;
case Types.OTHER:
+ // We cannot determine an appropriate OID in this case.
+ throw new PSQLException("postgresql.prep.untypednull", PSQLState.INVALID_PARAMETER_TYPE);
default:
! // Bad Types value.
! throw new PSQLException("postgresql.prep.type", PSQLState.INVALID_PARAMETER_TYPE);
}
preparedParameters.setNull(adjustParamIndex(parameterIndex), oid);
***************
*** 1372,1377 ****
--- 1374,1389 ----
return new BigDecimal(x.toString()).toString();
}
+ // Helper method for setting parameters to PGobject subclasses.
+ private void setPGobject(int parameterIndex, PGobject x) throws SQLException {
+ String typename = x.getType();
+ int oid = connection.getPGType(typename);
+ if (oid == Oid.INVALID)
+ throw new PSQLException("postgresql.prep.typenotfound", PSQLState.INVALID_PARAMETER_TYPE, typename);
+
+ setString(parameterIndex, x.getValue(), oid);
+ }
+
/*
* Set the value of a parameter using an object; use the java.lang
* equivalent objects for integral values.
***************
*** 1478,1487 ****
setObject(parameterIndex, x);
break;
case Types.OTHER:
! if (x instanceof PGobject)
! setString(parameterIndex, ((PGobject)x).getValue(), connection.getPGType( ((PGobject)x).getType()
));
! else
throw new PSQLException("postgresql.prep.type", PSQLState.INVALID_PARAMETER_TYPE);
break;
default:
throw new PSQLException("postgresql.prep.type", PSQLState.INVALID_PARAMETER_TYPE);
--- 1490,1501 ----
setObject(parameterIndex, x);
break;
case Types.OTHER:
! if (x instanceof PGobject) {
! setPGobject(parameterIndex, (PGobject)x);
! } else {
! // Nope. Go away!
throw new PSQLException("postgresql.prep.type", PSQLState.INVALID_PARAMETER_TYPE);
+ }
break;
default:
throw new PSQLException("postgresql.prep.type", PSQLState.INVALID_PARAMETER_TYPE);
***************
*** 1499,1509 ****
public void setObject(int parameterIndex, Object x) throws SQLException
{
checkClosed();
! if (x == null)
! {
! setNull(parameterIndex, Types.OTHER);
! return;
}
if (x instanceof String)
setString(parameterIndex, (String)x);
else if (x instanceof BigDecimal)
--- 1513,1523 ----
public void setObject(int parameterIndex, Object x) throws SQLException
{
checkClosed();
! if (x == null) {
! // We cannot determine an appropriate OID in this case.
! throw new PSQLException("postgresql.prep.untypedsetobject", PSQLState.INVALID_PARAMETER_TYPE);
}
+
if (x instanceof String)
setString(parameterIndex, (String)x);
else if (x instanceof BigDecimal)
***************
*** 1529,1538 ****
else if (x instanceof Boolean)
setBoolean(parameterIndex, ((Boolean)x).booleanValue());
else if (x instanceof PGobject)
! setString(parameterIndex, ((PGobject)x).getValue(), connection.getPGType(((PGobject)x).getType()));
! else
! // Try to store as a string in database
! setString(parameterIndex, x.toString(), 0);
}
/*
--- 1543,1553 ----
else if (x instanceof Boolean)
setBoolean(parameterIndex, ((Boolean)x).booleanValue());
else if (x instanceof PGobject)
! setPGobject(parameterIndex, (PGobject)x);
! else {
! // Nope. Go away!
! throw new PSQLException("postgresql.prep.type", PSQLState.INVALID_PARAMETER_TYPE);
! }
}
/*
Index: org/postgresql/test/jdbc2/GeometricTest.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/test/jdbc2/GeometricTest.java,v
retrieving revision 1.1
diff -u -c -r1.1 GeometricTest.java
*** org/postgresql/test/jdbc2/GeometricTest.java 29 Jun 2004 06:43:28 -0000 1.1
--- org/postgresql/test/jdbc2/GeometricTest.java 9 Oct 2004 10:13:42 -0000
***************
*** 44,50 ****
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT " + column + " FROM testgeometric");
assertTrue(rs.next());
! assertEquals(obj, rs.getObject(1));
rs.close();
stmt.executeUpdate("DELETE FROM testgeometric");
--- 44,56 ----
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT " + column + " FROM testgeometric");
assertTrue(rs.next());
! Object check = rs.getObject(1);
! if (obj.getValue() == null) {
! assertNull(check);
! assertTrue(rs.wasNull());
! } else {
! assertEquals(obj, check);
! }
rs.close();
stmt.executeUpdate("DELETE FROM testgeometric");
***************
*** 57,68 ****
--- 63,76 ----
checkReadWrite(new PGbox(1.0, -2.0, 3.0, 4.0), "boxval");
checkReadWrite(new PGbox(1.0, 2.0, -3.0, 4.0), "boxval");
checkReadWrite(new PGbox(1.0, 2.0, 3.0, -4.0), "boxval");
+ checkReadWrite(PGbox.NULL, "boxval");
}
public void testPGcircle() throws Exception {
checkReadWrite(new PGcircle(1.0, 2.0, 3.0), "circleval");
checkReadWrite(new PGcircle(-1.0, 2.0, 3.0), "circleval");
checkReadWrite(new PGcircle(1.0, -2.0, 3.0), "circleval");
+ checkReadWrite(PGcircle.NULL, "circleval");
}
public void testPGlseg() throws Exception {
***************
*** 71,76 ****
--- 79,85 ----
checkReadWrite(new PGlseg(1.0, -2.0, 3.0, 4.0), "lsegval");
checkReadWrite(new PGlseg(1.0, 2.0, -3.0, 4.0), "lsegval");
checkReadWrite(new PGlseg(1.0, 2.0, 3.0, -4.0), "lsegval");
+ checkReadWrite(PGlseg.NULL, "lsegval");
}
public void testPGpath() throws Exception {
***************
*** 85,90 ****
--- 94,100 ----
checkReadWrite(new PGpath(points, true), "pathval");
checkReadWrite(new PGpath(points, false), "pathval");
+ checkReadWrite(PGpath.NULL, "pathval");
}
public void testPGpolygon() throws Exception {
***************
*** 98,106 ****
--- 108,118 ----
};
checkReadWrite(new PGpolygon(points), "polygonval");
+ checkReadWrite(PGpolygon.NULL, "polygonval");
}
public void testPGpoint() throws Exception {
checkReadWrite(new PGpoint(1.0, 2.0), "pointval");
+ checkReadWrite(PGpoint.NULL, "pointval");
}
}
Index: org/postgresql/util/PGInterval.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/util/PGInterval.java,v
retrieving revision 1.2
diff -u -c -r1.2 PGInterval.java
*** org/postgresql/util/PGInterval.java 20 Sep 2004 08:36:51 -0000 1.2
--- org/postgresql/util/PGInterval.java 9 Oct 2004 10:13:42 -0000
***************
*** 4,23 ****
public class PGInterval extends PGobject implements Serializable, Cloneable
{
! public PGInterval()
! {
! setType("interval");
! }
! public PGInterval(String value )
! {
! this.value = value;
! }
! /*
! * This must be overidden to allow the object to be cloned
! */
! public Object clone()
! {
! return new PGInterval( value );
! }
}
--- 4,26 ----
public class PGInterval extends PGobject implements Serializable, Cloneable
{
! public PGInterval()
! {
! setType("interval");
! }
! public PGInterval(String value)
! {
! this.value = value;
! }
!
! /*
! * This must be overidden to allow the object to be cloned
! */
! public Object clone()
! {
! return new PGInterval( value );
! }
!
! public final static PGInterval NULL = new PGInterval();
}
Index: org/postgresql/util/PGmoney.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/util/PGmoney.java,v
retrieving revision 1.7
diff -u -c -r1.7 PGmoney.java
*** org/postgresql/util/PGmoney.java 29 Nov 2003 19:52:11 -0000 1.7
--- org/postgresql/util/PGmoney.java 9 Oct 2004 10:13:42 -0000
***************
*** 81,86 ****
--- 81,93 ----
if (obj instanceof PGmoney)
{
PGmoney p = (PGmoney)obj;
+
+ if (this == p)
+ return true;
+
+ if (this == NULL || p == NULL)
+ return false;
+
return val == p.val;
}
return false;
***************
*** 91,101 ****
--- 98,114 ----
*/
public Object clone()
{
+ if (this == NULL)
+ return NULL;
+
return new PGmoney(val);
}
public String getValue()
{
+ if (this == NULL)
+ return null;
+
if (val < 0)
{
return "-$" + ( -val);
***************
*** 105,108 ****
--- 118,127 ----
return "$" + val;
}
}
+
+
+ // Ugly hack -- this unique object, by object identity, is a SQL NULL.
+ // Cloning NULL gives you NULL. You can mutate NULL, but it doesn't
+ // affect its NULL-ness.
+ public final static PGmoney NULL = new PGmoney();
}
Index: org/postgresql/util/PGobject.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/util/PGobject.java,v
retrieving revision 1.6
diff -u -c -r1.6 PGobject.java
*** org/postgresql/util/PGobject.java 7 Jun 2004 21:52:46 -0000 1.6
--- org/postgresql/util/PGobject.java 9 Oct 2004 10:13:42 -0000
***************
*** 62,68 ****
/**
* This must be overidden, to return the value of the object, in the
! * form required by org.postgresql.
* @return the value of this object
*/
public String getValue()
--- 62,70 ----
/**
* This must be overidden, to return the value of the object, in the
! * form required by org.postgresql. If this returns null, the object
! * represents an appropriately-typed SQL NULL.
! *
* @return the value of this object
*/
public String getValue()
***************
*** 99,104 ****
*/
public String toString()
{
! return getValue();
}
}
--- 101,109 ----
*/
public String toString()
{
! String value = getValue();
! if (value == null)
! return "NULL";
! return value;
}
}