From: | bht(at)actrix(dot)gen(dot)nz |
---|---|
To: | pgsql-jdbc(at)postgresql(dot)org |
Subject: | Bug: Cannot pass null in Parameter in Query for ISNULL |
Date: | 2011-11-30 06:51:59 |
Message-ID: | 6ekbd7dm4d6su5b9i4hsf92ibv4j76n51f@4ax.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-jdbc |
Hi,
Native PostgreSQL has no problem with queries like:
select id from author a where null is null or a.name = null
However the JDBC driver fails to process such a query with a
parameter:
ERROR: could not determine data type of parameter $1
The failure reproduces with a very simple and common JPQL query shown
at
http://en.wikipedia.org/wiki/Java_Persistence_Query_Language#Examples
SELECT a FROM Author a WHERE :lastName IS NULL OR LOWER(a.lastName) =
:lastName
While the final pass criterion is a JPA testcase, the error can also
be reproduced more directly with raw JDBC.
It appears to be unproductive to test for the "type" of null of a host
variable in "WHERE ? IS NULL" or "WHERE :lastName IS NULL"
Other drivers for databases e.g. MS SQL Server, Oracle, Sybase, mySQL
achieve the expected results.
To solve this defect would be quite rewarding because while the defect
appears to be perplexingly simple, the typical use cases are quite
prominient, useful and powerful.
Testcase JDBC (I can provide a zip file with both JPA and JBC cases if
required):
DROP TABLE REGION
CREATE TABLE REGION (ID INTEGER NOT NULL, PRIMARY KEY (ID))
DROP TABLE CUSTOMERORDER
CREATE TABLE CUSTOMERORDER (ID INTEGER NOT NULL, NAME VARCHAR(255),
region_id INTEGER, PRIMARY KEY (ID))
ALTER TABLE CUSTOMERORDER ADD CONSTRAINT FK_CUSTOMERORDER_region_id
FOREIGN KEY (region_id) REFERENCES REGION (ID)
package main;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
public class Jdbc {
private static final boolean NULL_WORKAROUND = false;
public static void main(String[] args){
try {
DriverManager.registerDriver(new org.postgresql.Driver());
String url = "jdbc:postgresql://localhost:5432/test";
String user ="postgres";
String password="passme";
Connection conn = DriverManager.getConnection(url, user,
password);
String sql = "SELECT ID, NAME, region_id FROM
CUSTOMERORDER WHERE ((? IS NULL) OR (region_id = ?))";
PreparedStatement pStmt = conn.prepareStatement(sql);
Integer regionId = null;
if(regionId == null && NULL_WORKAROUND){
pStmt.setNull(1, Types.INTEGER);
pStmt.setNull(2, Types.INTEGER);
}else{
pStmt.setObject(1, regionId);
pStmt.setObject(2, regionId);
}
ResultSet result = pStmt.executeQuery();
while(result.next()){
int id = result.getInt(1);
String name = result.getString(2);
Integer regionIdResult = (Integer)result.getObject(3);
}
} catch (SQLException ex) {
ex.printStackTrace();
}
}
}
From | Date | Subject | |
---|---|---|---|
Next Message | Mikko Tiihonen | 2011-11-30 06:55:37 | Re: Bug when retrieving money datatype. |
Previous Message | Oliver Jowett | 2011-11-29 21:51:00 | Re: Bug when retrieving money datatype. |