]> granicus.if.org Git - postgresql/blob - src/backend/utils/adt/oid.c
Make oidin/oidout produce and consume unsigned representation of Oid,
[postgresql] / src / backend / utils / adt / oid.c
1 /*-------------------------------------------------------------------------
2  *
3  * oid.c
4  *        Functions for the built-in type Oid.
5  *
6  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $Header: /cvsroot/pgsql/src/backend/utils/adt/oid.c,v 1.39 2000/11/21 03:23:19 tgl Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15
16
17 #include <ctype.h>
18 #include "postgres.h"
19 #include "utils/builtins.h"
20
21 /*****************************************************************************
22  *       USER I/O ROUTINES                                                                                                               *
23  *****************************************************************************/
24
25 /*
26  *              oidvectorin                     - converts "num num ..." to internal form
27  *
28  *              Note:
29  *                              Fills any unsupplied positions with InvalidOid.
30  */
31 Datum
32 oidvectorin(PG_FUNCTION_ARGS)
33 {
34         char       *oidString = PG_GETARG_CSTRING(0);
35         Oid                *result;
36         int                     slot;
37
38         result = (Oid *) palloc(sizeof(Oid[INDEX_MAX_KEYS]));
39
40         for (slot = 0; *oidString && slot < INDEX_MAX_KEYS; slot++)
41         {
42                 if (sscanf(oidString, "%u", &result[slot]) != 1)
43                         break;
44                 while (*oidString && isspace((int) *oidString))
45                         oidString++;
46                 while (*oidString && isdigit((int) *oidString))
47                         oidString++;
48         }
49         while (*oidString && isspace((int) *oidString))
50                 oidString++;
51         if (*oidString)
52                 elog(ERROR, "oidvector value has too many values");
53         while (slot < INDEX_MAX_KEYS)
54                 result[slot++] = InvalidOid;
55
56         PG_RETURN_POINTER(result);
57 }
58
59 /*
60  *              oidvectorout - converts internal form to "num num ..."
61  */
62 Datum
63 oidvectorout(PG_FUNCTION_ARGS)
64 {
65         Oid                *oidArray = (Oid *) PG_GETARG_POINTER(0);
66         int                     num,
67                                 maxnum;
68         char       *rp;
69         char       *result;
70
71         /* find last non-zero value in vector */
72         for (maxnum = INDEX_MAX_KEYS - 1; maxnum >= 0; maxnum--)
73                 if (oidArray[maxnum] != 0)
74                         break;
75
76         /* assumes sign, 10 digits, ' ' */
77         rp = result = (char *) palloc((maxnum + 1) * 12 + 1);
78         for (num = 0; num <= maxnum; num++)
79         {
80                 if (num != 0)
81                         *rp++ = ' ';
82                 sprintf(rp, "%u", oidArray[num]);
83                 while (*++rp != '\0')
84                         ;
85         }
86         *rp = '\0';
87         PG_RETURN_CSTRING(result);
88 }
89
90 Datum
91 oidin(PG_FUNCTION_ARGS)
92 {
93         char       *s = PG_GETARG_CSTRING(0);
94         unsigned long cvt;
95         char       *endptr;
96         Oid                     result;
97
98         errno = 0;
99
100         cvt = strtoul(s, &endptr, 10);
101
102         /*
103          * strtoul() normally only sets ERANGE.  On some systems it also
104          * may set EINVAL, which simply means it couldn't parse the
105          * input string.  This is handled by the second "if" consistent
106          * across platforms.
107          */
108         if (errno && errno != EINVAL)
109                 elog(ERROR, "oidin: error reading \"%s\": %m", s);
110         if (endptr && *endptr)
111                 elog(ERROR, "oidin: error in \"%s\": can't parse \"%s\"", s, endptr);
112
113         /*
114          * Cope with possibility that unsigned long is wider than Oid.
115          */
116         result = (Oid) cvt;
117         if ((unsigned long) result != cvt)
118                 elog(ERROR, "oidin: error reading \"%s\": value too large", s);
119
120         return ObjectIdGetDatum(result);
121 }
122
123 Datum
124 oidout(PG_FUNCTION_ARGS)
125 {
126         Oid                     o = PG_GETARG_OID(0);
127         char       *result = (char *) palloc(12);
128
129         snprintf(result, 12, "%u", o);
130         PG_RETURN_CSTRING(result);
131 }
132
133 /*****************************************************************************
134  *       PUBLIC ROUTINES                                                                                                                 *
135  *****************************************************************************/
136
137 Datum
138 oideq(PG_FUNCTION_ARGS)
139 {
140         Oid                     arg1 = PG_GETARG_OID(0);
141         Oid                     arg2 = PG_GETARG_OID(1);
142
143         PG_RETURN_BOOL(arg1 == arg2);
144 }
145
146 Datum
147 oidne(PG_FUNCTION_ARGS)
148 {
149         Oid                     arg1 = PG_GETARG_OID(0);
150         Oid                     arg2 = PG_GETARG_OID(1);
151
152         PG_RETURN_BOOL(arg1 != arg2);
153 }
154
155 Datum
156 oidlt(PG_FUNCTION_ARGS)
157 {
158         Oid                     arg1 = PG_GETARG_OID(0);
159         Oid                     arg2 = PG_GETARG_OID(1);
160
161         PG_RETURN_BOOL(arg1 < arg2);
162 }
163
164 Datum
165 oidle(PG_FUNCTION_ARGS)
166 {
167         Oid                     arg1 = PG_GETARG_OID(0);
168         Oid                     arg2 = PG_GETARG_OID(1);
169
170         PG_RETURN_BOOL(arg1 <= arg2);
171 }
172
173 Datum
174 oidge(PG_FUNCTION_ARGS)
175 {
176         Oid                     arg1 = PG_GETARG_OID(0);
177         Oid                     arg2 = PG_GETARG_OID(1);
178
179         PG_RETURN_BOOL(arg1 >= arg2);
180 }
181
182 Datum
183 oidgt(PG_FUNCTION_ARGS)
184 {
185         Oid                     arg1 = PG_GETARG_OID(0);
186         Oid                     arg2 = PG_GETARG_OID(1);
187
188         PG_RETURN_BOOL(arg1 > arg2);
189 }
190
191 Datum
192 oidvectoreq(PG_FUNCTION_ARGS)
193 {
194         Oid                     *arg1 = (Oid *) PG_GETARG_POINTER(0);
195         Oid                     *arg2 = (Oid *) PG_GETARG_POINTER(1);
196
197         PG_RETURN_BOOL(memcmp(arg1, arg2, INDEX_MAX_KEYS * sizeof(Oid)) == 0);
198 }
199
200 Datum
201 oidvectorne(PG_FUNCTION_ARGS)
202 {
203         Oid                     *arg1 = (Oid *) PG_GETARG_POINTER(0);
204         Oid                     *arg2 = (Oid *) PG_GETARG_POINTER(1);
205
206         PG_RETURN_BOOL(memcmp(arg1, arg2, INDEX_MAX_KEYS * sizeof(Oid)) != 0);
207 }
208
209 Datum
210 oidvectorlt(PG_FUNCTION_ARGS)
211 {
212         Oid                     *arg1 = (Oid *) PG_GETARG_POINTER(0);
213         Oid                     *arg2 = (Oid *) PG_GETARG_POINTER(1);
214         int                     i;
215
216         for (i = 0; i < INDEX_MAX_KEYS; i++)
217                 if (arg1[i] != arg2[i])
218                         PG_RETURN_BOOL(arg1[i] < arg2[i]);
219         PG_RETURN_BOOL(false);
220 }
221
222 Datum
223 oidvectorle(PG_FUNCTION_ARGS)
224 {
225         Oid                     *arg1 = (Oid *) PG_GETARG_POINTER(0);
226         Oid                     *arg2 = (Oid *) PG_GETARG_POINTER(1);
227         int                     i;
228
229         for (i = 0; i < INDEX_MAX_KEYS; i++)
230                 if (arg1[i] != arg2[i])
231                         PG_RETURN_BOOL(arg1[i] <= arg2[i]);
232         PG_RETURN_BOOL(true);
233 }
234
235 Datum
236 oidvectorge(PG_FUNCTION_ARGS)
237 {
238         Oid                     *arg1 = (Oid *) PG_GETARG_POINTER(0);
239         Oid                     *arg2 = (Oid *) PG_GETARG_POINTER(1);
240         int                     i;
241
242         for (i = 0; i < INDEX_MAX_KEYS; i++)
243                 if (arg1[i] != arg2[i])
244                         PG_RETURN_BOOL(arg1[i] >= arg2[i]);
245         PG_RETURN_BOOL(true);
246 }
247
248 Datum
249 oidvectorgt(PG_FUNCTION_ARGS)
250 {
251         Oid                     *arg1 = (Oid *) PG_GETARG_POINTER(0);
252         Oid                     *arg2 = (Oid *) PG_GETARG_POINTER(1);
253         int                     i;
254
255         for (i = 0; i < INDEX_MAX_KEYS; i++)
256                 if (arg1[i] != arg2[i])
257                         PG_RETURN_BOOL(arg1[i] > arg2[i]);
258         PG_RETURN_BOOL(false);
259 }
260
261 Datum
262 oid_text(PG_FUNCTION_ARGS)
263 {
264         Oid                     oid = PG_GETARG_OID(0);
265         text       *result;
266         int                     len;
267         char       *str;
268
269         str = DatumGetCString(DirectFunctionCall1(oidout,
270                                                                                           ObjectIdGetDatum(oid)));
271         len = strlen(str) + VARHDRSZ;
272
273         result = (text *) palloc(len);
274
275         VARATT_SIZEP(result) = len;
276         memcpy(VARDATA(result), str, (len - VARHDRSZ));
277         pfree(str);
278
279         PG_RETURN_TEXT_P(result);
280 }
281
282 Datum
283 text_oid(PG_FUNCTION_ARGS)
284 {
285         text       *string = PG_GETARG_TEXT_P(0);
286         Oid                     result;
287         int                     len;
288         char       *str;
289
290         len = (VARSIZE(string) - VARHDRSZ);
291
292         str = palloc(len + 1);
293         memcpy(str, VARDATA(string), len);
294         *(str + len) = '\0';
295
296         result = DatumGetObjectId(DirectFunctionCall1(oidin,
297                                                                                                   CStringGetDatum(str)));
298         pfree(str);
299
300         PG_RETURN_OID(result);
301 }