1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-13 07:41:39 +03:00

Do some minor code refactoring in preparation for changing the APIs of

find_inheritance_children() and find_all_inheritors().  I got annoyed that
these are buried inside the planner but mostly used elsewhere.  So, create
a new file catalog/pg_inherits.c and put them there, along with a couple
of other functions that search pg_inherits.

The code that modifies pg_inherits is (still) in tablecmds.c --- it's
kind of entangled with unrelated code that modifies pg_depend and other
stuff, so pulling it out seemed like a bigger change than I wanted to make
right now.  But this file provides a natural home for it if anyone ever
gets around to that.

This commit just moves code around; it doesn't change anything, except
I succumbed to the temptation to make a couple of trivial optimizations
in typeInheritsFrom().
This commit is contained in:
Tom Lane
2009-05-12 00:56:05 +00:00
parent 6480c143ee
commit 0ada559187
12 changed files with 282 additions and 242 deletions

View File

@ -8,14 +8,12 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.213 2009/04/24 16:09:50 tgl Exp $
* $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.214 2009/05/12 00:56:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/heapam.h"
#include "catalog/pg_inherits.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "funcapi.h"
@ -28,10 +26,8 @@
#include "parser/parse_target.h"
#include "parser/parse_type.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
#include "utils/tqual.h"
static Oid FuncNameAsType(List *funcname);
@ -1037,98 +1033,6 @@ func_get_detail(List *funcname,
}
/*
* Given two type OIDs, determine whether the first is a complex type
* (class type) that inherits from the second.
*/
bool
typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId)
{
bool result = false;
Oid relid;
Relation inhrel;
List *visited,
*queue;
ListCell *queue_item;
if (!ISCOMPLEX(subclassTypeId) || !ISCOMPLEX(superclassTypeId))
return false;
relid = typeidTypeRelid(subclassTypeId);
if (relid == InvalidOid)
return false;
/*
* Begin the search at the relation itself, so add relid to the queue.
*/
queue = list_make1_oid(relid);
visited = NIL;
inhrel = heap_open(InheritsRelationId, AccessShareLock);
/*
* Use queue to do a breadth-first traversal of the inheritance graph from
* the relid supplied up to the root. Notice that we append to the queue
* inside the loop --- this is okay because the foreach() macro doesn't
* advance queue_item until the next loop iteration begins.
*/
foreach(queue_item, queue)
{
Oid this_relid = lfirst_oid(queue_item);
ScanKeyData skey;
HeapScanDesc inhscan;
HeapTuple inhtup;
/* If we've seen this relid already, skip it */
if (list_member_oid(visited, this_relid))
continue;
/*
* Okay, this is a not-yet-seen relid. Add it to the list of
* already-visited OIDs, then find all the types this relid inherits
* from and add them to the queue. The one exception is we don't add
* the original relation to 'visited'.
*/
if (queue_item != list_head(queue))
visited = lappend_oid(visited, this_relid);
ScanKeyInit(&skey,
Anum_pg_inherits_inhrelid,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(this_relid));
inhscan = heap_beginscan(inhrel, SnapshotNow, 1, &skey);
while ((inhtup = heap_getnext(inhscan, ForwardScanDirection)) != NULL)
{
Form_pg_inherits inh = (Form_pg_inherits) GETSTRUCT(inhtup);
Oid inhparent = inh->inhparent;
/* If this is the target superclass, we're done */
if (get_rel_type_id(inhparent) == superclassTypeId)
{
result = true;
break;
}
/* Else add to queue */
queue = lappend_oid(queue, inhparent);
}
heap_endscan(inhscan);
if (result)
break;
}
heap_close(inhrel, AccessShareLock);
list_free(visited);
list_free(queue);
return result;
}
/*
* make_fn_arguments()
*