-
Notifications
You must be signed in to change notification settings - Fork 2
/
pgsp_inherit.c
102 lines (80 loc) · 2.34 KB
/
pgsp_inherit.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/*-------------------------------------------------------------------------
*
* pspg_inherit.c: Some functions to handle inheritance children.
*
* This program is open source, licensed under the PostgreSQL license.
* For license terms, see the LICENSE file.
*
* Copyright (C) 2021-2023: Julien Rouhaud
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/genam.h"
#include "access/table.h"
#if PG_VERSION_NUM < 140000
#include "catalog/indexing.h"
#endif
#include "catalog/pg_inherits.h"
#include "utils/fmgroids.h"
#include "include/pgsp_import.h"
#include "include/pgsp_inherit.h"
static void pgsp_get_inheritance_ancestors_worker(Relation inhRel, Oid relid,
List **ancestors);
static List *pgsp_get_inheritance_parent_worker(Relation inhRel, Oid relid);
/*
* Modified version of get_partition_ancestors to work with relations having
* multiple ancestors.
*/
List *
pgsp_get_inheritance_ancestors(Oid relid)
{
List *result = NIL;
Relation inhRel;
inhRel = table_open(InheritsRelationId, AccessShareLock);
pgsp_get_inheritance_ancestors_worker(inhRel, relid, &result);
table_close(inhRel, AccessShareLock);
return result;
}
static void
pgsp_get_inheritance_ancestors_worker(Relation inhRel, Oid relid,
List **ancestors)
{
List *parentOids;
ListCell *lc;
/*
* Recursion ends at the topmost level, ie., when there's no parent.
*/
parentOids = pgsp_get_inheritance_parent_worker(inhRel, relid);
if (parentOids == NIL)
return;
foreach(lc, parentOids)
{
Oid parentOid = lfirst_oid(lc);
if (list_member_oid(*ancestors, parentOid))
continue;
*ancestors = lappend_oid(*ancestors, parentOid);
pgsp_get_inheritance_ancestors_worker(inhRel, parentOid, ancestors);
}
}
static List *
pgsp_get_inheritance_parent_worker(Relation inhRel, Oid relid)
{
SysScanDesc scan;
ScanKeyData key[1];
List *result = NIL;
HeapTuple tuple;
ScanKeyInit(&key[0],
Anum_pg_inherits_inhrelid,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(relid));
scan = systable_beginscan(inhRel, InheritsRelidSeqnoIndexId, true,
NULL, 1, key);
while ((tuple = systable_getnext(scan)) != NULL)
{
Form_pg_inherits form = (Form_pg_inherits) GETSTRUCT(tuple);
result = lappend_oid(result, form->inhparent);
}
systable_endscan(scan);
return result;
}