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-2017, 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"
24 #include "catalog/pg_type.h"
25 #include "libpq/pqformat.h"
26 #include "mb/pg_wchar.h"
27 #include "miscadmin.h"
28 #include "utils/array.h"
29 #include "utils/builtins.h"
30 #include "utils/lsyscache.h"
31 
32 
33 /*****************************************************************************
34  * USER I/O ROUTINES (none) *
35  *****************************************************************************/
36 
37 
38 /*
39  * namein - converts "..." to internal representation
40  *
41  * Note:
42  * [Old] Currently if strlen(s) < NAMEDATALEN, the extra chars are nulls
43  * Now, always NULL terminated
44  */
45 Datum
47 {
48  char *s = PG_GETARG_CSTRING(0);
49  Name result;
50  int len;
51 
52  len = strlen(s);
53 
54  /* Truncate oversize input */
55  if (len >= NAMEDATALEN)
56  len = pg_mbcliplen(s, len, NAMEDATALEN - 1);
57 
58  /* We use palloc0 here to ensure result is zero-padded */
59  result = (Name) palloc0(NAMEDATALEN);
60  memcpy(NameStr(*result), s, len);
61 
62  PG_RETURN_NAME(result);
63 }
64 
65 /*
66  * nameout - converts internal representation to "..."
67  */
68 Datum
70 {
71  Name s = PG_GETARG_NAME(0);
72 
74 }
75 
76 /*
77  * namerecv - converts external binary format to name
78  */
79 Datum
81 {
83  Name result;
84  char *str;
85  int nbytes;
86 
87  str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
88  if (nbytes >= NAMEDATALEN)
89  ereport(ERROR,
90  (errcode(ERRCODE_NAME_TOO_LONG),
91  errmsg("identifier too long"),
92  errdetail("Identifier must be less than %d characters.",
93  NAMEDATALEN)));
94  result = (NameData *) palloc0(NAMEDATALEN);
95  memcpy(result, str, nbytes);
96  pfree(str);
97  PG_RETURN_NAME(result);
98 }
99 
100 /*
101  * namesend - converts name to binary format
102  */
103 Datum
105 {
106  Name s = PG_GETARG_NAME(0);
108 
109  pq_begintypsend(&buf);
110  pq_sendtext(&buf, NameStr(*s), strlen(NameStr(*s)));
112 }
113 
114 
115 /*****************************************************************************
116  * PUBLIC ROUTINES *
117  *****************************************************************************/
118 
119 /*
120  * nameeq - returns 1 iff arguments are equal
121  * namene - returns 1 iff arguments are not equal
122  *
123  * BUGS:
124  * Assumes that "xy\0\0a" should be equal to "xy\0b".
125  * If not, can do the comparison backwards for efficiency.
126  *
127  * namelt - returns 1 iff a < b
128  * namele - returns 1 iff a <= b
129  * namegt - returns 1 iff a > b
130  * namege - returns 1 iff a >= b
131  *
132  */
133 Datum
135 {
136  Name arg1 = PG_GETARG_NAME(0);
137  Name arg2 = PG_GETARG_NAME(1);
138 
139  PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) == 0);
140 }
141 
142 Datum
144 {
145  Name arg1 = PG_GETARG_NAME(0);
146  Name arg2 = PG_GETARG_NAME(1);
147 
148  PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) != 0);
149 }
150 
151 Datum
153 {
154  Name arg1 = PG_GETARG_NAME(0);
155  Name arg2 = PG_GETARG_NAME(1);
156 
157  PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) < 0);
158 }
159 
160 Datum
162 {
163  Name arg1 = PG_GETARG_NAME(0);
164  Name arg2 = PG_GETARG_NAME(1);
165 
166  PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) <= 0);
167 }
168 
169 Datum
171 {
172  Name arg1 = PG_GETARG_NAME(0);
173  Name arg2 = PG_GETARG_NAME(1);
174 
175  PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) > 0);
176 }
177 
178 Datum
180 {
181  Name arg1 = PG_GETARG_NAME(0);
182  Name arg2 = PG_GETARG_NAME(1);
183 
184  PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) >= 0);
185 }
186 
187 
188 /* (see char.c for comparison/operation routines) */
189 
190 int
192 {
193  if (!n1 || !n2)
194  return -1;
195  StrNCpy(NameStr(*n1), NameStr(*n2), NAMEDATALEN);
196  return 0;
197 }
198 
199 #ifdef NOT_USED
200 int
201 namecat(Name n1, Name n2)
202 {
203  return namestrcat(n1, NameStr(*n2)); /* n2 can't be any longer than n1 */
204 }
205 #endif
206 
207 #ifdef NOT_USED
208 int
209 namecmp(Name n1, Name n2)
210 {
211  return strncmp(NameStr(*n1), NameStr(*n2), NAMEDATALEN);
212 }
213 #endif
214 
215 int
216 namestrcpy(Name name, const char *str)
217 {
218  if (!name || !str)
219  return -1;
220  StrNCpy(NameStr(*name), str, NAMEDATALEN);
221  return 0;
222 }
223 
224 #ifdef NOT_USED
225 int
226 namestrcat(Name name, const char *str)
227 {
228  int i;
229  char *p,
230  *q;
231 
232  if (!name || !str)
233  return -1;
234  for (i = 0, p = NameStr(*name); i < NAMEDATALEN && *p; ++i, ++p)
235  ;
236  for (q = str; i < NAMEDATALEN; ++i, ++p, ++q)
237  {
238  *p = *q;
239  if (!*q)
240  break;
241  }
242  return 0;
243 }
244 #endif
245 
246 int
247 namestrcmp(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  */
262 Datum
264 {
266 }
267 
268 Datum
270 {
272 }
273 
274 
275 /*
276  * SQL-functions CURRENT_SCHEMA, CURRENT_SCHEMAS
277  */
278 Datum
280 {
281  List *search_path = fetch_search_path(false);
282  char *nspname;
283 
284  if (search_path == NIL)
285  PG_RETURN_NULL();
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 
293 Datum
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(names, i,
318  NAMEOID,
319  NAMEDATALEN, /* sizeof(Name) */
320  false, /* Name is not by-val */
321  'c'); /* alignment of Name */
322 
323  PG_RETURN_POINTER(array);
324 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:321
int namecpy(Name n1, Name n2)
Definition: name.c:191
#define NIL
Definition: pg_list.h:69
Datum namein(PG_FUNCTION_ARGS)
Definition: name.c:46
#define NAMEOID
Definition: pg_type.h:300
Datum current_schema(PG_FUNCTION_ARGS)
Definition: name.c:279
Datum namene(PG_FUNCTION_ARGS)
Definition: name.c:143
Oid GetUserId(void)
Definition: miscinit.c:284
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:328
char * pstrdup(const char *in)
Definition: mcxt.c:1076
StringInfoData * StringInfo
Definition: stringinfo.h:43
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3279
int errcode(int sqlerrcode)
Definition: elog.c:575
int namestrcmp(Name name, const char *str)
Definition: name.c:247
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:174
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:585
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:239
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:330
int namestrcpy(Name name, const char *str)
Definition: name.c:216
Datum namege(PG_FUNCTION_ARGS)
Definition: name.c:179
Datum namelt(PG_FUNCTION_ARGS)
Definition: name.c:152
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:348
Oid GetSessionUserId(void)
Definition: miscinit.c:318
Datum namesend(PG_FUNCTION_ARGS)
Definition: name.c:104
#define NAMEDATALEN
void pfree(void *pointer)
Definition: mcxt.c:949
#define ERROR
Definition: elog.h:43
int pg_mbcliplen(const char *mbstr, int len, int limit)
Definition: mbutils.c:820
Definition: c.h:541
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3047
static char * buf
Definition: pg_test_fsync.c:67
Datum current_user(PG_FUNCTION_ARGS)
Definition: name.c:263
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define CStringGetDatum(X)
Definition: postgres.h:584
Datum current_schemas(PG_FUNCTION_ARGS)
Definition: name.c:294
#define ereport(elevel, rest)
Definition: elog.h:122
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition: pqformat.c:548
Datum namegt(PG_FUNCTION_ARGS)
Definition: name.c:170
Datum session_user(PG_FUNCTION_ARGS)
Definition: name.c:269
void * palloc0(Size size)
Definition: mcxt.c:877
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
uintptr_t Datum
Definition: postgres.h:372
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:313
Datum namerecv(PG_FUNCTION_ARGS)
Definition: name.c:80
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition: miscinit.c:692
#define StrNCpy(dst, src, len)
Definition: c.h:826
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:322
#define linitial_oid(l)
Definition: pg_list.h:113
static int list_length(const List *l)
Definition: pg_list.h:89
const char * name
Definition: encode.c:521
Datum namele(PG_FUNCTION_ARGS)
Definition: name.c:161
void * palloc(Size size)
Definition: mcxt.c:848
int errmsg(const char *fmt,...)
Definition: elog.c:797
void list_free(List *list)
Definition: list.c:1133
int i
#define NameStr(name)
Definition: c.h:547
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:242
#define PG_FUNCTION_ARGS
Definition: fmgr.h:158
Datum nameout(PG_FUNCTION_ARGS)
Definition: name.c:69
NameData * Name
Definition: c.h:545
Definition: pg_list.h:45
List * fetch_search_path(bool includeImplicit)
Definition: namespace.c:4168
#define PG_RETURN_NULL()
Definition: fmgr.h:305
#define PG_RETURN_NAME(x)
Definition: fmgr.h:323
#define PG_GETARG_NAME(n)
Definition: fmgr.h:243
#define lfirst_oid(lc)
Definition: pg_list.h:108
Datum nameeq(PG_FUNCTION_ARGS)
Definition: name.c:134