Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: resultsets should be updateable if there is a unique constraint on the table fixes issue #2196 #2199

Merged
merged 1 commit into from
Jul 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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();
}
}