88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/catalog/pg_shdepend.c,v 1.18 2007/05/11 17:57:12 tgl Exp $
11+ * $PostgreSQL: pgsql/src/backend/catalog/pg_shdepend.c,v 1.19 2007/05/14 16:50:36 alvherre Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -456,6 +456,9 @@ typedef struct
456456 * Check whether there are shared dependency entries for a given shared
457457 * object.Returns a string containing a newline-separated list of object
458458 * descriptions that depend on the shared object, or NULL if none is found.
459+ * The size of the returned string is limited to about MAX_REPORTED_DEPS lines;
460+ * if there are more objects than that, the output is returned truncated at
461+ * that point and the full message is logged to the postmaster log.
459462 *
460463 * We can find three different kinds of dependencies: dependencies on objects
461464 * of the current database; dependencies on shared objects; and dependencies
@@ -472,21 +475,26 @@ checkSharedDependencies(Oid classId, Oid objectId)
472475ScanKeyData key [2 ];
473476SysScanDesc scan ;
474477HeapTuple tup ;
475- int totalDeps = 0 ;
476- int numLocalDeps = 0 ;
477- int numSharedDeps = 0 ;
478+ int numNotReportedDeps = 0 ;
479+ int numReportedDeps = 0 ;
480+ int numNotReportedDbs = 0 ;
478481List * remDeps = NIL ;
479482ListCell * cell ;
480483ObjectAddress object ;
481484StringInfoData descs ;
485+ StringInfoData alldescs ;
482486
483487/*
484- * We try to limit the number of reported dependencies to something sane,
485- * both for the user's sake and to avoid blowing out memory.
488+ * We try to limit the number of dependencies reported to the client to
489+ * something sane, both for the user's sake and to avoid blowing out
490+ * memory. The server log always gets a full report, which is collected
491+ * in a separate StringInfo if and only if we detect that the original
492+ * report is going to be truncated.
486493 */
487494#define MAX_REPORTED_DEPS 100
488495
489496initStringInfo (& descs );
497+ initStringInfo (& alldescs );
490498
491499sdepRel = heap_open (SharedDependRelationId ,AccessShareLock );
492500
@@ -531,17 +539,35 @@ checkSharedDependencies(Oid classId, Oid objectId)
531539 */
532540if (sdepForm -> dbid == MyDatabaseId )
533541{
534- numLocalDeps ++ ;
535- if (++ totalDeps <=MAX_REPORTED_DEPS )
542+ if (++ numReportedDeps <=MAX_REPORTED_DEPS )
536543storeObjectDescription (& descs ,LOCAL_OBJECT ,& object ,
537544sdepForm -> deptype ,0 );
545+ else
546+ {
547+ numNotReportedDeps ++ ;
548+ /* initialize the server-only log line */
549+ if (alldescs .len == 0 )
550+ appendBinaryStringInfo (& alldescs ,descs .data ,descs .len );
551+
552+ storeObjectDescription (& alldescs ,LOCAL_OBJECT ,& object ,
553+ sdepForm -> deptype ,0 );
554+ }
538555}
539556else if (sdepForm -> dbid == InvalidOid )
540557{
541- numSharedDeps ++ ;
542- if (++ totalDeps <=MAX_REPORTED_DEPS )
558+ if (++ numReportedDeps <=MAX_REPORTED_DEPS )
543559storeObjectDescription (& descs ,SHARED_OBJECT ,& object ,
544560sdepForm -> deptype ,0 );
561+ else
562+ {
563+ numNotReportedDeps ++ ;
564+ /* initialize the server-only log line */
565+ if (alldescs .len == 0 )
566+ appendBinaryStringInfo (& alldescs ,descs .data ,descs .len );
567+
568+ storeObjectDescription (& alldescs ,SHARED_OBJECT ,& object ,
569+ sdepForm -> deptype ,0 );
570+ }
545571}
546572else
547573{
@@ -571,7 +597,6 @@ checkSharedDependencies(Oid classId, Oid objectId)
571597dep -> dbOid = sdepForm -> dbid ;
572598dep -> count = 1 ;
573599remDeps = lappend (remDeps ,dep );
574- totalDeps ++ ;
575600}
576601}
577602}
@@ -580,28 +605,11 @@ checkSharedDependencies(Oid classId, Oid objectId)
580605
581606heap_close (sdepRel ,AccessShareLock );
582607
583- if (totalDeps > MAX_REPORTED_DEPS )
584- {
585- /*
586- * Report seems unreasonably long, so reduce it to per-database info
587- *
588- * Note: we don't ever suppress per-database totals, which should be
589- * OK as long as there aren't too many databases ...
590- */
591- resetStringInfo (& descs );
592-
593- if (numLocalDeps > 0 )
594- {
595- appendStringInfo (& descs ,_ ("%d objects in this database" ),
596- numLocalDeps );
597- if (numSharedDeps > 0 )
598- appendStringInfoChar (& descs ,'\n' );
599- }
600- if (numSharedDeps > 0 )
601- appendStringInfo (& descs ,_ ("%d shared objects" ),
602- numSharedDeps );
603- }
604-
608+ /*
609+ * Report dependencies on remote databases. If we're truncating the
610+ * output already, don't put a line per database, but a single one for all
611+ * of them. Otherwise add as many as fit in MAX_REPORTED_DEPS.
612+ */
605613foreach (cell ,remDeps )
606614{
607615remoteDep * dep = lfirst (cell );
@@ -610,18 +618,63 @@ checkSharedDependencies(Oid classId, Oid objectId)
610618object .objectId = dep -> dbOid ;
611619object .objectSubId = 0 ;
612620
613- storeObjectDescription (& descs ,REMOTE_OBJECT ,& object ,
614- SHARED_DEPENDENCY_INVALID ,dep -> count );
621+ if (alldescs .len != 0 )
622+ {
623+ numNotReportedDbs ++ ;
624+ storeObjectDescription (& alldescs ,REMOTE_OBJECT ,& object ,
625+ SHARED_DEPENDENCY_INVALID ,dep -> count );
626+ }
627+ else
628+ {
629+ if (numReportedDeps <=MAX_REPORTED_DEPS )
630+ {
631+ numReportedDeps ++ ;
632+ storeObjectDescription (& descs ,REMOTE_OBJECT ,& object ,
633+ SHARED_DEPENDENCY_INVALID ,dep -> count );
634+ }
635+ else
636+ {
637+ /* initialize the server-only log line */
638+ numNotReportedDbs ++ ;
639+ appendBinaryStringInfo (& alldescs ,descs .data ,descs .len );
640+ storeObjectDescription (& alldescs ,REMOTE_OBJECT ,& object ,
641+ SHARED_DEPENDENCY_INVALID ,dep -> count );
642+ }
643+ }
644+ }
645+
646+ if (numNotReportedDbs > 0 )
647+ {
648+ appendStringInfo (& descs ,"\nand objects in other %d databases" ,
649+ numNotReportedDbs );
615650}
616651
617652list_free_deep (remDeps );
618653
619654if (descs .len == 0 )
620655{
621656pfree (descs .data );
657+ pfree (alldescs .data );
622658return NULL ;
623659}
624660
661+ if (numNotReportedDbs + numNotReportedDeps > 0 )
662+ {
663+ ObjectAddress obj ;
664+
665+ obj .classId = classId ;
666+ obj .objectId = objectId ;
667+ obj .objectSubId = 0 ;
668+ ereport (LOG ,
669+ (errmsg ("objects dependent on %s" ,getObjectDescription (& obj )),
670+ errdetail (alldescs .data )));
671+
672+ if (numNotReportedDeps > 0 )
673+ appendStringInfo (& descs ,"\nand other %d objects" ,
674+ numNotReportedDeps );
675+ }
676+ pfree (alldescs .data );
677+
625678return descs .data ;
626679}
627680
@@ -977,8 +1030,12 @@ storeObjectDescription(StringInfo descs, objectType type,
9771030break ;
9781031
9791032case REMOTE_OBJECT :
980- /* translator: %s will always be "database %s" */
981- appendStringInfo (descs ,_ ("%d objects in %s" ),count ,objdesc );
1033+ if (count == 1 )
1034+ /* translator: %s will always be "database %s" */
1035+ appendStringInfo (descs ,_ ("one object in %s" ),objdesc );
1036+ else
1037+ /* translator: %s will always be "database %s" */
1038+ appendStringInfo (descs ,_ ("%d objects in %s" ),count ,objdesc );
9821039break ;
9831040
9841041default :