sepgsql: update TAP test to use fat comma style
[pgsql.git] / src / backend / utils / adt / oid.c
blob4e880e76232739769680fc869dfd6024489ed731
1 /*-------------------------------------------------------------------------
3 * oid.c
4 * Functions for the built-in type Oid ... also oidvector.
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
10 * IDENTIFICATION
11 * src/backend/utils/adt/oid.c
13 *-------------------------------------------------------------------------
15 #include "postgres.h"
17 #include <ctype.h>
18 #include <limits.h>
20 #include "catalog/pg_type.h"
21 #include "common/int.h"
22 #include "libpq/pqformat.h"
23 #include "nodes/miscnodes.h"
24 #include "nodes/value.h"
25 #include "utils/array.h"
26 #include "utils/builtins.h"
29 #define OidVectorSize(n) (offsetof(oidvector, values) + (n) * sizeof(Oid))
32 /*****************************************************************************
33 * USER I/O ROUTINES *
34 *****************************************************************************/
36 Datum
37 oidin(PG_FUNCTION_ARGS)
39 char *s = PG_GETARG_CSTRING(0);
40 Oid result;
42 result = uint32in_subr(s, NULL, "oid", fcinfo->context);
43 PG_RETURN_OID(result);
46 Datum
47 oidout(PG_FUNCTION_ARGS)
49 Oid o = PG_GETARG_OID(0);
50 char *result = (char *) palloc(12);
52 snprintf(result, 12, "%u", o);
53 PG_RETURN_CSTRING(result);
57 * oidrecv - converts external binary format to oid
59 Datum
60 oidrecv(PG_FUNCTION_ARGS)
62 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
64 PG_RETURN_OID((Oid) pq_getmsgint(buf, sizeof(Oid)));
68 * oidsend - converts oid to binary format
70 Datum
71 oidsend(PG_FUNCTION_ARGS)
73 Oid arg1 = PG_GETARG_OID(0);
74 StringInfoData buf;
76 pq_begintypsend(&buf);
77 pq_sendint32(&buf, arg1);
78 PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
82 * construct oidvector given a raw array of Oids
84 * If oids is NULL then caller must fill values[] afterward
86 oidvector *
87 buildoidvector(const Oid *oids, int n)
89 oidvector *result;
91 result = (oidvector *) palloc0(OidVectorSize(n));
93 if (n > 0 && oids)
94 memcpy(result->values, oids, n * sizeof(Oid));
97 * Attach standard array header. For historical reasons, we set the index
98 * lower bound to 0 not 1.
100 SET_VARSIZE(result, OidVectorSize(n));
101 result->ndim = 1;
102 result->dataoffset = 0; /* never any nulls */
103 result->elemtype = OIDOID;
104 result->dim1 = n;
105 result->lbound1 = 0;
107 return result;
111 * oidvectorin - converts "num num ..." to internal form
113 Datum
114 oidvectorin(PG_FUNCTION_ARGS)
116 char *oidString = PG_GETARG_CSTRING(0);
117 Node *escontext = fcinfo->context;
118 oidvector *result;
119 int nalloc;
120 int n;
122 nalloc = 32; /* arbitrary initial size guess */
123 result = (oidvector *) palloc0(OidVectorSize(nalloc));
125 for (n = 0;; n++)
127 while (*oidString && isspace((unsigned char) *oidString))
128 oidString++;
129 if (*oidString == '\0')
130 break;
132 if (n >= nalloc)
134 nalloc *= 2;
135 result = (oidvector *) repalloc(result, OidVectorSize(nalloc));
138 result->values[n] = uint32in_subr(oidString, &oidString,
139 "oid", escontext);
140 if (SOFT_ERROR_OCCURRED(escontext))
141 PG_RETURN_NULL();
144 SET_VARSIZE(result, OidVectorSize(n));
145 result->ndim = 1;
146 result->dataoffset = 0; /* never any nulls */
147 result->elemtype = OIDOID;
148 result->dim1 = n;
149 result->lbound1 = 0;
151 PG_RETURN_POINTER(result);
155 * oidvectorout - converts internal form to "num num ..."
157 Datum
158 oidvectorout(PG_FUNCTION_ARGS)
160 oidvector *oidArray = (oidvector *) PG_GETARG_POINTER(0);
161 int num,
162 nnums = oidArray->dim1;
163 char *rp;
164 char *result;
166 /* assumes sign, 10 digits, ' ' */
167 rp = result = (char *) palloc(nnums * 12 + 1);
168 for (num = 0; num < nnums; num++)
170 if (num != 0)
171 *rp++ = ' ';
172 sprintf(rp, "%u", oidArray->values[num]);
173 while (*++rp != '\0')
176 *rp = '\0';
177 PG_RETURN_CSTRING(result);
181 * oidvectorrecv - converts external binary format to oidvector
183 Datum
184 oidvectorrecv(PG_FUNCTION_ARGS)
186 LOCAL_FCINFO(locfcinfo, 3);
187 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
188 oidvector *result;
191 * Normally one would call array_recv() using DirectFunctionCall3, but
192 * that does not work since array_recv wants to cache some data using
193 * fcinfo->flinfo->fn_extra. So we need to pass it our own flinfo
194 * parameter.
196 InitFunctionCallInfoData(*locfcinfo, fcinfo->flinfo, 3,
197 InvalidOid, NULL, NULL);
199 locfcinfo->args[0].value = PointerGetDatum(buf);
200 locfcinfo->args[0].isnull = false;
201 locfcinfo->args[1].value = ObjectIdGetDatum(OIDOID);
202 locfcinfo->args[1].isnull = false;
203 locfcinfo->args[2].value = Int32GetDatum(-1);
204 locfcinfo->args[2].isnull = false;
206 result = (oidvector *) DatumGetPointer(array_recv(locfcinfo));
208 Assert(!locfcinfo->isnull);
210 /* sanity checks: oidvector must be 1-D, 0-based, no nulls */
211 if (ARR_NDIM(result) != 1 ||
212 ARR_HASNULL(result) ||
213 ARR_ELEMTYPE(result) != OIDOID ||
214 ARR_LBOUND(result)[0] != 0)
215 ereport(ERROR,
216 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
217 errmsg("invalid oidvector data")));
219 PG_RETURN_POINTER(result);
223 * oidvectorsend - converts oidvector to binary format
225 Datum
226 oidvectorsend(PG_FUNCTION_ARGS)
228 return array_send(fcinfo);
232 * oidparse - get OID from ICONST/FCONST node
235 oidparse(Node *node)
237 switch (nodeTag(node))
239 case T_Integer:
240 return intVal(node);
241 case T_Float:
244 * Values too large for int4 will be represented as Float
245 * constants by the lexer. Accept these if they are valid OID
246 * strings.
248 return uint32in_subr(castNode(Float, node)->fval, NULL,
249 "oid", NULL);
250 default:
251 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
253 return InvalidOid; /* keep compiler quiet */
256 /* qsort comparison function for Oids */
258 oid_cmp(const void *p1, const void *p2)
260 Oid v1 = *((const Oid *) p1);
261 Oid v2 = *((const Oid *) p2);
263 return pg_cmp_u32(v1, v2);
267 /*****************************************************************************
268 * PUBLIC ROUTINES *
269 *****************************************************************************/
271 Datum
272 oideq(PG_FUNCTION_ARGS)
274 Oid arg1 = PG_GETARG_OID(0);
275 Oid arg2 = PG_GETARG_OID(1);
277 PG_RETURN_BOOL(arg1 == arg2);
280 Datum
281 oidne(PG_FUNCTION_ARGS)
283 Oid arg1 = PG_GETARG_OID(0);
284 Oid arg2 = PG_GETARG_OID(1);
286 PG_RETURN_BOOL(arg1 != arg2);
289 Datum
290 oidlt(PG_FUNCTION_ARGS)
292 Oid arg1 = PG_GETARG_OID(0);
293 Oid arg2 = PG_GETARG_OID(1);
295 PG_RETURN_BOOL(arg1 < arg2);
298 Datum
299 oidle(PG_FUNCTION_ARGS)
301 Oid arg1 = PG_GETARG_OID(0);
302 Oid arg2 = PG_GETARG_OID(1);
304 PG_RETURN_BOOL(arg1 <= arg2);
307 Datum
308 oidge(PG_FUNCTION_ARGS)
310 Oid arg1 = PG_GETARG_OID(0);
311 Oid arg2 = PG_GETARG_OID(1);
313 PG_RETURN_BOOL(arg1 >= arg2);
316 Datum
317 oidgt(PG_FUNCTION_ARGS)
319 Oid arg1 = PG_GETARG_OID(0);
320 Oid arg2 = PG_GETARG_OID(1);
322 PG_RETURN_BOOL(arg1 > arg2);
325 Datum
326 oidlarger(PG_FUNCTION_ARGS)
328 Oid arg1 = PG_GETARG_OID(0);
329 Oid arg2 = PG_GETARG_OID(1);
331 PG_RETURN_OID((arg1 > arg2) ? arg1 : arg2);
334 Datum
335 oidsmaller(PG_FUNCTION_ARGS)
337 Oid arg1 = PG_GETARG_OID(0);
338 Oid arg2 = PG_GETARG_OID(1);
340 PG_RETURN_OID((arg1 < arg2) ? arg1 : arg2);
343 Datum
344 oidvectoreq(PG_FUNCTION_ARGS)
346 int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
348 PG_RETURN_BOOL(cmp == 0);
351 Datum
352 oidvectorne(PG_FUNCTION_ARGS)
354 int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
356 PG_RETURN_BOOL(cmp != 0);
359 Datum
360 oidvectorlt(PG_FUNCTION_ARGS)
362 int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
364 PG_RETURN_BOOL(cmp < 0);
367 Datum
368 oidvectorle(PG_FUNCTION_ARGS)
370 int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
372 PG_RETURN_BOOL(cmp <= 0);
375 Datum
376 oidvectorge(PG_FUNCTION_ARGS)
378 int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
380 PG_RETURN_BOOL(cmp >= 0);
383 Datum
384 oidvectorgt(PG_FUNCTION_ARGS)
386 int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
388 PG_RETURN_BOOL(cmp > 0);