Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2edfc02

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 latervisits the whole table containing the column, it needs to propagate thedrop-context flags for the table to the existing target-object entry forthe column. Otherwise we might refuse the DROP (if not CASCADE) on theincorrect grounds that there was no automatic drop pathway to the column.Remarkably, this has not been reported before, though it's possible atleast when an extension creates both a datatype and a table using thatdatatype.Rather than just marking the column as allowed to be dropped, it mightseem good to skip the DROP COLUMN step altogether, since the later DROPof the table will surely get the job done. The problem with that is thatthe datatype would then be dropped before the table (since the wholesituation occurred because we visited the datatype, and then recursed tothe 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 ofeffort or risk to make the drops happen in a safe order. So we just playdumb and delete the column separately according to the existing dropordering rules.Per report from Petr Jelinek, though this is different from his proposedpatch.Back-patch to 9.1, where extensions were introduced. There's currentlyno evidence that such cases can arise before 9.1, and in any case we wouldalso need to back-patchcb5c2ba to 9.0if we wanted to back-patch this.
1 parent1871c89 commit2edfc02

File tree

1 file changed

+56
-18
lines changed

1 file changed

+56
-18
lines changed

‎src/backend/catalog/dependency.c

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ deleteObjectsInList(ObjectAddresses *targetObjects, Relation *depRel,
246246
* not the direct result of a user-initiated action. For example, when a
247247
* temporary schema is cleaned out so that a new backend can use it, or when
248248
* a column default is dropped as an intermediate step while adding a new one,
249-
* that's an internal operation. On the other hand, whenthewe drop something
249+
* that's an internal operation. On the other hand, when we drop something
250250
* because the user issued a DROP statement against it, that's not internal.
251251
*/
252252
void
@@ -2116,6 +2116,7 @@ object_address_present_add_flags(const ObjectAddress *object,
21162116
intflags,
21172117
ObjectAddresses*addrs)
21182118
{
2119+
boolresult= false;
21192120
inti;
21202121

21212122
for (i=addrs->numrefs-1;i >=0;i--)
@@ -2130,22 +2131,48 @@ object_address_present_add_flags(const ObjectAddress *object,
21302131
ObjectAddressExtra*thisextra=addrs->extras+i;
21312132

21322133
thisextra->flags |=flags;
2133-
return true;
2134+
result= true;
21342135
}
2135-
if (thisobj->objectSubId==0)
2136+
elseif (thisobj->objectSubId==0)
21362137
{
21372138
/*
21382139
* We get here if we find a need to delete a column after
21392140
* having already decided to drop its whole table. Obviously
2140-
* we no longer need to drop the column. But don't plaster
2141-
* its flags on the table.
2141+
* we no longer need to drop the subobject, so report that we
2142+
* found the subobject in the array. But don't plaster its
2143+
* flags on the whole object.
21422144
*/
2143-
return true;
2145+
result= true;
2146+
}
2147+
elseif (object->objectSubId==0)
2148+
{
2149+
/*
2150+
* We get here if we find a need to delete a whole table after
2151+
* having already decided to drop one of its columns. We
2152+
* can't report that the whole object is in the array, but we
2153+
* should mark the subobject with the whole object's flags.
2154+
*
2155+
* It might seem attractive to physically delete the column's
2156+
* array entry, or at least mark it as no longer needing
2157+
* separate deletion. But that could lead to, e.g., dropping
2158+
* the column's datatype before we drop the table, which does
2159+
* not seem like a good idea. This is a very rare situation
2160+
* in practice, so we just take the hit of doing a separate
2161+
* DROP COLUMN action even though we know we're gonna delete
2162+
* the table later.
2163+
*
2164+
* Because there could be other subobjects of this object in
2165+
* the array, this case means we always have to loop through
2166+
* the whole array; we cannot exit early on a match.
2167+
*/
2168+
ObjectAddressExtra*thisextra=addrs->extras+i;
2169+
2170+
thisextra->flags |=flags;
21442171
}
21452172
}
21462173
}
21472174

2148-
returnfalse;
2175+
returnresult;
21492176
}
21502177

21512178
/*
@@ -2156,6 +2183,7 @@ stack_address_present_add_flags(const ObjectAddress *object,
21562183
intflags,
21572184
ObjectAddressStack*stack)
21582185
{
2186+
boolresult= false;
21592187
ObjectAddressStack*stackptr;
21602188

21612189
for (stackptr=stack;stackptr;stackptr=stackptr->next)
@@ -2168,21 +2196,31 @@ stack_address_present_add_flags(const ObjectAddress *object,
21682196
if (object->objectSubId==thisobj->objectSubId)
21692197
{
21702198
stackptr->flags |=flags;
2171-
return true;
2199+
result= true;
2200+
}
2201+
elseif (thisobj->objectSubId==0)
2202+
{
2203+
/*
2204+
* We're visiting a column with whole table already on stack.
2205+
* As in object_address_present_add_flags(), we can skip
2206+
* further processing of the subobject, but we don't want to
2207+
* propagate flags for the subobject to the whole object.
2208+
*/
2209+
result= true;
2210+
}
2211+
elseif (object->objectSubId==0)
2212+
{
2213+
/*
2214+
* We're visiting a table with column already on stack. As in
2215+
* object_address_present_add_flags(), we should propagate
2216+
* flags for the whole object to each of its subobjects.
2217+
*/
2218+
stackptr->flags |=flags;
21722219
}
2173-
2174-
/*
2175-
* Could visit column with whole table already on stack; this is
2176-
* the same case noted in object_address_present_add_flags(), and
2177-
* as in that case, we don't propagate flags for the component to
2178-
* the whole object.
2179-
*/
2180-
if (thisobj->objectSubId==0)
2181-
return true;
21822220
}
21832221
}
21842222

2185-
returnfalse;
2223+
returnresult;
21862224
}
21872225

21882226
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp