Fix oversight in previous error-reporting patch; mustn't pfree path string
[PostgreSQL.git] / src / backend / utils / adt / name.c
blobea268e39618363c7cb51a60ac0f3d2c984e0bc9c
1 /*-------------------------------------------------------------------------
3 * name.c
4 * Functions for the built-in type "name".
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
12 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
13 * Portions Copyright (c) 1994, Regents of the University of California
16 * IDENTIFICATION
17 * $PostgreSQL$
19 *-------------------------------------------------------------------------
21 #include "postgres.h"
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"
33 /*****************************************************************************
34 * USER I/O ROUTINES (none) *
35 *****************************************************************************/
39 * namein - converts "..." to internal representation
41 * Note:
42 * [Old] Currently if strlen(s) < NAMEDATALEN, the extra chars are nulls
43 * Now, always NULL terminated
45 Datum
46 namein(PG_FUNCTION_ARGS)
48 char *s = PG_GETARG_CSTRING(0);
49 NameData *result;
50 int len;
52 len = strlen(s);
53 len = pg_mbcliplen(s, len, NAMEDATALEN - 1);
55 result = (NameData *) palloc0(NAMEDATALEN);
56 memcpy(NameStr(*result), s, len);
58 PG_RETURN_NAME(result);
62 * nameout - converts internal representation to "..."
64 Datum
65 nameout(PG_FUNCTION_ARGS)
67 Name s = PG_GETARG_NAME(0);
69 PG_RETURN_CSTRING(pstrdup(NameStr(*s)));
73 * namerecv - converts external binary format to name
75 Datum
76 namerecv(PG_FUNCTION_ARGS)
78 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
79 Name result;
80 char *str;
81 int nbytes;
83 str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
84 if (nbytes >= NAMEDATALEN)
85 ereport(ERROR,
86 (errcode(ERRCODE_NAME_TOO_LONG),
87 errmsg("identifier too long"),
88 errdetail("Identifier must be less than %d characters.",
89 NAMEDATALEN)));
90 result = (NameData *) palloc0(NAMEDATALEN);
91 memcpy(result, str, nbytes);
92 pfree(str);
93 PG_RETURN_NAME(result);
97 * namesend - converts name to binary format
99 Datum
100 namesend(PG_FUNCTION_ARGS)
102 Name s = PG_GETARG_NAME(0);
103 StringInfoData buf;
105 pq_begintypsend(&buf);
106 pq_sendtext(&buf, NameStr(*s), strlen(NameStr(*s)));
107 PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
111 /*****************************************************************************
112 * PUBLIC ROUTINES *
113 *****************************************************************************/
116 * nameeq - returns 1 iff arguments are equal
117 * namene - returns 1 iff arguments are not equal
119 * BUGS:
120 * Assumes that "xy\0\0a" should be equal to "xy\0b".
121 * If not, can do the comparison backwards for efficiency.
123 * namelt - returns 1 iff a < b
124 * namele - returns 1 iff a <= b
125 * namegt - returns 1 iff a > b
126 * namege - returns 1 iff a >= b
129 Datum
130 nameeq(PG_FUNCTION_ARGS)
132 Name arg1 = PG_GETARG_NAME(0);
133 Name arg2 = PG_GETARG_NAME(1);
135 PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) == 0);
138 Datum
139 namene(PG_FUNCTION_ARGS)
141 Name arg1 = PG_GETARG_NAME(0);
142 Name arg2 = PG_GETARG_NAME(1);
144 PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) != 0);
147 Datum
148 namelt(PG_FUNCTION_ARGS)
150 Name arg1 = PG_GETARG_NAME(0);
151 Name arg2 = PG_GETARG_NAME(1);
153 PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) < 0);
156 Datum
157 namele(PG_FUNCTION_ARGS)
159 Name arg1 = PG_GETARG_NAME(0);
160 Name arg2 = PG_GETARG_NAME(1);
162 PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) <= 0);
165 Datum
166 namegt(PG_FUNCTION_ARGS)
168 Name arg1 = PG_GETARG_NAME(0);
169 Name arg2 = PG_GETARG_NAME(1);
171 PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) > 0);
174 Datum
175 namege(PG_FUNCTION_ARGS)
177 Name arg1 = PG_GETARG_NAME(0);
178 Name arg2 = PG_GETARG_NAME(1);
180 PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) >= 0);
184 /* (see char.c for comparison/operation routines) */
187 namecpy(Name n1, Name n2)
189 if (!n1 || !n2)
190 return -1;
191 strncpy(NameStr(*n1), NameStr(*n2), NAMEDATALEN);
192 return 0;
195 #ifdef NOT_USED
197 namecat(Name n1, Name n2)
199 return namestrcat(n1, NameStr(*n2)); /* n2 can't be any longer than
200 * n1 */
202 #endif
204 #ifdef NOT_USED
206 namecmp(Name n1, Name n2)
208 return strncmp(NameStr(*n1), NameStr(*n2), NAMEDATALEN);
210 #endif
213 namestrcpy(Name name, const char *str)
215 if (!name || !str)
216 return -1;
217 StrNCpy(NameStr(*name), str, NAMEDATALEN);
218 return 0;
221 #ifdef NOT_USED
223 namestrcat(Name name, const char *str)
225 int i;
226 char *p,
229 if (!name || !str)
230 return -1;
231 for (i = 0, p = NameStr(*name); i < NAMEDATALEN && *p; ++i, ++p)
233 for (q = str; i < NAMEDATALEN; ++i, ++p, ++q)
235 *p = *q;
236 if (!*q)
237 break;
239 return 0;
241 #endif
244 namestrcmp(Name name, const char *str)
246 if (!name && !str)
247 return 0;
248 if (!name)
249 return -1; /* NULL < anything */
250 if (!str)
251 return 1; /* NULL < anything */
252 return strncmp(NameStr(*name), str, NAMEDATALEN);
257 * SQL-functions CURRENT_USER, SESSION_USER
259 Datum
260 current_user(PG_FUNCTION_ARGS)
262 PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(GetUserNameFromId(GetUserId()))));
265 Datum
266 session_user(PG_FUNCTION_ARGS)
268 PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(GetUserNameFromId(GetSessionUserId()))));
273 * SQL-functions CURRENT_SCHEMA, CURRENT_SCHEMAS
275 Datum
276 current_schema(PG_FUNCTION_ARGS)
278 List *search_path = fetch_search_path(false);
279 char *nspname;
281 if (search_path == NIL)
282 PG_RETURN_NULL();
283 nspname = get_namespace_name(linitial_oid(search_path));
284 list_free(search_path);
285 if (!nspname)
286 PG_RETURN_NULL(); /* recently-deleted namespace? */
287 PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(nspname)));
290 Datum
291 current_schemas(PG_FUNCTION_ARGS)
293 List *search_path = fetch_search_path(PG_GETARG_BOOL(0));
294 ListCell *l;
295 Datum *names;
296 int i;
297 ArrayType *array;
299 names = (Datum *) palloc(list_length(search_path) * sizeof(Datum));
300 i = 0;
301 foreach(l, search_path)
303 char *nspname;
305 nspname = get_namespace_name(lfirst_oid(l));
306 if (nspname) /* watch out for deleted namespace */
308 names[i] = DirectFunctionCall1(namein, CStringGetDatum(nspname));
309 i++;
312 list_free(search_path);
314 array = construct_array(names, i,
315 NAMEOID,
316 NAMEDATALEN, /* sizeof(Name) */
317 false, /* Name is not by-val */
318 'c'); /* alignment of Name */
320 PG_RETURN_POINTER(array);