forked from CartoDB/pg_schema_triggers
-
Notifications
You must be signed in to change notification settings - Fork 0
/
catalog_funcs.c
144 lines (114 loc) · 3.38 KB
/
catalog_funcs.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
* Utility functions for looking up information in the system catalogs which
* is not provided by the catcache/relcache infrastructure.
*
* pg_schema_triggers/catalog_funcs.c
*/
#include "postgres.h"
#include "access/genam.h"
#include "access/heapam.h"
#include "access/htup.h"
#include "access/htup_details.h"
#include "access/sysattr.h"
#include "access/xact.h"
#include "catalog/indexing.h"
#include "catalog/pg_attribute.h"
#include "catalog/pg_class.h"
#include "catalog/pg_trigger.h"
#include "utils/lsyscache.h"
/*
* F_INT2EQ and F_OIDEQ definitions copied from
* backend/utils/fmgroids.h
*/
#define F_INT2EQ 63
#define F_OIDEQ 184
#include "catalog_funcs.h"
HeapTuple catalog_fetch_tuple(Oid relation,
Oid index,
ScanKeyData *keys,
int num_keys,
Snapshot snapshot);
HeapTuple
pgclass_fetch_tuple(Oid reloid, Snapshot snapshot)
{
Oid relation = RelationRelationId;
Oid index = ClassOidIndexId;
ScanKeyData keys[1];
/* Scan key is an Oid. */
ScanKeyInit(&keys[0],
ObjectIdAttributeNumber,
BTEqualStrategyNumber,
F_OIDEQ,
ObjectIdGetDatum(reloid));
return catalog_fetch_tuple(relation, index, keys, 1, snapshot);
}
HeapTuple
pgattribute_fetch_tuple(Oid reloid, int16 attnum, Snapshot snapshot)
{
Oid relation = AttributeRelationId;
Oid index = AttributeRelidNumIndexId;
ScanKeyData keys[2];
ScanKeyInit(&keys[0],
Anum_pg_attribute_attrelid,
BTEqualStrategyNumber,
F_OIDEQ,
ObjectIdGetDatum(reloid));
ScanKeyInit(&keys[1],
Anum_pg_attribute_attnum,
BTEqualStrategyNumber,
F_INT2EQ,
Int16GetDatum(attnum));
return catalog_fetch_tuple(relation, index, keys, 2, snapshot);
}
HeapTuple
pgtrigger_fetch_tuple(Oid trigoid, Snapshot snapshot)
{
Oid relation = TriggerRelationId;
Oid index = TriggerOidIndexId;
ScanKeyData keys[1];
/* Scan key is an Oid. */
ScanKeyInit(&keys[0],
ObjectIdAttributeNumber,
BTEqualStrategyNumber,
F_OIDEQ,
ObjectIdGetDatum(trigoid));
return catalog_fetch_tuple(relation, index, keys, 1, snapshot);
}
/*
* Fetch a tuple from a system catalog given a suitable scan key. The returned
* HeapTuple is suitable for use with HeapTupleGetDatum(), and must be freed by
* calling heap_freetuple().
*/
HeapTuple
catalog_fetch_tuple(Oid relation, Oid index, ScanKeyData *keys, int num_keys, Snapshot snapshot)
{
Relation reldesc;
SysScanDesc relscan;
HeapTuple reltuple;
Oid reltypeid;
/* Get the Oid of the relation's rowtype. */
reltypeid = get_rel_type_id(relation);
if (reltypeid == InvalidOid)
elog(ERROR, "catalog_fetch_tuple: relation %u has no rowtype", relation);
/* Open the catalog relation and fetch a tuple using the given index. */
reldesc = heap_open(relation, AccessShareLock);
relscan = systable_beginscan(reldesc,
index,
true,
snapshot,
num_keys, keys);
reltuple = systable_getnext(relscan);
/* Copy the tuple. */
if (!HeapTupleIsValid(reltuple))
goto finish;
/* Copy the tuple and ensure that the Datum headers are set. */
reltuple = heap_copytuple(reltuple);
HeapTupleHeaderSetDatumLength(reltuple->t_data, reltuple->t_len);
HeapTupleHeaderSetTypeId(reltuple->t_data, reltypeid);
HeapTupleHeaderSetTypMod(reltuple->t_data, -1);
finish:
/* Close the relation and return the copied tuple. */
systable_endscan(relscan);
heap_close(reldesc, AccessShareLock);
return reltuple;
}