Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * pg_range.c
4 : * routines to support manipulation of the pg_range relation
5 : *
6 : * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 : * Portions Copyright (c) 1994, Regents of the University of California
8 : *
9 : *
10 : * IDENTIFICATION
11 : * src/backend/catalog/pg_range.c
12 : *
13 : *-------------------------------------------------------------------------
14 : */
15 : #include "postgres.h"
16 :
17 : #include "access/genam.h"
18 : #include "access/htup_details.h"
19 : #include "access/table.h"
20 : #include "catalog/dependency.h"
21 : #include "catalog/indexing.h"
22 : #include "catalog/pg_collation.h"
23 : #include "catalog/pg_opclass.h"
24 : #include "catalog/pg_proc.h"
25 : #include "catalog/pg_range.h"
26 : #include "catalog/pg_type.h"
27 : #include "utils/fmgroids.h"
28 : #include "utils/rel.h"
29 :
30 :
31 : /*
32 : * RangeCreate
33 : * Create an entry in pg_range.
34 : */
35 : void
36 160 : RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation,
37 : Oid rangeSubOpclass, RegProcedure rangeCanonical,
38 : RegProcedure rangeSubDiff, Oid multirangeTypeOid,
39 : RegProcedure rangeConstruct2, RegProcedure rangeConstruct3,
40 : RegProcedure mltrngConstruct0, RegProcedure mltrngConstruct1, RegProcedure mltrngConstruct2)
41 : {
42 : Relation pg_range;
43 : Datum values[Natts_pg_range];
44 : bool nulls[Natts_pg_range];
45 : HeapTuple tup;
46 : ObjectAddress myself;
47 : ObjectAddress referenced;
48 : ObjectAddress referencing;
49 : ObjectAddresses *addrs;
50 :
51 160 : pg_range = table_open(RangeRelationId, RowExclusiveLock);
52 :
53 160 : memset(nulls, 0, sizeof(nulls));
54 :
55 160 : values[Anum_pg_range_rngtypid - 1] = ObjectIdGetDatum(rangeTypeOid);
56 160 : values[Anum_pg_range_rngsubtype - 1] = ObjectIdGetDatum(rangeSubType);
57 160 : values[Anum_pg_range_rngcollation - 1] = ObjectIdGetDatum(rangeCollation);
58 160 : values[Anum_pg_range_rngsubopc - 1] = ObjectIdGetDatum(rangeSubOpclass);
59 160 : values[Anum_pg_range_rngcanonical - 1] = ObjectIdGetDatum(rangeCanonical);
60 160 : values[Anum_pg_range_rngsubdiff - 1] = ObjectIdGetDatum(rangeSubDiff);
61 160 : values[Anum_pg_range_rngmultitypid - 1] = ObjectIdGetDatum(multirangeTypeOid);
62 160 : values[Anum_pg_range_rngconstruct2 - 1] = ObjectIdGetDatum(rangeConstruct2);
63 160 : values[Anum_pg_range_rngconstruct3 - 1] = ObjectIdGetDatum(rangeConstruct3);
64 160 : values[Anum_pg_range_rngmltconstruct0 - 1] = ObjectIdGetDatum(mltrngConstruct0);
65 160 : values[Anum_pg_range_rngmltconstruct1 - 1] = ObjectIdGetDatum(mltrngConstruct1);
66 160 : values[Anum_pg_range_rngmltconstruct2 - 1] = ObjectIdGetDatum(mltrngConstruct2);
67 :
68 160 : tup = heap_form_tuple(RelationGetDescr(pg_range), values, nulls);
69 :
70 160 : CatalogTupleInsert(pg_range, tup);
71 160 : heap_freetuple(tup);
72 :
73 : /* record type's dependencies on range-related items */
74 160 : addrs = new_object_addresses();
75 :
76 160 : ObjectAddressSet(myself, TypeRelationId, rangeTypeOid);
77 :
78 160 : ObjectAddressSet(referenced, TypeRelationId, rangeSubType);
79 160 : add_exact_object_address(&referenced, addrs);
80 :
81 160 : ObjectAddressSet(referenced, OperatorClassRelationId, rangeSubOpclass);
82 160 : add_exact_object_address(&referenced, addrs);
83 :
84 160 : if (OidIsValid(rangeCollation))
85 : {
86 72 : ObjectAddressSet(referenced, CollationRelationId, rangeCollation);
87 72 : add_exact_object_address(&referenced, addrs);
88 : }
89 :
90 160 : if (OidIsValid(rangeCanonical))
91 : {
92 0 : ObjectAddressSet(referenced, ProcedureRelationId, rangeCanonical);
93 0 : add_exact_object_address(&referenced, addrs);
94 : }
95 :
96 160 : if (OidIsValid(rangeSubDiff))
97 : {
98 8 : ObjectAddressSet(referenced, ProcedureRelationId, rangeSubDiff);
99 8 : add_exact_object_address(&referenced, addrs);
100 : }
101 :
102 160 : record_object_address_dependencies(&myself, addrs, DEPENDENCY_NORMAL);
103 160 : free_object_addresses(addrs);
104 :
105 : /* record multirange type's dependency on the range type */
106 160 : referencing.classId = TypeRelationId;
107 160 : referencing.objectId = multirangeTypeOid;
108 160 : referencing.objectSubId = 0;
109 160 : recordDependencyOn(&referencing, &myself, DEPENDENCY_INTERNAL);
110 :
111 160 : table_close(pg_range, RowExclusiveLock);
112 160 : }
113 :
114 :
115 : /*
116 : * RangeDelete
117 : * Remove the pg_range entry for the specified type.
118 : */
119 : void
120 104 : RangeDelete(Oid rangeTypeOid)
121 : {
122 : Relation pg_range;
123 : ScanKeyData key[1];
124 : SysScanDesc scan;
125 : HeapTuple tup;
126 :
127 104 : pg_range = table_open(RangeRelationId, RowExclusiveLock);
128 :
129 104 : ScanKeyInit(&key[0],
130 : Anum_pg_range_rngtypid,
131 : BTEqualStrategyNumber, F_OIDEQ,
132 : ObjectIdGetDatum(rangeTypeOid));
133 :
134 104 : scan = systable_beginscan(pg_range, RangeTypidIndexId, true,
135 : NULL, 1, key);
136 :
137 208 : while (HeapTupleIsValid(tup = systable_getnext(scan)))
138 : {
139 104 : CatalogTupleDelete(pg_range, &tup->t_self);
140 : }
141 :
142 104 : systable_endscan(scan);
143 :
144 104 : table_close(pg_range, RowExclusiveLock);
145 104 : }
|