Skip to content

Commit

Permalink
fix: resultsets should be updateable if there is a unique constraint …
Browse files Browse the repository at this point in the history
…on the table fixes issue pgjdbc#2196
  • Loading branch information
davecramer committed Jul 1, 2021
1 parent 5f9798e commit be9a3ca
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 1 deletion.
43 changes: 43 additions & 0 deletions pgjdbc/src/main/java/org/postgresql/jdbc/PgDatabaseMetaData.java
Original file line number Diff line number Diff line change
Expand Up @@ -2170,6 +2170,49 @@ public ResultSet getPrimaryKeys(@Nullable String catalog, @Nullable String schem
return createMetaDataStatement().executeQuery(sql);
}

/*
This is for internal use only to see if a resultset is updateable.
Unique keys can also be used so we add them to the query.
*/
protected ResultSet getPrimaryUniqueKeys(@Nullable String catalog, @Nullable String schema, String table)
throws SQLException {
String sql;
sql = "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, "
+ " ct.relname AS TABLE_NAME, a.attname AS COLUMN_NAME, "
+ " (information_schema._pg_expandarray(i.indkey)).n AS KEY_SEQ, ci.relname AS PK_NAME, "
+ " information_schema._pg_expandarray(i.indkey) AS KEYS, a.attnum AS A_ATTNUM "
+ "FROM pg_catalog.pg_class ct "
+ " JOIN pg_catalog.pg_attribute a ON (ct.oid = a.attrelid) "
+ " JOIN pg_catalog.pg_namespace n ON (ct.relnamespace = n.oid) "
+ " JOIN pg_catalog.pg_index i ON ( a.attrelid = i.indrelid) "
+ " JOIN pg_catalog.pg_class ci ON (ci.oid = i.indexrelid) "
+ "WHERE true ";

if (schema != null && !schema.isEmpty()) {
sql += " AND n.nspname = " + escapeQuotes(schema);
}

if (table != null && !table.isEmpty()) {
sql += " AND ct.relname = " + escapeQuotes(table);
}

sql += " AND (i.indisprimary or i.indisunique) ";
sql = "SELECT "
+ " result.TABLE_CAT, "
+ " result.TABLE_SCHEM, "
+ " result.TABLE_NAME, "
+ " result.COLUMN_NAME, "
+ " result.KEY_SEQ, "
+ " result.PK_NAME "
+ "FROM "
+ " (" + sql + " ) result"
+ " where "
+ " result.A_ATTNUM = (result.KEYS).x ";
sql += " ORDER BY result.table_name, result.pk_name, result.key_seq";

return createMetaDataStatement().executeQuery(sql);
}

/**
* @param primaryCatalog primary catalog
* @param primarySchema primary schema
Expand Down
2 changes: 1 addition & 1 deletion pgjdbc/src/main/java/org/postgresql/jdbc/PgResultSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -1646,7 +1646,7 @@ boolean isUpdateable() throws SQLException {
@Nullable String[] s = quotelessTableName(castNonNull(tableName));
String quotelessTableName = castNonNull(s[0]);
@Nullable String quotelessSchemaName = s[1];
java.sql.ResultSet rs = connection.getMetaData().getPrimaryKeys("",
java.sql.ResultSet rs = ((PgDatabaseMetaData)connection.getMetaData()).getPrimaryUniqueKeys("",
quotelessSchemaName, quotelessTableName);

while (rs.next()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ public void setUp() throws Exception {
// put some dummy data into second
st2.execute("insert into second values (1,'anyvalue' )");
st2.close();
TestUtil.createTable(con, "uniqueconstraint", "u1 int unique, name1 text");
TestUtil.execute("insert into uniqueconstraint values (1, 'dave')", con);

}

Expand All @@ -68,6 +70,7 @@ public void tearDown() throws SQLException {
TestUtil.dropTable(con, "stream");
TestUtil.dropTable(con, "nopkmulticol");
TestUtil.dropTable(con, "booltable");
TestUtil.dropTable(con, "uniqueconstraint");
super.tearDown();
}

Expand Down Expand Up @@ -703,4 +706,16 @@ public void testOidUpdatable() throws Exception {
rs.close();
st.close();
}

@Test
public void testUniqueUpdatable() throws Exception {
Statement st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet rs = st.executeQuery("SELECT * from uniqueconstraint");
assertTrue(rs.next());
assertTrue(rs.first());
rs.updateString("name1", "bob");
rs.close();
st.close();
}
}

0 comments on commit be9a3ca

Please sign in to comment.