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