Attached is the patch requested by Tom Lane (see below). It
includes two changes in the JDBC driver: 1) When connected to a backend >= 7.2: use obj_description() and col_description() instead of direct access to pg_description. 2) In DatabaseMetaData.getTables()/getColumns()/getProcedures(): when there is no comment on the object, return null in the REMARKS column of the ResultSet, instead of the default string "no remarks". Change 2 first appeared as a side-effect of change 1, but it is actually more compliant with the JDBC spec: "String object containing an explanatory comment on the table/column/procedure, which may be null". The default string "no remarks" was strictly speaking incorrect, as it could not be distinguished from a real user comment "no remarks". So I removed the default string completely. Change 2 might break existing code that doesn't follow the JDBC spec and isn't prepared to handle a null in the REMARKS column of getTables()/getColumns()/getProcedures. Patch tested with jdbc2 against both a 7.1 and a CVS tip backend. I did not have a jdbc1 environment to build and test with, but since the touched code is identical in jdbc1 and jdbc2 I don't foresee any problems. Regards, Ren? Pijlman
This commit is contained in:
parent
b5453fae74
commit
1ebbfc150a
@ -43,10 +43,6 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
|||||||
static final int iInt4Oid = 23; // OID for int4
|
static final int iInt4Oid = 23; // OID for int4
|
||||||
static final int VARHDRSZ = 4; // length 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)
|
public DatabaseMetaData(Connection conn)
|
||||||
{
|
{
|
||||||
this.connection = conn;
|
this.connection = conn;
|
||||||
@ -1517,8 +1513,6 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
|||||||
java.sql.ResultSet r; // ResultSet for the SQL query that we need to do
|
java.sql.ResultSet r; // ResultSet for the SQL query that we need to do
|
||||||
Vector v = new Vector(); // The new ResultSet tuple stuff
|
Vector v = new Vector(); // The new ResultSet tuple stuff
|
||||||
|
|
||||||
byte remarks[] = defaultRemarks;
|
|
||||||
|
|
||||||
f[0] = new Field(connection, "PROCEDURE_CAT", iVarcharOid, 32);
|
f[0] = new Field(connection, "PROCEDURE_CAT", iVarcharOid, 32);
|
||||||
f[1] = new Field(connection, "PROCEDURE_SCHEM", iVarcharOid, 32);
|
f[1] = new Field(connection, "PROCEDURE_SCHEM", iVarcharOid, 32);
|
||||||
f[2] = new Field(connection, "PROCEDURE_NAME", iVarcharOid, 32);
|
f[2] = new Field(connection, "PROCEDURE_NAME", iVarcharOid, 32);
|
||||||
@ -1540,7 +1534,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
|||||||
tuple[1] = null; // Schema name
|
tuple[1] = null; // Schema name
|
||||||
tuple[2] = r.getBytes(1); // Procedure name
|
tuple[2] = r.getBytes(1); // Procedure name
|
||||||
tuple[3] = tuple[4] = tuple[5] = null; // Reserved
|
tuple[3] = tuple[4] = tuple[5] = null; // Reserved
|
||||||
tuple[6] = remarks; // Remarks
|
tuple[6] = null; // Remarks
|
||||||
|
|
||||||
if (r.getBoolean(2))
|
if (r.getBoolean(2))
|
||||||
tuple[7] = Integer.toString(java.sql.DatabaseMetaData.procedureReturnsResult).getBytes();
|
tuple[7] = Integer.toString(java.sql.DatabaseMetaData.procedureReturnsResult).getBytes();
|
||||||
@ -1684,6 +1678,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
|||||||
|
|
||||||
// Now form the query
|
// Now form the query
|
||||||
StringBuffer sql = new StringBuffer("select relname,oid,relkind from pg_class where (");
|
StringBuffer sql = new StringBuffer("select relname,oid,relkind from pg_class where (");
|
||||||
|
|
||||||
boolean notFirst=false;
|
boolean notFirst=false;
|
||||||
for(int i=0;i<types.length;i++) {
|
for(int i=0;i<types.length;i++) {
|
||||||
for(int j=0;j<getTableTypes.length;j++)
|
for(int j=0;j<getTableTypes.length;j++)
|
||||||
@ -1704,19 +1699,24 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
|||||||
// Now run the query
|
// Now run the query
|
||||||
r = connection.ExecSQL(sql.toString());
|
r = connection.ExecSQL(sql.toString());
|
||||||
|
|
||||||
byte remarks[];
|
|
||||||
|
|
||||||
while (r.next())
|
while (r.next())
|
||||||
{
|
{
|
||||||
byte[][] tuple = new byte[5][0];
|
byte[][] tuple = new byte[5][0];
|
||||||
|
|
||||||
// Fetch the description for the table (if any)
|
// Fetch the description for the table (if any)
|
||||||
java.sql.ResultSet dr = connection.ExecSQL("select description from pg_description where objoid="+r.getInt(2));
|
String getDescriptionStatement =
|
||||||
|
connection.haveMinimumServerVersion("7.2") ?
|
||||||
|
"select obj_description("+r.getInt(2)+",'pg_class')" :
|
||||||
|
"select description from pg_description where objoid=" + r.getInt(2);
|
||||||
|
|
||||||
|
java.sql.ResultSet dr = connection.ExecSQL(getDescriptionStatement);
|
||||||
|
|
||||||
|
byte remarks[] = null;
|
||||||
|
|
||||||
if(((org.postgresql.ResultSet)dr).getTupleCount()==1) {
|
if(((org.postgresql.ResultSet)dr).getTupleCount()==1) {
|
||||||
dr.next();
|
dr.next();
|
||||||
remarks = dr.getBytes(1);
|
remarks = dr.getBytes(1);
|
||||||
} else
|
}
|
||||||
remarks = defaultRemarks;
|
|
||||||
dr.close();
|
dr.close();
|
||||||
|
|
||||||
String relKind;
|
String relKind;
|
||||||
@ -1919,22 +1919,35 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
|||||||
if (columnNamePattern == null) columnNamePattern="%";
|
if (columnNamePattern == null) columnNamePattern="%";
|
||||||
|
|
||||||
// Now form the query
|
// Now form the query
|
||||||
// Modified by Stefan Andreasen <stefan@linux.kapow.dk>
|
String query =
|
||||||
r = connection.ExecSQL("select a.oid,c.relname,a.attname,a.atttypid,a.attnum,a.attnotnull,a.attlen,a.atttypmod,d.adsrc from pg_class c,pg_attribute a,pg_attrdef d where a.attrelid=c.oid and c.relname like '"+tableNamePattern.toLowerCase()+"' and a.attname like '"+columnNamePattern.toLowerCase()+"' and a.attnum>0 and c.oid=d.adrelid and d.adnum=a.attnum order by c.relname,a.attnum");
|
"select " +
|
||||||
|
(connection.haveMinimumServerVersion("7.2") ? "a.attrelid" : "a.oid") +
|
||||||
|
",c.relname,a.attname,a.atttypid," +
|
||||||
|
"a.attnum,a.attnotnull,a.attlen,a.atttypmod,d.adsrc from pg_class c," +
|
||||||
|
"pg_attribute a,pg_attrdef d where a.attrelid=c.oid and " +
|
||||||
|
"c.relname like '"+tableNamePattern.toLowerCase()+"' and " +
|
||||||
|
"a.attname like '"+columnNamePattern.toLowerCase()+"' and " +
|
||||||
|
"a.attnum>0 and c.oid=d.adrelid and d.adnum=a.attnum " +
|
||||||
|
"order by c.relname,a.attnum";
|
||||||
|
|
||||||
byte remarks[];
|
r = connection.ExecSQL(query);
|
||||||
|
|
||||||
while(r.next()) {
|
while(r.next()) {
|
||||||
byte[][] tuple = new byte[18][0];
|
byte[][] tuple = new byte[18][0];
|
||||||
|
|
||||||
// Fetch the description for the table (if any)
|
// Fetch the description for the table (if any)
|
||||||
java.sql.ResultSet dr = connection.ExecSQL("select description from pg_description where objoid="+r.getInt(1));
|
String getDescriptionStatement =
|
||||||
|
connection.haveMinimumServerVersion("7.2") ?
|
||||||
|
"select col_description(" + r.getInt(1) + "," + r.getInt(5) + ")" :
|
||||||
|
"select description from pg_description where objoid=" + r.getInt(1);
|
||||||
|
|
||||||
|
java.sql.ResultSet dr = connection.ExecSQL(getDescriptionStatement);
|
||||||
|
|
||||||
if(((org.postgresql.ResultSet)dr).getTupleCount()==1) {
|
if(((org.postgresql.ResultSet)dr).getTupleCount()==1) {
|
||||||
dr.next();
|
dr.next();
|
||||||
tuple[11] = dr.getBytes(1);
|
tuple[11] = dr.getBytes(1);
|
||||||
} else
|
} else
|
||||||
tuple[11] = defaultRemarks;
|
tuple[11] = null;
|
||||||
|
|
||||||
dr.close();
|
dr.close();
|
||||||
|
|
||||||
tuple[0] = "".getBytes(); // Catalog name
|
tuple[0] = "".getBytes(); // Catalog name
|
||||||
@ -1985,7 +1998,6 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
|||||||
r.close();
|
r.close();
|
||||||
return new ResultSet(connection, f, v, "OK", 1);
|
return new ResultSet(connection, f, v, "OK", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a description of the access rights for a table's columns.
|
* Get a description of the access rights for a table's columns.
|
||||||
*
|
*
|
||||||
|
@ -43,10 +43,6 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
|||||||
static final int iInt4Oid = 23; // OID for int4
|
static final int iInt4Oid = 23; // OID for int4
|
||||||
static final int VARHDRSZ = 4; // length 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)
|
public DatabaseMetaData(Connection conn)
|
||||||
{
|
{
|
||||||
this.connection = conn;
|
this.connection = conn;
|
||||||
@ -1517,8 +1513,6 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
|||||||
java.sql.ResultSet r; // ResultSet for the SQL query that we need to do
|
java.sql.ResultSet r; // ResultSet for the SQL query that we need to do
|
||||||
Vector v = new Vector(); // The new ResultSet tuple stuff
|
Vector v = new Vector(); // The new ResultSet tuple stuff
|
||||||
|
|
||||||
byte remarks[] = defaultRemarks;
|
|
||||||
|
|
||||||
f[0] = new Field(connection, "PROCEDURE_CAT", iVarcharOid, 32);
|
f[0] = new Field(connection, "PROCEDURE_CAT", iVarcharOid, 32);
|
||||||
f[1] = new Field(connection, "PROCEDURE_SCHEM", iVarcharOid, 32);
|
f[1] = new Field(connection, "PROCEDURE_SCHEM", iVarcharOid, 32);
|
||||||
f[2] = new Field(connection, "PROCEDURE_NAME", iVarcharOid, 32);
|
f[2] = new Field(connection, "PROCEDURE_NAME", iVarcharOid, 32);
|
||||||
@ -1540,7 +1534,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
|||||||
tuple[1] = null; // Schema name
|
tuple[1] = null; // Schema name
|
||||||
tuple[2] = r.getBytes(1); // Procedure name
|
tuple[2] = r.getBytes(1); // Procedure name
|
||||||
tuple[3] = tuple[4] = tuple[5] = null; // Reserved
|
tuple[3] = tuple[4] = tuple[5] = null; // Reserved
|
||||||
tuple[6] = remarks; // Remarks
|
tuple[6] = null;
|
||||||
|
|
||||||
if (r.getBoolean(2))
|
if (r.getBoolean(2))
|
||||||
tuple[7] = Integer.toString(java.sql.DatabaseMetaData.procedureReturnsResult).getBytes();
|
tuple[7] = Integer.toString(java.sql.DatabaseMetaData.procedureReturnsResult).getBytes();
|
||||||
@ -1684,6 +1678,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
|||||||
|
|
||||||
// Now form the query
|
// Now form the query
|
||||||
StringBuffer sql = new StringBuffer("select relname,oid,relkind from pg_class where (");
|
StringBuffer sql = new StringBuffer("select relname,oid,relkind from pg_class where (");
|
||||||
|
|
||||||
boolean notFirst=false;
|
boolean notFirst=false;
|
||||||
for(int i=0;i<types.length;i++) {
|
for(int i=0;i<types.length;i++) {
|
||||||
for(int j=0;j<getTableTypes.length;j++)
|
for(int j=0;j<getTableTypes.length;j++)
|
||||||
@ -1704,19 +1699,24 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
|||||||
// Now run the query
|
// Now run the query
|
||||||
r = connection.ExecSQL(sql.toString());
|
r = connection.ExecSQL(sql.toString());
|
||||||
|
|
||||||
byte remarks[];
|
|
||||||
|
|
||||||
while (r.next())
|
while (r.next())
|
||||||
{
|
{
|
||||||
byte[][] tuple = new byte[5][0];
|
byte[][] tuple = new byte[5][0];
|
||||||
|
|
||||||
// Fetch the description for the table (if any)
|
// Fetch the description for the table (if any)
|
||||||
java.sql.ResultSet dr = connection.ExecSQL("select description from pg_description where objoid="+r.getInt(2));
|
String getDescriptionStatement =
|
||||||
|
connection.haveMinimumServerVersion("7.2") ?
|
||||||
|
"select obj_description("+r.getInt(2)+",'pg_class')" :
|
||||||
|
"select description from pg_description where objoid=" + r.getInt(2);
|
||||||
|
|
||||||
|
java.sql.ResultSet dr = connection.ExecSQL(getDescriptionStatement);
|
||||||
|
|
||||||
|
byte remarks[] = null;
|
||||||
|
|
||||||
if(((org.postgresql.ResultSet)dr).getTupleCount()==1) {
|
if(((org.postgresql.ResultSet)dr).getTupleCount()==1) {
|
||||||
dr.next();
|
dr.next();
|
||||||
remarks = dr.getBytes(1);
|
remarks = dr.getBytes(1);
|
||||||
} else
|
}
|
||||||
remarks = defaultRemarks;
|
|
||||||
dr.close();
|
dr.close();
|
||||||
|
|
||||||
String relKind;
|
String relKind;
|
||||||
@ -1919,22 +1919,35 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
|||||||
if (columnNamePattern == null) columnNamePattern="%";
|
if (columnNamePattern == null) columnNamePattern="%";
|
||||||
|
|
||||||
// Now form the query
|
// Now form the query
|
||||||
// Modified by Stefan Andreasen <stefan@linux.kapow.dk>
|
String query =
|
||||||
r = connection.ExecSQL("select a.oid,c.relname,a.attname,a.atttypid,a.attnum,a.attnotnull,a.attlen,a.atttypmod,d.adsrc from pg_class c,pg_attribute a,pg_attrdef d where a.attrelid=c.oid and c.relname like '"+tableNamePattern.toLowerCase()+"' and a.attname like '"+columnNamePattern.toLowerCase()+"' and a.attnum>0 and c.oid=d.adrelid and d.adnum=a.attnum order by c.relname,a.attnum");
|
"select " +
|
||||||
|
(connection.haveMinimumServerVersion("7.2") ? "a.attrelid" : "a.oid") +
|
||||||
|
",c.relname,a.attname,a.atttypid," +
|
||||||
|
"a.attnum,a.attnotnull,a.attlen,a.atttypmod,d.adsrc from pg_class c," +
|
||||||
|
"pg_attribute a,pg_attrdef d where a.attrelid=c.oid and " +
|
||||||
|
"c.relname like '"+tableNamePattern.toLowerCase()+"' and " +
|
||||||
|
"a.attname like '"+columnNamePattern.toLowerCase()+"' and " +
|
||||||
|
"a.attnum>0 and c.oid=d.adrelid and d.adnum=a.attnum " +
|
||||||
|
"order by c.relname,a.attnum";
|
||||||
|
|
||||||
byte remarks[];
|
r = connection.ExecSQL(query);
|
||||||
|
|
||||||
while(r.next()) {
|
while(r.next()) {
|
||||||
byte[][] tuple = new byte[18][0];
|
byte[][] tuple = new byte[18][0];
|
||||||
|
|
||||||
// Fetch the description for the table (if any)
|
// Fetch the description for the table (if any)
|
||||||
java.sql.ResultSet dr = connection.ExecSQL("select description from pg_description where objoid="+r.getInt(1));
|
String getDescriptionStatement =
|
||||||
|
connection.haveMinimumServerVersion("7.2") ?
|
||||||
|
"select col_description(" + r.getInt(1) + "," + r.getInt(5) + ")" :
|
||||||
|
"select description from pg_description where objoid=" + r.getInt(1);
|
||||||
|
|
||||||
|
java.sql.ResultSet dr = connection.ExecSQL(getDescriptionStatement);
|
||||||
|
|
||||||
if(((org.postgresql.ResultSet)dr).getTupleCount()==1) {
|
if(((org.postgresql.ResultSet)dr).getTupleCount()==1) {
|
||||||
dr.next();
|
dr.next();
|
||||||
tuple[11] = dr.getBytes(1);
|
tuple[11] = dr.getBytes(1);
|
||||||
} else
|
} else
|
||||||
tuple[11] = defaultRemarks;
|
tuple[11] = null;
|
||||||
|
|
||||||
dr.close();
|
dr.close();
|
||||||
|
|
||||||
tuple[0] = "".getBytes(); // Catalog name
|
tuple[0] = "".getBytes(); // Catalog name
|
||||||
|
Loading…
x
Reference in New Issue
Block a user