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:
@ -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()
|
||||
*
|
||||
|
Reference in New Issue
Block a user