Content-Length: 440886 | pFad | http://github.com/postgrespro/postgres/commit/94d5d57d5915f1235a4de754da36e47f7c1ff122

8A Fix dependency searching for case where column is visited before table. · postgrespro/postgres@94d5d57 · GitHub
Skip to content

Commit 94d5d57

Browse files
committed
Fix dependency searching for case where column is visited before table.
When the recursive search in dependency.c visits a column and then later visits the whole table containing the column, it needs to propagate the drop-context flags for the table to the existing target-object entry for the column. Otherwise we might refuse the DROP (if not CASCADE) on the incorrect grounds that there was no automatic drop pathway to the column. Remarkably, this has not been reported before, though it's possible at least when an extension creates both a datatype and a table using that datatype. Rather than just marking the column as allowed to be dropped, it might seem good to skip the DROP COLUMN step altogether, since the later DROP of the table will surely get the job done. The problem with that is that the datatype would then be dropped before the table (since the whole situation occurred because we visited the datatype, and then recursed to the dependent column, before visiting the table). That seems pretty risky, and the case is rare enough that it doesn't seem worth expending a lot of effort or risk to make the drops happen in a safe order. So we just play dumb and delete the column separately according to the existing drop ordering rules. Per report from Petr Jelinek, though this is different from his proposed patch. Back-patch to 9.1, where extensions were introduced. There's currently no evidence that such cases can arise before 9.1, and in any case we would also need to back-patch cb5c2ba to 9.0 if we wanted to back-patch this.
1 parent 0766880 commit 94d5d57

File tree

1 file changed

+55
-17
lines changed

1 file changed

+55
-17
lines changed

src/backend/catalog/dependency.c

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1993,6 +1993,7 @@ object_address_present_add_flags(const ObjectAddress *object,
19931993
int flags,
19941994
ObjectAddresses *addrs)
19951995
{
1996+
bool result = false;
19961997
int i;
19971998

19981999
for (i = addrs->numrefs - 1; i >= 0; i--)
@@ -2007,22 +2008,48 @@ object_address_present_add_flags(const ObjectAddress *object,
20072008
ObjectAddressExtra *thisextra = addrs->extras + i;
20082009

20092010
thisextra->flags |= flags;
2010-
return true;
2011+
result = true;
20112012
}
2012-
if (thisobj->objectSubId == 0)
2013+
else if (thisobj->objectSubId == 0)
20132014
{
20142015
/*
20152016
* We get here if we find a need to delete a column after
20162017
* having already decided to drop its whole table. Obviously
2017-
* we no longer need to drop the column. But don't plaster
2018-
* its flags on the table.
2018+
* we no longer need to drop the subobject, so report that we
2019+
* found the subobject in the array. But don't plaster its
2020+
* flags on the whole object.
20192021
*/
2020-
return true;
2022+
result = true;
2023+
}
2024+
else if (object->objectSubId == 0)
2025+
{
2026+
/*
2027+
* We get here if we find a need to delete a whole table after
2028+
* having already decided to drop one of its columns. We
2029+
* can't report that the whole object is in the array, but we
2030+
* should mark the subobject with the whole object's flags.
2031+
*
2032+
* It might seem attractive to physically delete the column's
2033+
* array entry, or at least mark it as no longer needing
2034+
* separate deletion. But that could lead to, e.g., dropping
2035+
* the column's datatype before we drop the table, which does
2036+
* not seem like a good idea. This is a very rare situation
2037+
* in practice, so we just take the hit of doing a separate
2038+
* DROP COLUMN action even though we know we're gonna delete
2039+
* the table later.
2040+
*
2041+
* Because there could be other subobjects of this object in
2042+
* the array, this case means we always have to loop through
2043+
* the whole array; we cannot exit early on a match.
2044+
*/
2045+
ObjectAddressExtra *thisextra = addrs->extras + i;
2046+
2047+
thisextra->flags |= flags;
20212048
}
20222049
}
20232050
}
20242051

2025-
return false;
2052+
return result;
20262053
}
20272054

20282055
/*
@@ -2033,6 +2060,7 @@ stack_address_present_add_flags(const ObjectAddress *object,
20332060
int flags,
20342061
ObjectAddressStack *stack)
20352062
{
2063+
bool result = false;
20362064
ObjectAddressStack *stackptr;
20372065

20382066
for (stackptr = stack; stackptr; stackptr = stackptr->next)
@@ -2045,21 +2073,31 @@ stack_address_present_add_flags(const ObjectAddress *object,
20452073
if (object->objectSubId == thisobj->objectSubId)
20462074
{
20472075
stackptr->flags |= flags;
2048-
return true;
2076+
result = true;
2077+
}
2078+
else if (thisobj->objectSubId == 0)
2079+
{
2080+
/*
2081+
* We're visiting a column with whole table already on stack.
2082+
* As in object_address_present_add_flags(), we can skip
2083+
* further processing of the subobject, but we don't want to
2084+
* propagate flags for the subobject to the whole object.
2085+
*/
2086+
result = true;
2087+
}
2088+
else if (object->objectSubId == 0)
2089+
{
2090+
/*
2091+
* We're visiting a table with column already on stack. As in
2092+
* object_address_present_add_flags(), we should propagate
2093+
* flags for the whole object to each of its subobjects.
2094+
*/
2095+
stackptr->flags |= flags;
20492096
}
2050-
2051-
/*
2052-
* Could visit column with whole table already on stack; this is
2053-
* the same case noted in object_address_present_add_flags(), and
2054-
* as in that case, we don't propagate flags for the component to
2055-
* the whole object.
2056-
*/
2057-
if (thisobj->objectSubId == 0)
2058-
return true;
20592097
}
20602098
}
20612099

2062-
return false;
2100+
return result;
20632101
}
20642102

20652103
/*

0 commit comments

Comments
 (0)








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/postgrespro/postgres/commit/94d5d57d5915f1235a4de754da36e47f7c1ff122

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy