PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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
204  * n1 */
205 }
206 #endif
207 
208 #ifdef NOT_USED
209 int
210 namecmp(Name n1, Name n2)
211 {
212  return strncmp(NameStr(*n1), NameStr(*n2), NAMEDATALEN);
213 }
214 #endif
215 
216 int
217 namestrcpy(Name name, const char *str)
218 {
219  if (!name || !str)
220  return -1;
221  StrNCpy(NameStr(*name), str, NAMEDATALEN);
222  return 0;
223 }
224 
225 #ifdef NOT_USED
226 int
227 namestrcat(Name name, const char *str)
228 {
229  int i;
230  char *p,
231  *q;
232 
233  if (!name || !str)
234  return -1;
235  for (i = 0, p = NameStr(*name); i < NAMEDATALEN && *p; ++i, ++p)
236  ;
237  for (q = str; i < NAMEDATALEN; ++i, ++p, ++q)
238  {
239  *p = *q;
240  if (!*q)
241  break;
242  }
243  return 0;
244 }
245 #endif
246 
247 int
248 namestrcmp(Name name, const char *str)
249 {
250  if (!name && !str)
251  return 0;
252  if (!name)
253  return -1; /* NULL < anything */
254  if (!str)
255  return 1; /* NULL < anything */
256  return strncmp(NameStr(*name), str, NAMEDATALEN);
257 }
258 
259 
260 /*
261  * SQL-functions CURRENT_USER, SESSION_USER
262  */
263 Datum
265 {
267 }
268 
269 Datum
271 {
273 }
274 
275 
276 /*
277  * SQL-functions CURRENT_SCHEMA, CURRENT_SCHEMAS
278  */
279 Datum
281 {
282  List *search_path = fetch_search_path(false);
283  char *nspname;
284 
285  if (search_path == NIL)
286  PG_RETURN_NULL();
287  nspname = get_namespace_name(linitial_oid(search_path));
288  list_free(search_path);
289  if (!nspname)
290  PG_RETURN_NULL(); /* recently-deleted namespace? */
292 }
293 
294 Datum
296 {
297  List *search_path = fetch_search_path(PG_GETARG_BOOL(0));
298  ListCell *l;
299  Datum *names;
300  int i;
301  ArrayType *array;
302 
303  names = (Datum *) palloc(list_length(search_path) * sizeof(Datum));
304  i = 0;
305  foreach(l, search_path)
306  {
307  char *nspname;
308 
309  nspname = get_namespace_name(lfirst_oid(l));
310  if (nspname) /* watch out for deleted namespace */
311  {
312  names[i] = DirectFunctionCall1(namein, CStringGetDatum(nspname));
313  i++;
314  }
315  }
316  list_free(search_path);
317 
318  array = construct_array(names, i,
319  NAMEOID,
320  NAMEDATALEN, /* sizeof(Name) */
321  false, /* Name is not by-val */
322  'c'); /* alignment of Name */
323 
324  PG_RETURN_POINTER(array);
325 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:305
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:280
Datum namene(PG_FUNCTION_ARGS)
Definition: name.c:143
Oid GetUserId(void)
Definition: miscinit.c:283
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:359
char * pstrdup(const char *in)
Definition: mcxt.c:1165
StringInfoData * StringInfo
Definition: stringinfo.h:46
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3306
int errcode(int sqlerrcode)
Definition: elog.c:575
int namestrcmp(Name name, const char *str)
Definition: name.c:248
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:163
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:232
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:555
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:230
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:313
int namestrcpy(Name name, const char *str)
Definition: name.c:217
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:379
Oid GetSessionUserId(void)
Definition: miscinit.c:317
Datum namesend(PG_FUNCTION_ARGS)
Definition: name.c:104
#define NAMEDATALEN
void pfree(void *pointer)
Definition: mcxt.c:992
#define ERROR
Definition: elog.h:43
int pg_mbcliplen(const char *mbstr, int len, int limit)
Definition: mbutils.c:831
Definition: c.h:489
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3006
static char * buf
Definition: pg_test_fsync.c:65
Datum current_user(PG_FUNCTION_ARGS)
Definition: name.c:264
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define CStringGetDatum(X)
Definition: postgres.h:586
Datum current_schemas(PG_FUNCTION_ARGS)
Definition: name.c:295
#define ereport(elevel, rest)
Definition: elog.h:122
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition: pqformat.c:588
Datum namegt(PG_FUNCTION_ARGS)
Definition: name.c:170
Datum session_user(PG_FUNCTION_ARGS)
Definition: name.c:270
void * palloc0(Size size)
Definition: mcxt.c:920
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:303
uintptr_t Datum
Definition: postgres.h:374
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:297
Datum namerecv(PG_FUNCTION_ARGS)
Definition: name.c:80
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition: miscinit.c:691
#define StrNCpy(dst, src, len)
Definition: c.h:826
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:306
#define linitial_oid(l)
Definition: pg_list.h:112
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:891
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:495
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:233
#define PG_FUNCTION_ARGS
Definition: fmgr.h:150
Datum nameout(PG_FUNCTION_ARGS)
Definition: name.c:69
NameData * Name
Definition: c.h:493
Definition: pg_list.h:45
List * fetch_search_path(bool includeImplicit)
Definition: namespace.c:4018
#define PG_RETURN_NULL()
Definition: fmgr.h:289
#define PG_RETURN_NAME(x)
Definition: fmgr.h:307
#define PG_GETARG_NAME(n)
Definition: fmgr.h:234
#define lfirst_oid(lc)
Definition: pg_list.h:108
Datum nameeq(PG_FUNCTION_ARGS)
Definition: name.c:134