Subject: Sequence queries on pg_depend lacking classid filter

From: Magnus Hagander <[email-masked]>
Date: Thu, 15 Sep 2016 18:22:32 +0200

There are a number of cases where queries in both pgadmin4 and pgadmin3 are
done against pg_depend but falis to constrain the query on classid.

In particular, if for example a constraint and a sequence exists with the
same oid (which is perfectly valid, as they are in different tables), a
column will suddenly refer sequences that are completely incorrect. When we
look up sequences, we have to make sure we only match dependencies against
pg_class.

AFAICT, the following patch catches the important ones. I could go ahead
and push it, but given that we're in RC I'd appreciate a round of review
before doing that, even though it looks fairly simple.

I've got the same changes in a patch to pgadmin3, as these queries are
basically a copy/paste from there. But let's focus the review on the one
for pgadmin4 :)

-- 
 Magnus Hagander
 Me: http://www.hagander.net/
 Work: http://www.redpill-linpro.com/
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/templates/catalog_object_column/sql/9.1_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/templates/catalog_object_column/sql/9.1_plus/properties.sql
index 8be7e99..b2ca255 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/templates/catalog_object_column/sql/9.1_plus/properties.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/templates/catalog_object_column/sql/9.1_plus/properties.sql
@@ -28,7 +28,7 @@ FROM pg_attribute att
   LEFT OUTER JOIN pg_type et ON et.oid=ty.typelem
   LEFT OUTER JOIN pg_attrdef def ON adrelid=att.attrelid AND adnum=att.attnum
   LEFT OUTER JOIN pg_description des ON (des.objoid=att.attrelid AND des.objsubid=att.attnum AND des.classoid='pg_class'::regclass)
-  LEFT OUTER JOIN (pg_depend JOIN pg_class cs ON objid=cs.oid AND cs.relkind='S') ON refobjid=att.attrelid AND refobjsubid=att.attnum
+  LEFT OUTER JOIN (pg_depend JOIN pg_class cs ON objid=cs.oid AND classid='pg_class'::regclass AND cs.relkind='S') ON refobjid=att.attrelid AND refobjsubid=att.attnum
   LEFT OUTER JOIN pg_namespace ns ON ns.oid=cs.relnamespace
   LEFT OUTER JOIN pg_index pi ON pi.indrelid=att.attrelid AND indisprimary
   LEFT OUTER JOIN pg_collation coll ON att.attcollation=coll.oid
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.1_plus/is_referenced.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.1_plus/is_referenced.sql
index 7d0bfc3..52a4ffa 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.1_plus/is_referenced.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.1_plus/is_referenced.sql
@@ -2,4 +2,5 @@ SELECT COUNT(1)
 FROM pg_depend dep
     JOIN pg_class cl ON dep.classid=cl.oid AND relname='pg_rewrite'
     WHERE refobjid= {{tid}}::oid
+    AND classid='pg_class'::regclass
     AND refobjsubid= {{clid|qtLiteral}};
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.1_plus/nodes.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.1_plus/nodes.sql
index 5083dfd..7536a9c 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.1_plus/nodes.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.1_plus/nodes.sql
@@ -6,7 +6,7 @@ FROM pg_attribute att
     JOIN pg_namespace na ON na.oid=cl.relnamespace
     LEFT OUTER JOIN pg_type et ON et.oid=ty.typelem
     LEFT OUTER JOIN pg_attrdef def ON adrelid=att.attrelid AND adnum=att.attnum
-    LEFT OUTER JOIN (pg_depend JOIN pg_class cs ON objid=cs.oid AND cs.relkind='S') ON refobjid=att.attrelid AND refobjsubid=att.attnum
+    LEFT OUTER JOIN (pg_depend JOIN pg_class cs ON classid='pg_class'::regclass AND objid=cs.oid AND cs.relkind='S') ON refobjid=att.attrelid AND refobjsubid=att.attnum
     LEFT OUTER JOIN pg_namespace ns ON ns.oid=cs.relnamespace
     LEFT OUTER JOIN pg_index pi ON pi.indrelid=att.attrelid AND indisprimary
 WHERE
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.1_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.1_plus/properties.sql
index 130b4a8..bb96cff 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.1_plus/properties.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.1_plus/properties.sql
@@ -28,7 +28,7 @@ FROM pg_attribute att
   LEFT OUTER JOIN pg_type et ON et.oid=ty.typelem
   LEFT OUTER JOIN pg_attrdef def ON adrelid=att.attrelid AND adnum=att.attnum
   LEFT OUTER JOIN pg_description des ON (des.objoid=att.attrelid AND des.objsubid=att.attnum AND des.classoid='pg_class'::regclass)
-  LEFT OUTER JOIN (pg_depend JOIN pg_class cs ON objid=cs.oid AND cs.relkind='S') ON refobjid=att.attrelid AND refobjsubid=att.attnum
+  LEFT OUTER JOIN (pg_depend JOIN pg_class cs ON classid='pg_class'::regclass AND objid=cs.oid AND cs.relkind='S') ON refobjid=att.attrelid AND refobjsubid=att.attnum
   LEFT OUTER JOIN pg_namespace ns ON ns.oid=cs.relnamespace
   LEFT OUTER JOIN pg_index pi ON pi.indrelid=att.attrelid AND indisprimary
   LEFT OUTER JOIN pg_collation coll ON att.attcollation=coll.oid
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.2_plus/is_referenced.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.2_plus/is_referenced.sql
index 7d0bfc3..52a4ffa 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.2_plus/is_referenced.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.2_plus/is_referenced.sql
@@ -2,4 +2,5 @@ SELECT COUNT(1)
 FROM pg_depend dep
     JOIN pg_class cl ON dep.classid=cl.oid AND relname='pg_rewrite'
     WHERE refobjid= {{tid}}::oid
+    AND classid='pg_class'::regclass
     AND refobjsubid= {{clid|qtLiteral}};
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.2_plus/nodes.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.2_plus/nodes.sql
index 7c8a1ac..af764a8 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.2_plus/nodes.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.2_plus/nodes.sql
@@ -6,7 +6,7 @@ FROM pg_attribute att
   JOIN pg_namespace na ON na.oid=cl.relnamespace
   LEFT OUTER JOIN pg_type et ON et.oid=ty.typelem
   LEFT OUTER JOIN pg_attrdef def ON adrelid=att.attrelid AND adnum=att.attnum
-  LEFT OUTER JOIN (pg_depend JOIN pg_class cs ON objid=cs.oid AND cs.relkind='S') ON refobjid=att.attrelid AND refobjsubid=att.attnum
+  LEFT OUTER JOIN (pg_depend JOIN pg_class cs ON classid='pg_class'::regclass AND objid=cs.oid AND classid='pg_class'::regclass AND cs.relkind='S') ON refobjid=att.attrelid AND refobjsubid=att.attnum
   LEFT OUTER JOIN pg_namespace ns ON ns.oid=cs.relnamespace
   LEFT OUTER JOIN pg_index pi ON pi.indrelid=att.attrelid AND indisprimary
 WHERE
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.2_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.2_plus/properties.sql
index 8c5b189..b383496 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.2_plus/properties.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.2_plus/properties.sql
@@ -28,7 +28,7 @@ FROM pg_attribute att
   LEFT OUTER JOIN pg_type et ON et.oid=ty.typelem
   LEFT OUTER JOIN pg_attrdef def ON adrelid=att.attrelid AND adnum=att.attnum
   LEFT OUTER JOIN pg_description des ON (des.objoid=att.attrelid AND des.objsubid=att.attnum AND des.classoid='pg_class'::regclass)
-  LEFT OUTER JOIN (pg_depend JOIN pg_class cs ON objid=cs.oid AND cs.relkind='S') ON refobjid=att.attrelid AND refobjsubid=att.attnum
+  LEFT OUTER JOIN (pg_depend JOIN pg_class cs ON classid='pg_class'::regclass AND objid=cs.oid AND cs.relkind='S') ON refobjid=att.attrelid AND refobjsubid=att.attnum
   LEFT OUTER JOIN pg_namespace ns ON ns.oid=cs.relnamespace
   LEFT OUTER JOIN pg_index pi ON pi.indrelid=att.attrelid AND indisprimary
   LEFT OUTER JOIN pg_collation coll ON att.attcollation=coll.oid

-- 
Sent via pgadmin-hackers mailing list ([email-masked])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers

---

From: Dave Page <[email-masked]>
Date: Fri, 16 Sep 2016 11:25:51 +0100

Thanks - committed with a minor change to remove a duplicate WHERE
clause that you added to one of the queries.

On Thu, Sep 15, 2016 at 5:22 PM, Magnus Hagander <[email-masked]> wrote:
> AFAICT, the following patch catches the important ones. I could go ahead and
> push it, but given that we're in RC I'd appreciate a round of review before
> doing that, even though it looks fairly simple.
>
> basically a copy/paste from there. But let's focus the review on the one for
> pgadmin4 :)
>
> --
>  Magnus Hagander

-- 
Dave Page
Blog: http://pgsnake.blogspot.com
Twitter: @pgsnake

EnterpriseDB UK: http://www.enterprisedb.com
The Enterprise PostgreSQL Company