OSDN Git Service

Update copyrights to 2003.
[pg-rex/syncrep.git] / 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-2003, PostgreSQL Global Development Group
13  * Portions Copyright (c) 1994, Regents of the University of California
14  *
15  *
16  * IDENTIFICATION
17  *        $Header: /cvsroot/pgsql/src/backend/utils/adt/name.c,v 1.49 2003/08/04 02:40:05 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         /* verify encoding */
53         len = strlen(s);
54         pg_verifymbstr(s, len, false);
55
56         len = pg_mbcliplen(s, len, NAMEDATALEN - 1);
57
58         result = (NameData *) palloc0(NAMEDATALEN);
59         memcpy(NameStr(*result), s, len);
60
61         PG_RETURN_NAME(result);
62 }
63
64 /*
65  *              nameout - converts internal representation to "..."
66  */
67 Datum
68 nameout(PG_FUNCTION_ARGS)
69 {
70         Name            s = PG_GETARG_NAME(0);
71
72         PG_RETURN_CSTRING(pstrdup(NameStr(*s)));
73 }
74
75 /*
76  *              namerecv                        - converts external binary format to name
77  */
78 Datum
79 namerecv(PG_FUNCTION_ARGS)
80 {
81         StringInfo      buf = (StringInfo) PG_GETARG_POINTER(0);
82         Name            result;
83         char       *str;
84         int                     nbytes;
85
86         str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
87         if (nbytes >= NAMEDATALEN)
88                 ereport(ERROR,
89                                 (errcode(ERRCODE_NAME_TOO_LONG),
90                                  errmsg("identifier too long"),
91                                  errdetail("Identifier must be less than %d characters.",
92                                                    NAMEDATALEN)));
93         result = (NameData *) palloc0(NAMEDATALEN);
94         memcpy(result, str, nbytes);
95         pfree(str);
96         PG_RETURN_NAME(result);
97 }
98
99 /*
100  *              namesend                        - converts name to binary format
101  */
102 Datum
103 namesend(PG_FUNCTION_ARGS)
104 {
105         Name            s = PG_GETARG_NAME(0);
106         StringInfoData buf;
107
108         pq_begintypsend(&buf);
109         pq_sendtext(&buf, NameStr(*s), strlen(NameStr(*s)));
110         PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
111 }
112
113
114 /*****************************************************************************
115  *       PUBLIC ROUTINES                                                                                                                 *
116  *****************************************************************************/
117
118 /*
119  *              nameeq  - returns 1 iff arguments are equal
120  *              namene  - returns 1 iff arguments are not equal
121  *
122  *              BUGS:
123  *                              Assumes that "xy\0\0a" should be equal to "xy\0b".
124  *                              If not, can do the comparison backwards for efficiency.
125  *
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
130  *
131  */
132 Datum
133 nameeq(PG_FUNCTION_ARGS)
134 {
135         Name            arg1 = PG_GETARG_NAME(0);
136         Name            arg2 = PG_GETARG_NAME(1);
137
138         PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) == 0);
139 }
140
141 Datum
142 namene(PG_FUNCTION_ARGS)
143 {
144         Name            arg1 = PG_GETARG_NAME(0);
145         Name            arg2 = PG_GETARG_NAME(1);
146
147         PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) != 0);
148 }
149
150 Datum
151 namelt(PG_FUNCTION_ARGS)
152 {
153         Name            arg1 = PG_GETARG_NAME(0);
154         Name            arg2 = PG_GETARG_NAME(1);
155
156         PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) < 0);
157 }
158
159 Datum
160 namele(PG_FUNCTION_ARGS)
161 {
162         Name            arg1 = PG_GETARG_NAME(0);
163         Name            arg2 = PG_GETARG_NAME(1);
164
165         PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) <= 0);
166 }
167
168 Datum
169 namegt(PG_FUNCTION_ARGS)
170 {
171         Name            arg1 = PG_GETARG_NAME(0);
172         Name            arg2 = PG_GETARG_NAME(1);
173
174         PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) > 0);
175 }
176
177 Datum
178 namege(PG_FUNCTION_ARGS)
179 {
180         Name            arg1 = PG_GETARG_NAME(0);
181         Name            arg2 = PG_GETARG_NAME(1);
182
183         PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) >= 0);
184 }
185
186
187 /*
188  * comparison routines for LIKE indexing support
189  */
190
191 Datum
192 name_pattern_eq(PG_FUNCTION_ARGS)
193 {
194         Name            arg1 = PG_GETARG_NAME(0);
195         Name            arg2 = PG_GETARG_NAME(1);
196
197         PG_RETURN_BOOL(memcmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) == 0);
198 }
199
200 Datum
201 name_pattern_ne(PG_FUNCTION_ARGS)
202 {
203         Name            arg1 = PG_GETARG_NAME(0);
204         Name            arg2 = PG_GETARG_NAME(1);
205
206         PG_RETURN_BOOL(memcmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) != 0);
207 }
208
209 Datum
210 name_pattern_lt(PG_FUNCTION_ARGS)
211 {
212         Name            arg1 = PG_GETARG_NAME(0);
213         Name            arg2 = PG_GETARG_NAME(1);
214
215         PG_RETURN_BOOL(memcmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) < 0);
216 }
217
218 Datum
219 name_pattern_le(PG_FUNCTION_ARGS)
220 {
221         Name            arg1 = PG_GETARG_NAME(0);
222         Name            arg2 = PG_GETARG_NAME(1);
223
224         PG_RETURN_BOOL(memcmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) <= 0);
225 }
226
227 Datum
228 name_pattern_gt(PG_FUNCTION_ARGS)
229 {
230         Name            arg1 = PG_GETARG_NAME(0);
231         Name            arg2 = PG_GETARG_NAME(1);
232
233         PG_RETURN_BOOL(memcmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) > 0);
234 }
235
236 Datum
237 name_pattern_ge(PG_FUNCTION_ARGS)
238 {
239         Name            arg1 = PG_GETARG_NAME(0);
240         Name            arg2 = PG_GETARG_NAME(1);
241
242         PG_RETURN_BOOL(memcmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) >= 0);
243 }
244
245
246 /* (see char.c for comparison/operation routines) */
247
248 int
249 namecpy(Name n1, Name n2)
250 {
251         if (!n1 || !n2)
252                 return -1;
253         strncpy(NameStr(*n1), NameStr(*n2), NAMEDATALEN);
254         return 0;
255 }
256
257 #ifdef NOT_USED
258 int
259 namecat(Name n1, Name n2)
260 {
261         return namestrcat(n1, NameStr(*n2));            /* n2 can't be any longer
262                                                                                                  * than n1 */
263 }
264 #endif
265
266 #ifdef NOT_USED
267 int
268 namecmp(Name n1, Name n2)
269 {
270         return strncmp(NameStr(*n1), NameStr(*n2), NAMEDATALEN);
271 }
272 #endif
273
274 int
275 namestrcpy(Name name, const char *str)
276 {
277         if (!name || !str)
278                 return -1;
279         StrNCpy(NameStr(*name), str, NAMEDATALEN);
280         return 0;
281 }
282
283 #ifdef NOT_USED
284 int
285 namestrcat(Name name, const char *str)
286 {
287         int                     i;
288         char       *p,
289                            *q;
290
291         if (!name || !str)
292                 return -1;
293         for (i = 0, p = NameStr(*name); i < NAMEDATALEN && *p; ++i, ++p)
294                 ;
295         for (q = str; i < NAMEDATALEN; ++i, ++p, ++q)
296         {
297                 *p = *q;
298                 if (!*q)
299                         break;
300         }
301         return 0;
302 }
303 #endif
304
305 int
306 namestrcmp(Name name, const char *str)
307 {
308         if (!name && !str)
309                 return 0;
310         if (!name)
311                 return -1;                              /* NULL < anything */
312         if (!str)
313                 return 1;                               /* NULL < anything */
314         return strncmp(NameStr(*name), str, NAMEDATALEN);
315 }
316
317
318 /*
319  * SQL-functions CURRENT_USER, SESSION_USER
320  */
321 Datum
322 current_user(PG_FUNCTION_ARGS)
323 {
324         PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(GetUserNameFromId(GetUserId()))));
325 }
326
327 Datum
328 session_user(PG_FUNCTION_ARGS)
329 {
330         PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(GetUserNameFromId(GetSessionUserId()))));
331 }
332
333
334 /*
335  * SQL-functions CURRENT_SCHEMA, CURRENT_SCHEMAS
336  */
337 Datum
338 current_schema(PG_FUNCTION_ARGS)
339 {
340         List       *search_path = fetch_search_path(false);
341         char       *nspname;
342
343         if (search_path == NIL)
344                 PG_RETURN_NULL();
345         nspname = get_namespace_name(lfirsto(search_path));
346         if (!nspname)
347                 PG_RETURN_NULL();               /* recently-deleted namespace? */
348         PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(nspname)));
349 }
350
351 Datum
352 current_schemas(PG_FUNCTION_ARGS)
353 {
354         List       *search_path = fetch_search_path(PG_GETARG_BOOL(0));
355         Datum      *names;
356         int                     i;
357         ArrayType  *array;
358
359         /* +1 here is just to avoid palloc(0) error */
360         names = (Datum *) palloc((length(search_path) + 1) * sizeof(Datum));
361         i = 0;
362         while (search_path)
363         {
364                 char       *nspname;
365
366                 nspname = get_namespace_name(lfirsto(search_path));
367                 if (nspname)                    /* watch out for deleted namespace */
368                 {
369                         names[i] = DirectFunctionCall1(namein, CStringGetDatum(nspname));
370                         i++;
371                 }
372                 search_path = lnext(search_path);
373         }
374
375         array = construct_array(names, i,
376                                                         NAMEOID,
377                                                         NAMEDATALEN,            /* sizeof(Name) */
378                                                         false,          /* Name is not by-val */
379                                                         'i');           /* alignment of Name */
380
381         PG_RETURN_POINTER(array);
382 }