53{
58 bool nulls[Natts_pg_collation];
62 referenced;
63
67 Assert((collprovider == COLLPROVIDER_LIBC &&
68 collcollate && collctype && !colllocale) ||
69 (collprovider != COLLPROVIDER_LIBC &&
70 !collcollate && !collctype && colllocale));
71
72 /*
73 * Make sure there is no existing collation of same name & encoding.
74 *
75 * This would be caught by the unique index anyway; we're just giving a
76 * friendlier error message. The unique index provides a backstop against
77 * race conditions.
78 */
80 Anum_pg_collation_oid,
85 {
86 if (quiet)
88 else if (if_not_exists)
89 {
90 /*
91 * If we are in an extension script, insist that the pre-existing
92 * object be a member of the extension, to avoid security risks.
93 */
96
97 /* OK to skip */
100 collencoding == -1
101 ?
errmsg(
"collation \"%s\" already exists, skipping",
102 collname)
103 :
errmsg(
"collation \"%s\" for encoding \"%s\" already exists, skipping",
106 }
107 else
110 collencoding == -1
111 ?
errmsg(
"collation \"%s\" already exists",
112 collname)
113 :
errmsg(
"collation \"%s\" for encoding \"%s\" already exists",
115 }
116
117 /* open pg_collation; see below about the lock level */
119
120 /*
121 * Also forbid a specific-encoding collation shadowing an any-encoding
122 * collation, or an any-encoding collation being shadowed (see
123 * get_collation_name()). This test is not backed up by the unique index,
124 * so we take a ShareRowExclusiveLock earlier, to protect against
125 * concurrent changes fooling this check.
126 */
127 if (collencoding == -1)
129 Anum_pg_collation_oid,
133 else
135 Anum_pg_collation_oid,
140 {
141 if (quiet)
142 {
145 }
146 else if (if_not_exists)
147 {
148 /*
149 * If we are in an extension script, insist that the pre-existing
150 * object be a member of the extension, to avoid security risks.
151 */
154
155 /* OK to skip */
159 errmsg(
"collation \"%s\" already exists, skipping",
160 collname)));
162 }
163 else
166 errmsg(
"collation \"%s\" already exists",
167 collname)));
168 }
169
171
172 /* form a tuple */
173 memset(nulls, 0, sizeof(nulls));
174
177 Anum_pg_collation_oid);
183 values[Anum_pg_collation_collisdeterministic - 1] =
BoolGetDatum(collisdeterministic);
185 if (collcollate)
187 else
188 nulls[Anum_pg_collation_collcollate - 1] = true;
189 if (collctype)
191 else
192 nulls[Anum_pg_collation_collctype - 1] = true;
193 if (colllocale)
195 else
196 nulls[Anum_pg_collation_colllocale - 1] = true;
197 if (collicurules)
199 else
200 nulls[Anum_pg_collation_collicurules - 1] = true;
201 if (collversion)
203 else
204 nulls[Anum_pg_collation_collversion - 1] = true;
205
207
208 /* insert a new tuple */
211
212 /* set up dependencies for the new collation */
213 myself.
classId = CollationRelationId;
216
217 /* create dependency on namespace */
218 referenced.
classId = NamespaceRelationId;
219 referenced.
objectId = collnamespace;
222
223 /* create dependency on owner */
225
226 /* dependency on extension */
228
229 /* Post creation hook for new collation */
231
234
235 return oid;
236}
static Datum values[MAXATTR]
#define CStringGetTextDatum(s)
#define OidIsValid(objectId)
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
Assert(PointerIsAligned(start, uint64))
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
void heap_freetuple(HeapTuple htup)
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
#define ShareRowExclusiveLock
int GetDatabaseEncoding(void)
void namestrcpy(Name name, const char *str)
#define InvokeObjectPostCreateHook(classId, objectId, subId)
#define ObjectAddressSet(addr, class_id, object_id)
void checkMembershipInCurrentExtension(const ObjectAddress *object)
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
#define pg_encoding_to_char
static Datum PointerGetDatum(const void *X)
static Datum BoolGetDatum(bool X)
static Datum ObjectIdGetDatum(Oid X)
static Datum NameGetDatum(const NameData *X)
static Datum Int32GetDatum(int32 X)
static Datum CharGetDatum(char X)
#define RelationGetDescr(relation)
#define ERRCODE_DUPLICATE_OBJECT
#define GetSysCacheOid3(cacheId, oidcol, key1, key2, key3)
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)