Re: Fixing findDependentObjects()'s dependency on scan order (regressions in DROP diagnostic messages)

From: Andrey Lepikhov <a(dot)lepikhov(at)postgrespro(dot)ru>
To: Peter Geoghegan <pg(at)bowt(dot)ie>, Alvaro Herrera <alvherre(at)2ndquadrant(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Fixing findDependentObjects()'s dependency on scan order (regressions in DROP diagnostic messages)
Date: 2018-11-06 03:46:17
Message-ID: 0a89eb40-ea89-9037-aad0-3b65c67cdcbd@postgrespro.ru
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

In my opinion, your patch detected three problems:
1. Unsteady order of query results/system messages ('DROP...CASCADE'
detects it).
2. Hide info about a child object dropping ('drop cascades to 62
other objects' detects it).
3. Possible non-informative messages about dependencies ('drop trigger
trg1' detects it)

Problem No. 1 will be amplified with new asynchronous operations,
background workers and distributing query execution. It is not problem
of DBMS. The solution is change the tests: include sorting of query
results, sorting of system messages before diff operation.
If steady order of messages is critical for users we can sort
targetObjects array in the begin of reportDependentObjects() routine by
classId, objectId and objectSubId fields.

Problem No. 2: we can suppress some output optimizations in
object_address_present_add_flags() routine and print all deleted objects.

Problem No. 3: I suppose we can go one of two ways:
a) print all depended objects returned by scan of DependDependerIndexId
relation, not only the first.
b) search a root of dependence and print only it.

On 06.11.2018 5:04, Peter Geoghegan wrote:
> I've realized that my patch to make nbtree keys unique by treating
> heap TID as a tie-breaker attribute must use ASC ordering, for reasons
> that I won't go into here. Now that I'm not using DESC ordering, there
> are changes to a small number of DROP...CASCADE messages that leave
> users with something much less useful than what they'll see today --
> see attached patch for full details. Some of these problematic cases
> involve partitioning:
>
> """
> create table trigpart (a int, b int) partition by range (a);
> create table trigpart1 partition of trigpart for values from (0) to (1000);
> create trigger trg1 after insert on trigpart for each row execute
> procedure trigger_nothing();
> ...
> drop trigger trg1 on trigpart1; -- fail
> -ERROR: cannot drop trigger trg1 on table trigpart1 because trigger
> trg1 on table trigpart requires it
> -HINT: You can drop trigger trg1 on table trigpart instead.
> +ERROR: cannot drop trigger trg1 on table trigpart1 because table
> trigpart1 requires it
> +HINT: You can drop table trigpart1 instead.
> """
>
> As you can see, the original hint suggests "you need to drop the
> object on the partition parent instead of its child", which is useful.
> The new hint suggests "instead of dropping the trigger on the
> partition child, maybe drop the child itself!", which is less than
> useless. This is a problem that needs to be treated as a prerequisite
> to committing the nbtree patch, so I'd like to get it out of the way
> soon.
>
> The high level issue is that findDependentObjects() relies on the scan
> order of duplicates within the
> DependDependerIndexId/pg_depend_depender_index index in a way that
> nbtree doesn't actually guarantee, and never has guaranteed. As I've
> shown, findDependentObjects()'s assumptions around where nbtree will
> leave duplicates accidentally affects the quality of various
> diagnostic messages. My example also breaks with
> ignore_system_indexes=on, even on the master branch, so technically
> this isn't a new problem.
>
> I've looked into a way to fix findDependentObjects(). As far as I can
> tell, I can fix issues by adding a kludgey special case along these
> lines:
>
> 1 diff --git a/src/backend/catalog/dependency.c
> b/src/backend/catalog/dependency.c
> 2 index 7dfa3278a5..7454d4e6f8 100644
> 3 --- a/src/backend/catalog/dependency.c
> 4 +++ b/src/backend/catalog/dependency.c
> 5 @@ -605,6 +605,15 @@ findDependentObjects(const ObjectAddress *object,
> 6 ReleaseDeletionLock(object);
> 7 return;
> 8 }
> 9 + /*
> 10 + * Assume that another pg_depend entry more suitably
> 11 + * represents dependency when an entry for a partition
> 12 + * child's index references a column of the partition
> 13 + * itself.
> 14 + */
> 15 + if (foundDep->deptype == DEPENDENCY_INTERNAL_AUTO &&
> 16 + otherObject.objectSubId != 0)
> 17 + break;
>
> This is obviously brittle, but maybe it hints at a better approach.
> Notably, it doesn't fix other similar issues, such as this:
>
> --- a/contrib/earthdistance/expected/earthdistance.out
> +++ b/contrib/earthdistance/expected/earthdistance.out
> @@ -972,7 +972,7 @@ SELECT abs(cube_distance(ll_to_earth(-30,-90),
> '(0)'::cube) / earth() - 1) <
>
> drop extension cube; -- fail, earthdistance requires it
> ERROR: cannot drop extension cube because other objects depend on it
> -DETAIL: extension earthdistance depends on extension cube
> +DETAIL: extension earthdistance depends on function cube_out(cube)
>
> Can anyone think of a workable, scalable approach to fixing the
> processing order of this findDependentObjects() pg_depend scan so that
> we reliably get the user-visible behavior we already tacitly expect?
>
> --
> Peter Geoghegan
>

--
Andrey Lepikhov
Postgres Professional
https://postgrespro.com
The Russian Postgres Company

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Jonathan S. Katz 2018-11-06 03:49:30 Re: First-draft release notes for back-branch releases
Previous Message David Rowley 2018-11-06 03:40:55 Re: Tid scan improvements