/*------------------------------------------------------------------------- * * pg_range.c * routines to support manipulation of the pg_range relation * * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION * src/backend/catalog/pg_range.c * *------------------------------------------------------------------------- */ #include "postgres.h" #include "access/genam.h" #include "access/htup_details.h" #include "access/table.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/pg_collation.h" #include "catalog/pg_opclass.h" #include "catalog/pg_proc.h" #include "catalog/pg_range.h" #include "catalog/pg_type.h" #include "utils/fmgroids.h" #include "utils/rel.h" /* * RangeCreate * Create an entry in pg_range. */ void RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation, Oid rangeSubOpclass, RegProcedure rangeCanonical, RegProcedure rangeSubDiff, Oid multirangeTypeOid) { Relation pg_range; Datum values[Natts_pg_range]; bool nulls[Natts_pg_range]; HeapTuple tup; ObjectAddress myself; ObjectAddress referenced; ObjectAddress referencing; ObjectAddresses *addrs; pg_range = table_open(RangeRelationId, RowExclusiveLock); memset(nulls, 0, sizeof(nulls)); values[Anum_pg_range_rngtypid - 1] = ObjectIdGetDatum(rangeTypeOid); values[Anum_pg_range_rngsubtype - 1] = ObjectIdGetDatum(rangeSubType); values[Anum_pg_range_rngcollation - 1] = ObjectIdGetDatum(rangeCollation); values[Anum_pg_range_rngsubopc - 1] = ObjectIdGetDatum(rangeSubOpclass); values[Anum_pg_range_rngcanonical - 1] = ObjectIdGetDatum(rangeCanonical); values[Anum_pg_range_rngsubdiff - 1] = ObjectIdGetDatum(rangeSubDiff); values[Anum_pg_range_rngmultitypid - 1] = ObjectIdGetDatum(multirangeTypeOid); tup = heap_form_tuple(RelationGetDescr(pg_range), values, nulls); CatalogTupleInsert(pg_range, tup); heap_freetuple(tup); /* record type's dependencies on range-related items */ addrs = new_object_addresses(); ObjectAddressSet(myself, TypeRelationId, rangeTypeOid); ObjectAddressSet(referenced, TypeRelationId, rangeSubType); add_exact_object_address(&referenced, addrs); ObjectAddressSet(referenced, OperatorClassRelationId, rangeSubOpclass); add_exact_object_address(&referenced, addrs); if (OidIsValid(rangeCollation)) { ObjectAddressSet(referenced, CollationRelationId, rangeCollation); add_exact_object_address(&referenced, addrs); } if (OidIsValid(rangeCanonical)) { ObjectAddressSet(referenced, ProcedureRelationId, rangeCanonical); add_exact_object_address(&referenced, addrs); } if (OidIsValid(rangeSubDiff)) { ObjectAddressSet(referenced, ProcedureRelationId, rangeSubDiff); add_exact_object_address(&referenced, addrs); } record_object_address_dependencies(&myself, addrs, DEPENDENCY_NORMAL); free_object_addresses(addrs); /* record multirange type's dependency on the range type */ referencing.classId = TypeRelationId; referencing.objectId = multirangeTypeOid; referencing.objectSubId = 0; recordDependencyOn(&referencing, &myself, DEPENDENCY_INTERNAL); table_close(pg_range, RowExclusiveLock); } /* * RangeDelete * Remove the pg_range entry for the specified type. */ void RangeDelete(Oid rangeTypeOid) { Relation pg_range; ScanKeyData key[1]; SysScanDesc scan; HeapTuple tup; pg_range = table_open(RangeRelationId, RowExclusiveLock); ScanKeyInit(&key[0], Anum_pg_range_rngtypid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(rangeTypeOid)); scan = systable_beginscan(pg_range, RangeTypidIndexId, true, NULL, 1, key); while (HeapTupleIsValid(tup = systable_getnext(scan))) { CatalogTupleDelete(pg_range, &tup->t_self); } systable_endscan(scan); table_close(pg_range, RowExclusiveLock); }