1 /*-------------------------------------------------------------------------
4 * routines to support manipulation of the pg_enum relation
6 * Copyright (c) 2006-2008, PostgreSQL Global Development Group
12 *-------------------------------------------------------------------------
16 #include "access/genam.h"
17 #include "access/heapam.h"
18 #include "catalog/catalog.h"
19 #include "catalog/indexing.h"
20 #include "catalog/pg_enum.h"
21 #include "utils/builtins.h"
22 #include "utils/fmgroids.h"
23 #include "utils/tqual.h"
25 static int oid_cmp(const void *p1
, const void *p2
);
30 * Create an entry in pg_enum for each of the supplied enum values.
32 * vals is a list of Value strings.
35 EnumValuesCreate(Oid enumTypeOid
, List
*vals
)
43 Datum values
[Natts_pg_enum
];
44 char nulls
[Natts_pg_enum
];
48 n
= list_length(vals
);
51 * XXX we do not bother to check the list of values for duplicates --- if
52 * you have any, you'll get a less-than-friendly unique-index violation.
53 * Is it worth trying harder?
56 pg_enum
= heap_open(EnumRelationId
, RowExclusiveLock
);
57 tupDesc
= pg_enum
->rd_att
;
60 * Allocate oids. While this method does not absolutely guarantee that we
61 * generate no duplicate oids (since we haven't entered each oid into the
62 * table before allocating the next), trouble could only occur if the oid
63 * counter wraps all the way around before we finish. Which seems
66 oids
= (Oid
*) palloc(n
* sizeof(Oid
));
67 for (i
= 0; i
< n
; i
++)
69 oids
[i
] = GetNewOid(pg_enum
);
72 /* sort them, just in case counter wrapped from high to low */
73 qsort(oids
, n
, sizeof(Oid
), oid_cmp
);
75 /* and make the entries */
76 memset(nulls
, ' ', sizeof(nulls
));
81 char *lab
= strVal(lfirst(lc
));
84 * labels are stored in a name field, for easier syscache lookup, so
85 * check the length to make sure it's within range.
87 if (strlen(lab
) > (NAMEDATALEN
- 1))
89 (errcode(ERRCODE_INVALID_NAME
),
90 errmsg("invalid enum label \"%s\"", lab
),
91 errdetail("Labels must be %d characters or less.",
94 values
[Anum_pg_enum_enumtypid
- 1] = ObjectIdGetDatum(enumTypeOid
);
95 namestrcpy(&enumlabel
, lab
);
96 values
[Anum_pg_enum_enumlabel
- 1] = NameGetDatum(&enumlabel
);
98 tup
= heap_formtuple(tupDesc
, values
, nulls
);
99 HeapTupleSetOid(tup
, oids
[i
]);
101 simple_heap_insert(pg_enum
, tup
);
102 CatalogUpdateIndexes(pg_enum
, tup
);
110 heap_close(pg_enum
, RowExclusiveLock
);
116 * Remove all the pg_enum entries for the specified enum type.
119 EnumValuesDelete(Oid enumTypeOid
)
126 pg_enum
= heap_open(EnumRelationId
, RowExclusiveLock
);
129 Anum_pg_enum_enumtypid
,
130 BTEqualStrategyNumber
, F_OIDEQ
,
131 ObjectIdGetDatum(enumTypeOid
));
133 scan
= systable_beginscan(pg_enum
, EnumTypIdLabelIndexId
, true,
134 SnapshotNow
, 1, key
);
136 while (HeapTupleIsValid(tup
= systable_getnext(scan
)))
138 simple_heap_delete(pg_enum
, &tup
->t_self
);
141 systable_endscan(scan
);
143 heap_close(pg_enum
, RowExclusiveLock
);
147 /* qsort comparison function */
149 oid_cmp(const void *p1
, const void *p2
)
151 Oid v1
= *((const Oid
*) p1
);
152 Oid v2
= *((const Oid
*) p2
);