1 /*-------------------------------------------------------------------------
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-2003, PostgreSQL Global Development Group
13 * Portions Copyright (c) 1994, Regents of the University of California
17 * $Header: /cvsroot/pgsql/src/backend/utils/adt/name.c,v 1.49 2003/08/04 02:40:05 momjian Exp $
19 *-------------------------------------------------------------------------
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
42 * [Old] Currently if strlen(s) < NAMEDATALEN, the extra chars are nulls
43 * Now, always NULL terminated
46 namein(PG_FUNCTION_ARGS)
48 char *s = PG_GETARG_CSTRING(0);
54 pg_verifymbstr(s, len, false);
56 len = pg_mbcliplen(s, len, NAMEDATALEN - 1);
58 result = (NameData *) palloc0(NAMEDATALEN);
59 memcpy(NameStr(*result), s, len);
61 PG_RETURN_NAME(result);
65 * nameout - converts internal representation to "..."
68 nameout(PG_FUNCTION_ARGS)
70 Name s = PG_GETARG_NAME(0);
72 PG_RETURN_CSTRING(pstrdup(NameStr(*s)));
76 * namerecv - converts external binary format to name
79 namerecv(PG_FUNCTION_ARGS)
81 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
86 str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
87 if (nbytes >= NAMEDATALEN)
89 (errcode(ERRCODE_NAME_TOO_LONG),
90 errmsg("identifier too long"),
91 errdetail("Identifier must be less than %d characters.",
93 result = (NameData *) palloc0(NAMEDATALEN);
94 memcpy(result, str, nbytes);
96 PG_RETURN_NAME(result);
100 * namesend - converts name to binary format
103 namesend(PG_FUNCTION_ARGS)
105 Name s = PG_GETARG_NAME(0);
108 pq_begintypsend(&buf);
109 pq_sendtext(&buf, NameStr(*s), strlen(NameStr(*s)));
110 PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
114 /*****************************************************************************
116 *****************************************************************************/
119 * nameeq - returns 1 iff arguments are equal
120 * namene - returns 1 iff arguments are not equal
123 * Assumes that "xy\0\0a" should be equal to "xy\0b".
124 * If not, can do the comparison backwards for efficiency.
126 * namelt - returns 1 iff a < b
127 * namele - returns 1 iff a <= b
128 * namegt - returns 1 iff a < b
129 * namege - returns 1 iff a <= b
133 nameeq(PG_FUNCTION_ARGS)
135 Name arg1 = PG_GETARG_NAME(0);
136 Name arg2 = PG_GETARG_NAME(1);
138 PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) == 0);
142 namene(PG_FUNCTION_ARGS)
144 Name arg1 = PG_GETARG_NAME(0);
145 Name arg2 = PG_GETARG_NAME(1);
147 PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) != 0);
151 namelt(PG_FUNCTION_ARGS)
153 Name arg1 = PG_GETARG_NAME(0);
154 Name arg2 = PG_GETARG_NAME(1);
156 PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) < 0);
160 namele(PG_FUNCTION_ARGS)
162 Name arg1 = PG_GETARG_NAME(0);
163 Name arg2 = PG_GETARG_NAME(1);
165 PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) <= 0);
169 namegt(PG_FUNCTION_ARGS)
171 Name arg1 = PG_GETARG_NAME(0);
172 Name arg2 = PG_GETARG_NAME(1);
174 PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) > 0);
178 namege(PG_FUNCTION_ARGS)
180 Name arg1 = PG_GETARG_NAME(0);
181 Name arg2 = PG_GETARG_NAME(1);
183 PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) >= 0);
188 * comparison routines for LIKE indexing support
192 name_pattern_eq(PG_FUNCTION_ARGS)
194 Name arg1 = PG_GETARG_NAME(0);
195 Name arg2 = PG_GETARG_NAME(1);
197 PG_RETURN_BOOL(memcmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) == 0);
201 name_pattern_ne(PG_FUNCTION_ARGS)
203 Name arg1 = PG_GETARG_NAME(0);
204 Name arg2 = PG_GETARG_NAME(1);
206 PG_RETURN_BOOL(memcmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) != 0);
210 name_pattern_lt(PG_FUNCTION_ARGS)
212 Name arg1 = PG_GETARG_NAME(0);
213 Name arg2 = PG_GETARG_NAME(1);
215 PG_RETURN_BOOL(memcmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) < 0);
219 name_pattern_le(PG_FUNCTION_ARGS)
221 Name arg1 = PG_GETARG_NAME(0);
222 Name arg2 = PG_GETARG_NAME(1);
224 PG_RETURN_BOOL(memcmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) <= 0);
228 name_pattern_gt(PG_FUNCTION_ARGS)
230 Name arg1 = PG_GETARG_NAME(0);
231 Name arg2 = PG_GETARG_NAME(1);
233 PG_RETURN_BOOL(memcmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) > 0);
237 name_pattern_ge(PG_FUNCTION_ARGS)
239 Name arg1 = PG_GETARG_NAME(0);
240 Name arg2 = PG_GETARG_NAME(1);
242 PG_RETURN_BOOL(memcmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) >= 0);
246 /* (see char.c for comparison/operation routines) */
249 namecpy(Name n1, Name n2)
253 strncpy(NameStr(*n1), NameStr(*n2), NAMEDATALEN);
259 namecat(Name n1, Name n2)
261 return namestrcat(n1, NameStr(*n2)); /* n2 can't be any longer
268 namecmp(Name n1, Name n2)
270 return strncmp(NameStr(*n1), NameStr(*n2), NAMEDATALEN);
275 namestrcpy(Name name, const char *str)
279 StrNCpy(NameStr(*name), str, NAMEDATALEN);
285 namestrcat(Name name, const char *str)
293 for (i = 0, p = NameStr(*name); i < NAMEDATALEN && *p; ++i, ++p)
295 for (q = str; i < NAMEDATALEN; ++i, ++p, ++q)
306 namestrcmp(Name name, const char *str)
311 return -1; /* NULL < anything */
313 return 1; /* NULL < anything */
314 return strncmp(NameStr(*name), str, NAMEDATALEN);
319 * SQL-functions CURRENT_USER, SESSION_USER
322 current_user(PG_FUNCTION_ARGS)
324 PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(GetUserNameFromId(GetUserId()))));
328 session_user(PG_FUNCTION_ARGS)
330 PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(GetUserNameFromId(GetSessionUserId()))));
335 * SQL-functions CURRENT_SCHEMA, CURRENT_SCHEMAS
338 current_schema(PG_FUNCTION_ARGS)
340 List *search_path = fetch_search_path(false);
343 if (search_path == NIL)
345 nspname = get_namespace_name(lfirsto(search_path));
347 PG_RETURN_NULL(); /* recently-deleted namespace? */
348 PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(nspname)));
352 current_schemas(PG_FUNCTION_ARGS)
354 List *search_path = fetch_search_path(PG_GETARG_BOOL(0));
359 /* +1 here is just to avoid palloc(0) error */
360 names = (Datum *) palloc((length(search_path) + 1) * sizeof(Datum));
366 nspname = get_namespace_name(lfirsto(search_path));
367 if (nspname) /* watch out for deleted namespace */
369 names[i] = DirectFunctionCall1(namein, CStringGetDatum(nspname));
372 search_path = lnext(search_path);
375 array = construct_array(names, i,
377 NAMEDATALEN, /* sizeof(Name) */
378 false, /* Name is not by-val */
379 'i'); /* alignment of Name */
381 PG_RETURN_POINTER(array);