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

Commitaf6550d

Browse files
committed
Sort dependent objects before reporting them in DROP ROLE.
Commit8aa9dd7 didn't quite finish the job in this area after all,because DROP ROLE has a code path distinct from DROP OWNED BY, andit was still reporting dependent objects in whatever order the indexscan returned them in.Buildfarm experience shows that index ordering of equal-keyed objects issignificantly less stable than before in the wake of using heap TIDs astie-breakers. So if we try to hide the unstable ordering by suppressingDETAIL reports, we're just going to end up having to do that for everyDROP that reports multiple objects. That's not great from a coverageor problem-detection standpoint, and it's something we'll inevitablyforget in future patches, leading to more iterations of fixing-an-unstable-result. So let's just bite the bullet and sort here too.Discussion:https://postgr.es/m/E1h6eep-0001Mw-Vd@gemulon.postgresql.org
1 parent59ab3be commitaf6550d

File tree

2 files changed

+111
-25
lines changed

2 files changed

+111
-25
lines changed

‎src/backend/catalog/pg_shdepend.c

Lines changed: 109 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,13 @@ typedef enum
7474
REMOTE_OBJECT
7575
}SharedDependencyObjectType;
7676

77+
typedefstruct
78+
{
79+
ObjectAddressobject;
80+
chardeptype;
81+
SharedDependencyObjectTypeobjtype;
82+
}ShDependObjectInfo;
83+
7784
staticvoidgetOidListDiff(Oid*list1,int*nlist1,Oid*list2,int*nlist2);
7885
staticOidclassIdGetDbId(OidclassId);
7986
staticvoidshdepChangeDep(RelationsdepRel,
@@ -496,6 +503,56 @@ typedef struct
496503
intcount;
497504
}remoteDep;
498505

506+
/*
507+
* qsort comparator for ShDependObjectInfo items
508+
*/
509+
staticint
510+
shared_dependency_comparator(constvoid*a,constvoid*b)
511+
{
512+
constShDependObjectInfo*obja= (constShDependObjectInfo*)a;
513+
constShDependObjectInfo*objb= (constShDependObjectInfo*)b;
514+
515+
/*
516+
* Primary sort key is OID ascending.
517+
*/
518+
if (obja->object.objectId<objb->object.objectId)
519+
return-1;
520+
if (obja->object.objectId>objb->object.objectId)
521+
return1;
522+
523+
/*
524+
* Next sort on catalog ID, in case identical OIDs appear in different
525+
* catalogs. Sort direction is pretty arbitrary here.
526+
*/
527+
if (obja->object.classId<objb->object.classId)
528+
return-1;
529+
if (obja->object.classId>objb->object.classId)
530+
return1;
531+
532+
/*
533+
* Sort on object subId.
534+
*
535+
* We sort the subId as an unsigned int so that 0 (the whole object) will
536+
* come first.
537+
*/
538+
if ((unsignedint)obja->object.objectSubId< (unsignedint)objb->object.objectSubId)
539+
return-1;
540+
if ((unsignedint)obja->object.objectSubId> (unsignedint)objb->object.objectSubId)
541+
return1;
542+
543+
/*
544+
* Last, sort on deptype, in case the same object has multiple dependency
545+
* types. (Note that there's no need to consider objtype, as that's
546+
* determined by the catalog OID.)
547+
*/
548+
if (obja->deptype<objb->deptype)
549+
return-1;
550+
if (obja->deptype>objb->deptype)
551+
return1;
552+
553+
return0;
554+
}
555+
499556
/*
500557
* checkSharedDependencies
501558
*
@@ -531,16 +588,27 @@ checkSharedDependencies(Oid classId, Oid objectId,
531588
List*remDeps=NIL;
532589
ListCell*cell;
533590
ObjectAddressobject;
591+
ShDependObjectInfo*objects;
592+
intnumobjects;
593+
intallocedobjects;
534594
StringInfoDatadescs;
535595
StringInfoDataalldescs;
536596

537597
/*
538598
* We limit the number of dependencies reported to the client to
539599
* MAX_REPORTED_DEPS, since client software may not deal well with
540600
* enormous error strings. The server log always gets a full report.
601+
*
602+
* For stability of regression test results, we sort local and shared
603+
* objects by OID before reporting them. We don't worry about the order
604+
* in which other databases are reported, though.
541605
*/
542606
#defineMAX_REPORTED_DEPS 100
543607

608+
allocedobjects=128;/* arbitrary initial array size */
609+
objects= (ShDependObjectInfo*)
610+
palloc(allocedobjects*sizeof(ShDependObjectInfo));
611+
numobjects=0;
544612
initStringInfo(&descs);
545613
initStringInfo(&alldescs);
546614

@@ -580,36 +648,26 @@ checkSharedDependencies(Oid classId, Oid objectId,
580648

581649
/*
582650
* If it's a dependency local to this database or it's a shared
583-
* object,describe it.
651+
* object,add it to the objects array.
584652
*
585653
* If it's a remote dependency, keep track of it so we can report the
586654
* number of them later.
587655
*/
588-
if (sdepForm->dbid==MyDatabaseId)
589-
{
590-
if (numReportedDeps<MAX_REPORTED_DEPS)
591-
{
592-
numReportedDeps++;
593-
storeObjectDescription(&descs,LOCAL_OBJECT,&object,
594-
sdepForm->deptype,0);
595-
}
596-
else
597-
numNotReportedDeps++;
598-
storeObjectDescription(&alldescs,LOCAL_OBJECT,&object,
599-
sdepForm->deptype,0);
600-
}
601-
elseif (sdepForm->dbid==InvalidOid)
656+
if (sdepForm->dbid==MyDatabaseId||
657+
sdepForm->dbid==InvalidOid)
602658
{
603-
if (numReportedDeps<MAX_REPORTED_DEPS)
659+
if (numobjects >=allocedobjects)
604660
{
605-
numReportedDeps++;
606-
storeObjectDescription(&descs,SHARED_OBJECT,&object,
607-
sdepForm->deptype,0);
661+
allocedobjects *=2;
662+
objects= (ShDependObjectInfo*)
663+
repalloc(objects,
664+
allocedobjects*sizeof(ShDependObjectInfo));
608665
}
609-
else
610-
numNotReportedDeps++;
611-
storeObjectDescription(&alldescs,SHARED_OBJECT,&object,
612-
sdepForm->deptype,0);
666+
objects[numobjects].object=object;
667+
objects[numobjects].deptype=sdepForm->deptype;
668+
objects[numobjects].objtype= (sdepForm->dbid==MyDatabaseId) ?
669+
LOCAL_OBJECT :SHARED_OBJECT;
670+
numobjects++;
613671
}
614672
else
615673
{
@@ -647,6 +705,33 @@ checkSharedDependencies(Oid classId, Oid objectId,
647705

648706
table_close(sdepRel,AccessShareLock);
649707

708+
/*
709+
* Sort and report local and shared objects.
710+
*/
711+
if (numobjects>1)
712+
qsort((void*)objects,numobjects,
713+
sizeof(ShDependObjectInfo),shared_dependency_comparator);
714+
715+
for (inti=0;i<numobjects;i++)
716+
{
717+
if (numReportedDeps<MAX_REPORTED_DEPS)
718+
{
719+
numReportedDeps++;
720+
storeObjectDescription(&descs,
721+
objects[i].objtype,
722+
&objects[i].object,
723+
objects[i].deptype,
724+
0);
725+
}
726+
else
727+
numNotReportedDeps++;
728+
storeObjectDescription(&alldescs,
729+
objects[i].objtype,
730+
&objects[i].object,
731+
objects[i].deptype,
732+
0);
733+
}
734+
650735
/*
651736
* Summarize dependencies in remote databases.
652737
*/
@@ -670,6 +755,7 @@ checkSharedDependencies(Oid classId, Oid objectId,
670755
SHARED_DEPENDENCY_INVALID,dep->count);
671756
}
672757

758+
pfree(objects);
673759
list_free_deep(remDeps);
674760

675761
if (descs.len==0)

‎src/test/regress/expected/dependency.out

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ FROM pg_type JOIN pg_class c ON typrelid = c.oid WHERE typname = 'deptest_t';
128128
-- doesn't work: grant still exists
129129
DROP USER regress_dep_user1;
130130
ERROR: role "regress_dep_user1" cannot be dropped because some objects depend on it
131-
DETAIL: privileges fortable deptest1
132-
privileges fordatabase regression
131+
DETAIL: privileges fordatabase regression
132+
privileges fortable deptest1
133133
owner of default privileges on new relations belonging to role regress_dep_user1 in schema deptest
134134
DROP OWNED BY regress_dep_user1;
135135
DROP USER regress_dep_user1;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp