PostgreSQL Source Code git master
name.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * name.c
4 * Functions for the built-in type "name".
5 *
6 * name replaces char16 and is carefully implemented so that it
7 * is a string of physical length NAMEDATALEN.
8 * DO NOT use hard-coded constants anywhere
9 * always use NAMEDATALEN as the symbolic constant! - jolly 8/21/95
10 *
11 *
12 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
13 * Portions Copyright (c) 1994, Regents of the University of California
14 *
15 *
16 * IDENTIFICATION
17 * src/backend/utils/adt/name.c
18 *
19 *-------------------------------------------------------------------------
20 */
21#include "postgres.h"
22
23#include "catalog/namespace.h"
25#include "catalog/pg_type.h"
26#include "libpq/pqformat.h"
27#include "mb/pg_wchar.h"
28#include "miscadmin.h"
29#include "utils/array.h"
30#include "utils/builtins.h"
31#include "utils/lsyscache.h"
32#include "utils/varlena.h"
33
34
35/*****************************************************************************
36 * USER I/O ROUTINES (none) *
37 *****************************************************************************/
38
39
40/*
41 * namein - converts cstring to internal representation
42 *
43 * Note:
44 * [Old] Currently if strlen(s) < NAMEDATALEN, the extra chars are nulls
45 * Now, always NULL terminated
46 */
49{
50 char *s = PG_GETARG_CSTRING(0);
51 Name result;
52 int len;
53
54 len = strlen(s);
55
56 /* Truncate oversize input */
57 if (len >= NAMEDATALEN)
59
60 /* We use palloc0 here to ensure result is zero-padded */
61 result = (Name) palloc0(NAMEDATALEN);
62 memcpy(NameStr(*result), s, len);
63
64 PG_RETURN_NAME(result);
65}
66
67/*
68 * nameout - converts internal representation to cstring
69 */
72{
73 Name s = PG_GETARG_NAME(0);
74
76}
77
78/*
79 * namerecv - converts external binary format to name
80 */
83{
85 Name result;
86 char *str;
87 int nbytes;
88
89 str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
90 if (nbytes >= NAMEDATALEN)
92 (errcode(ERRCODE_NAME_TOO_LONG),
93 errmsg("identifier too long"),
94 errdetail("Identifier must be less than %d characters.",
95 NAMEDATALEN)));
96 result = (NameData *) palloc0(NAMEDATALEN);
97 memcpy(result, str, nbytes);
98 pfree(str);
99 PG_RETURN_NAME(result);
100}
101
102/*
103 * namesend - converts name to binary format
104 */
105Datum
107{
108 Name s = PG_GETARG_NAME(0);
110
112 pq_sendtext(&buf, NameStr(*s), strlen(NameStr(*s)));
114}
115
116
117/*****************************************************************************
118 * COMPARISON/SORTING ROUTINES *
119 *****************************************************************************/
120
121/*
122 * nameeq - returns 1 iff arguments are equal
123 * namene - returns 1 iff arguments are not equal
124 * namelt - returns 1 iff a < b
125 * namele - returns 1 iff a <= b
126 * namegt - returns 1 iff a > b
127 * namege - returns 1 iff a >= b
128 *
129 * Note that the use of strncmp with NAMEDATALEN limit is mostly historical;
130 * strcmp would do as well, because we do not allow NAME values that don't
131 * have a '\0' terminator. Whatever might be past the terminator is not
132 * considered relevant to comparisons.
133 */
134static int
136{
137 /* Fast path for common case used in system catalogs */
138 if (collid == C_COLLATION_OID)
139 return strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN);
140
141 /* Else rely on the varstr infrastructure */
142 return varstr_cmp(NameStr(*arg1), strlen(NameStr(*arg1)),
143 NameStr(*arg2), strlen(NameStr(*arg2)),
144 collid);
145}
146
147Datum
149{
150 Name arg1 = PG_GETARG_NAME(0);
151 Name arg2 = PG_GETARG_NAME(1);
152
153 PG_RETURN_BOOL(namecmp(arg1, arg2, PG_GET_COLLATION()) == 0);
154}
155
156Datum
158{
159 Name arg1 = PG_GETARG_NAME(0);
160 Name arg2 = PG_GETARG_NAME(1);
161
162 PG_RETURN_BOOL(namecmp(arg1, arg2, PG_GET_COLLATION()) != 0);
163}
164
165Datum
167{
168 Name arg1 = PG_GETARG_NAME(0);
169 Name arg2 = PG_GETARG_NAME(1);
170
171 PG_RETURN_BOOL(namecmp(arg1, arg2, PG_GET_COLLATION()) < 0);
172}
173
174Datum
176{
177 Name arg1 = PG_GETARG_NAME(0);
178 Name arg2 = PG_GETARG_NAME(1);
179
180 PG_RETURN_BOOL(namecmp(arg1, arg2, PG_GET_COLLATION()) <= 0);
181}
182
183Datum
185{
186 Name arg1 = PG_GETARG_NAME(0);
187 Name arg2 = PG_GETARG_NAME(1);
188
189 PG_RETURN_BOOL(namecmp(arg1, arg2, PG_GET_COLLATION()) > 0);
190}
191
192Datum
194{
195 Name arg1 = PG_GETARG_NAME(0);
196 Name arg2 = PG_GETARG_NAME(1);
197
198 PG_RETURN_BOOL(namecmp(arg1, arg2, PG_GET_COLLATION()) >= 0);
199}
200
201Datum
203{
204 Name arg1 = PG_GETARG_NAME(0);
205 Name arg2 = PG_GETARG_NAME(1);
206
208}
209
210Datum
212{
214 Oid collid = ssup->ssup_collation;
215 MemoryContext oldcontext;
216
217 oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
218
219 /* Use generic string SortSupport */
220 varstr_sortsupport(ssup, NAMEOID, collid);
221
222 MemoryContextSwitchTo(oldcontext);
223
225}
226
227
228/*****************************************************************************
229 * MISCELLANEOUS PUBLIC ROUTINES *
230 *****************************************************************************/
231
232void
233namestrcpy(Name name, const char *str)
234{
235 /* NB: We need to zero-pad the destination. */
236 strncpy(NameStr(*name), str, NAMEDATALEN);
237 NameStr(*name)[NAMEDATALEN - 1] = '\0';
238}
239
240/*
241 * Compare a NAME to a C string
242 *
243 * Assumes C collation always; be careful when using this for
244 * anything but equality checks!
245 */
246int
247namestrcmp(Name name, const char *str)
248{
249 if (!name && !str)
250 return 0;
251 if (!name)
252 return -1; /* NULL < anything */
253 if (!str)
254 return 1; /* NULL < anything */
255 return strncmp(NameStr(*name), str, NAMEDATALEN);
256}
257
258
259/*
260 * SQL-functions CURRENT_USER, SESSION_USER
261 */
262Datum
264{
266}
267
268Datum
270{
272}
273
274
275/*
276 * SQL-functions CURRENT_SCHEMA, CURRENT_SCHEMAS
277 */
278Datum
280{
281 List *search_path = fetch_search_path(false);
282 char *nspname;
283
284 if (search_path == NIL)
286 nspname = get_namespace_name(linitial_oid(search_path));
287 list_free(search_path);
288 if (!nspname)
289 PG_RETURN_NULL(); /* recently-deleted namespace? */
291}
292
293Datum
295{
296 List *search_path = fetch_search_path(PG_GETARG_BOOL(0));
297 ListCell *l;
298 Datum *names;
299 int i;
300 ArrayType *array;
301
302 names = (Datum *) palloc(list_length(search_path) * sizeof(Datum));
303 i = 0;
304 foreach(l, search_path)
305 {
306 char *nspname;
307
308 nspname = get_namespace_name(lfirst_oid(l));
309 if (nspname) /* watch out for deleted namespace */
310 {
311 names[i] = DirectFunctionCall1(namein, CStringGetDatum(nspname));
312 i++;
313 }
314 }
315 list_free(search_path);
316
317 array = construct_array_builtin(names, i, NAMEOID);
318
319 PG_RETURN_POINTER(array);
320}
321
322/*
323 * SQL-function nameconcatoid(name, oid) returns name
324 *
325 * This is used in the information_schema to produce specific_name columns,
326 * which are supposed to be unique per schema. We achieve that (in an ugly
327 * way) by appending the object's OID. The result is the same as
328 * ($1::text || '_' || $2::text)::name
329 * except that, if it would not fit in NAMEDATALEN, we make it do so by
330 * truncating the name input (not the oid).
331 */
332Datum
334{
335 Name nam = PG_GETARG_NAME(0);
336 Oid oid = PG_GETARG_OID(1);
337 Name result;
338 char suffix[20];
339 int suflen;
340 int namlen;
341
342 suflen = snprintf(suffix, sizeof(suffix), "_%u", oid);
343 namlen = strlen(NameStr(*nam));
344
345 /* Truncate oversize input by truncating name part, not suffix */
346 if (namlen + suflen >= NAMEDATALEN)
347 namlen = pg_mbcliplen(NameStr(*nam), namlen, NAMEDATALEN - 1 - suflen);
348
349 /* We use palloc0 here to ensure result is zero-padded */
350 result = (Name) palloc0(NAMEDATALEN);
351 memcpy(NameStr(*result), NameStr(*nam), namlen);
352 memcpy(NameStr(*result) + namlen, suffix, suflen);
353
354 PG_RETURN_NAME(result);
355}
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
Definition: arrayfuncs.c:3381
#define NameStr(name)
Definition: c.h:703
NameData * Name
Definition: c.h:701
Oid collid
int errdetail(const char *fmt,...)
Definition: elog.c:1203
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:641
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_GETARG_NAME(n)
Definition: fmgr.h:278
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
#define PG_RETURN_NAME(x)
Definition: fmgr.h:363
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define PG_GET_COLLATION()
Definition: fmgr.h:198
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
const char * str
int i
Definition: isn.c:72
void list_free(List *list)
Definition: list.c:1546
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3393
int pg_mbcliplen(const char *mbstr, int len, int limit)
Definition: mbutils.c:1083
char * pstrdup(const char *in)
Definition: mcxt.c:1696
void pfree(void *pointer)
Definition: mcxt.c:1521
void * palloc0(Size size)
Definition: mcxt.c:1347
void * palloc(Size size)
Definition: mcxt.c:1317
Oid GetUserId(void)
Definition: miscinit.c:517
Oid GetSessionUserId(void)
Definition: miscinit.c:556
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition: miscinit.c:1036
Datum nameout(PG_FUNCTION_ARGS)
Definition: name.c:71
Datum nameeq(PG_FUNCTION_ARGS)
Definition: name.c:148
Datum nameconcatoid(PG_FUNCTION_ARGS)
Definition: name.c:333
Datum btnamecmp(PG_FUNCTION_ARGS)
Definition: name.c:202
Datum current_user(PG_FUNCTION_ARGS)
Definition: name.c:263
Datum btnamesortsupport(PG_FUNCTION_ARGS)
Definition: name.c:211
int namestrcmp(Name name, const char *str)
Definition: name.c:247
Datum namele(PG_FUNCTION_ARGS)
Definition: name.c:175
Datum namerecv(PG_FUNCTION_ARGS)
Definition: name.c:82
Datum namegt(PG_FUNCTION_ARGS)
Definition: name.c:184
void namestrcpy(Name name, const char *str)
Definition: name.c:233
Datum session_user(PG_FUNCTION_ARGS)
Definition: name.c:269
Datum namelt(PG_FUNCTION_ARGS)
Definition: name.c:166
Datum namein(PG_FUNCTION_ARGS)
Definition: name.c:48
Datum current_schema(PG_FUNCTION_ARGS)
Definition: name.c:279
Datum namege(PG_FUNCTION_ARGS)
Definition: name.c:193
static int namecmp(Name arg1, Name arg2, Oid collid)
Definition: name.c:135
Datum namesend(PG_FUNCTION_ARGS)
Definition: name.c:106
Datum current_schemas(PG_FUNCTION_ARGS)
Definition: name.c:294
Datum namene(PG_FUNCTION_ARGS)
Definition: name.c:157
List * fetch_search_path(bool includeImplicit)
Definition: namespace.c:4819
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
#define NAMEDATALEN
const void size_t len
static int list_length(const List *l)
Definition: pg_list.h:152
#define NIL
Definition: pg_list.h:68
#define linitial_oid(l)
Definition: pg_list.h:180
#define lfirst_oid(lc)
Definition: pg_list.h:174
static char * buf
Definition: pg_test_fsync.c:72
#define snprintf
Definition: port.h:239
uintptr_t Datum
Definition: postgres.h:69
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:355
unsigned int Oid
Definition: postgres_ext.h:32
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:172
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition: pqformat.c:546
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:326
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:346
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
StringInfoData * StringInfo
Definition: stringinfo.h:54
Definition: pg_list.h:54
MemoryContext ssup_cxt
Definition: sortsupport.h:66
Definition: c.h:698
int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid)
Definition: varlena.c:1538
void varstr_sortsupport(SortSupport ssup, Oid typid, Oid collid)
Definition: varlena.c:1856
const char * name