Move the HTSU_Result enum definition into snapshot.h, to avoid including
[PostgreSQL.git] / src / backend / catalog / pg_enum.c
blob24a1e8e65363f033835155becbdfd57186944bd9
1 /*-------------------------------------------------------------------------
3 * pg_enum.c
4 * routines to support manipulation of the pg_enum relation
6 * Copyright (c) 2006-2008, PostgreSQL Global Development Group
9 * IDENTIFICATION
10 * $PostgreSQL$
12 *-------------------------------------------------------------------------
14 #include "postgres.h"
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);
29 * EnumValuesCreate
30 * Create an entry in pg_enum for each of the supplied enum values.
32 * vals is a list of Value strings.
34 void
35 EnumValuesCreate(Oid enumTypeOid, List *vals)
37 Relation pg_enum;
38 TupleDesc tupDesc;
39 NameData enumlabel;
40 Oid *oids;
41 int i,
43 Datum values[Natts_pg_enum];
44 char nulls[Natts_pg_enum];
45 ListCell *lc;
46 HeapTuple tup;
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
64 * unlikely.
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));
78 i = 0;
79 foreach(lc, vals)
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))
88 ereport(ERROR,
89 (errcode(ERRCODE_INVALID_NAME),
90 errmsg("invalid enum label \"%s\"", lab),
91 errdetail("Labels must be %d characters or less.",
92 NAMEDATALEN - 1)));
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);
103 heap_freetuple(tup);
105 i++;
108 /* clean up */
109 pfree(oids);
110 heap_close(pg_enum, RowExclusiveLock);
115 * EnumValuesDelete
116 * Remove all the pg_enum entries for the specified enum type.
118 void
119 EnumValuesDelete(Oid enumTypeOid)
121 Relation pg_enum;
122 ScanKeyData key[1];
123 SysScanDesc scan;
124 HeapTuple tup;
126 pg_enum = heap_open(EnumRelationId, RowExclusiveLock);
128 ScanKeyInit(&key[0],
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 */
148 static int
149 oid_cmp(const void *p1, const void *p2)
151 Oid v1 = *((const Oid *) p1);
152 Oid v2 = *((const Oid *) p2);
154 if (v1 < v2)
155 return -1;
156 if (v1 > v2)
157 return 1;
158 return 0;