]> granicus.if.org Git - postgresql/blob - src/backend/utils/adt/name.c
Update copyright for the year 2010.
[postgresql] / src / backend / utils / adt / name.c
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-2010, PostgreSQL Global Development Group
13  * Portions Copyright (c) 1994, Regents of the University of California
14  *
15  *
16  * IDENTIFICATION
17  *        $PostgreSQL: pgsql/src/backend/utils/adt/name.c,v 1.65 2010/01/02 16:57:54 momjian Exp $
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
46 namein(PG_FUNCTION_ARGS)
47 {
48         char       *s = PG_GETARG_CSTRING(0);
49         NameData   *result;
50         int                     len;
51
52         len = strlen(s);
53         len = pg_mbcliplen(s, len, NAMEDATALEN - 1);
54
55         result = (NameData *) palloc0(NAMEDATALEN);
56         memcpy(NameStr(*result), s, len);
57
58         PG_RETURN_NAME(result);
59 }
60
61 /*
62  *              nameout - converts internal representation to "..."
63  */
64 Datum
65 nameout(PG_FUNCTION_ARGS)
66 {
67         Name            s = PG_GETARG_NAME(0);
68
69         PG_RETURN_CSTRING(pstrdup(NameStr(*s)));
70 }
71
72 /*
73  *              namerecv                        - converts external binary format to name
74  */
75 Datum
76 namerecv(PG_FUNCTION_ARGS)
77 {
78         StringInfo      buf = (StringInfo) PG_GETARG_POINTER(0);
79         Name            result;
80         char       *str;
81         int                     nbytes;
82
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);
94 }
95
96 /*
97  *              namesend                        - converts name to binary format
98  */
99 Datum
100 namesend(PG_FUNCTION_ARGS)
101 {
102         Name            s = PG_GETARG_NAME(0);
103         StringInfoData buf;
104
105         pq_begintypsend(&buf);
106         pq_sendtext(&buf, NameStr(*s), strlen(NameStr(*s)));
107         PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
108 }
109
110
111 /*****************************************************************************
112  *       PUBLIC ROUTINES                                                                                                                 *
113  *****************************************************************************/
114
115 /*
116  *              nameeq  - returns 1 iff arguments are equal
117  *              namene  - returns 1 iff arguments are not equal
118  *
119  *              BUGS:
120  *                              Assumes that "xy\0\0a" should be equal to "xy\0b".
121  *                              If not, can do the comparison backwards for efficiency.
122  *
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
127  *
128  */
129 Datum
130 nameeq(PG_FUNCTION_ARGS)
131 {
132         Name            arg1 = PG_GETARG_NAME(0);
133         Name            arg2 = PG_GETARG_NAME(1);
134
135         PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) == 0);
136 }
137
138 Datum
139 namene(PG_FUNCTION_ARGS)
140 {
141         Name            arg1 = PG_GETARG_NAME(0);
142         Name            arg2 = PG_GETARG_NAME(1);
143
144         PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) != 0);
145 }
146
147 Datum
148 namelt(PG_FUNCTION_ARGS)
149 {
150         Name            arg1 = PG_GETARG_NAME(0);
151         Name            arg2 = PG_GETARG_NAME(1);
152
153         PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) < 0);
154 }
155
156 Datum
157 namele(PG_FUNCTION_ARGS)
158 {
159         Name            arg1 = PG_GETARG_NAME(0);
160         Name            arg2 = PG_GETARG_NAME(1);
161
162         PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) <= 0);
163 }
164
165 Datum
166 namegt(PG_FUNCTION_ARGS)
167 {
168         Name            arg1 = PG_GETARG_NAME(0);
169         Name            arg2 = PG_GETARG_NAME(1);
170
171         PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) > 0);
172 }
173
174 Datum
175 namege(PG_FUNCTION_ARGS)
176 {
177         Name            arg1 = PG_GETARG_NAME(0);
178         Name            arg2 = PG_GETARG_NAME(1);
179
180         PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) >= 0);
181 }
182
183
184 /* (see char.c for comparison/operation routines) */
185
186 int
187 namecpy(Name n1, Name n2)
188 {
189         if (!n1 || !n2)
190                 return -1;
191         strncpy(NameStr(*n1), NameStr(*n2), NAMEDATALEN);
192         return 0;
193 }
194
195 #ifdef NOT_USED
196 int
197 namecat(Name n1, Name n2)
198 {
199         return namestrcat(n1, NameStr(*n2));            /* n2 can't be any longer than
200                                                                                                  * n1 */
201 }
202 #endif
203
204 #ifdef NOT_USED
205 int
206 namecmp(Name n1, Name n2)
207 {
208         return strncmp(NameStr(*n1), NameStr(*n2), NAMEDATALEN);
209 }
210 #endif
211
212 int
213 namestrcpy(Name name, const char *str)
214 {
215         if (!name || !str)
216                 return -1;
217         StrNCpy(NameStr(*name), str, NAMEDATALEN);
218         return 0;
219 }
220
221 #ifdef NOT_USED
222 int
223 namestrcat(Name name, const char *str)
224 {
225         int                     i;
226         char       *p,
227                            *q;
228
229         if (!name || !str)
230                 return -1;
231         for (i = 0, p = NameStr(*name); i < NAMEDATALEN && *p; ++i, ++p)
232                 ;
233         for (q = str; i < NAMEDATALEN; ++i, ++p, ++q)
234         {
235                 *p = *q;
236                 if (!*q)
237                         break;
238         }
239         return 0;
240 }
241 #endif
242
243 int
244 namestrcmp(Name name, const char *str)
245 {
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);
253 }
254
255
256 /*
257  * SQL-functions CURRENT_USER, SESSION_USER
258  */
259 Datum
260 current_user(PG_FUNCTION_ARGS)
261 {
262         PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(GetUserNameFromId(GetUserId()))));
263 }
264
265 Datum
266 session_user(PG_FUNCTION_ARGS)
267 {
268         PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(GetUserNameFromId(GetSessionUserId()))));
269 }
270
271
272 /*
273  * SQL-functions CURRENT_SCHEMA, CURRENT_SCHEMAS
274  */
275 Datum
276 current_schema(PG_FUNCTION_ARGS)
277 {
278         List       *search_path = fetch_search_path(false);
279         char       *nspname;
280
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)));
288 }
289
290 Datum
291 current_schemas(PG_FUNCTION_ARGS)
292 {
293         List       *search_path = fetch_search_path(PG_GETARG_BOOL(0));
294         ListCell   *l;
295         Datum      *names;
296         int                     i;
297         ArrayType  *array;
298
299         names = (Datum *) palloc(list_length(search_path) * sizeof(Datum));
300         i = 0;
301         foreach(l, search_path)
302         {
303                 char       *nspname;
304
305                 nspname = get_namespace_name(lfirst_oid(l));
306                 if (nspname)                    /* watch out for deleted namespace */
307                 {
308                         names[i] = DirectFunctionCall1(namein, CStringGetDatum(nspname));
309                         i++;
310                 }
311         }
312         list_free(search_path);
313
314         array = construct_array(names, i,
315                                                         NAMEOID,
316                                                         NAMEDATALEN,            /* sizeof(Name) */
317                                                         false,          /* Name is not by-val */
318                                                         'c');           /* alignment of Name */
319
320         PG_RETURN_POINTER(array);
321 }