1 /*-------------------------------------------------------------------------
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
11 * src/backend/utils/adt/oid.c
13 *-------------------------------------------------------------------------
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 /*****************************************************************************
34 *****************************************************************************/
37 oidin(PG_FUNCTION_ARGS
)
39 char *s
= PG_GETARG_CSTRING(0);
42 result
= uint32in_subr(s
, NULL
, "oid", fcinfo
->context
);
43 PG_RETURN_OID(result
);
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
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
71 oidsend(PG_FUNCTION_ARGS
)
73 Oid arg1
= PG_GETARG_OID(0);
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
87 buildoidvector(const Oid
*oids
, int n
)
91 result
= (oidvector
*) palloc0(OidVectorSize(n
));
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
));
102 result
->dataoffset
= 0; /* never any nulls */
103 result
->elemtype
= OIDOID
;
111 * oidvectorin - converts "num num ..." to internal form
114 oidvectorin(PG_FUNCTION_ARGS
)
116 char *oidString
= PG_GETARG_CSTRING(0);
117 Node
*escontext
= fcinfo
->context
;
122 nalloc
= 32; /* arbitrary initial size guess */
123 result
= (oidvector
*) palloc0(OidVectorSize(nalloc
));
127 while (*oidString
&& isspace((unsigned char) *oidString
))
129 if (*oidString
== '\0')
135 result
= (oidvector
*) repalloc(result
, OidVectorSize(nalloc
));
138 result
->values
[n
] = uint32in_subr(oidString
, &oidString
,
140 if (SOFT_ERROR_OCCURRED(escontext
))
144 SET_VARSIZE(result
, OidVectorSize(n
));
146 result
->dataoffset
= 0; /* never any nulls */
147 result
->elemtype
= OIDOID
;
151 PG_RETURN_POINTER(result
);
155 * oidvectorout - converts internal form to "num num ..."
158 oidvectorout(PG_FUNCTION_ARGS
)
160 oidvector
*oidArray
= (oidvector
*) PG_GETARG_POINTER(0);
162 nnums
= oidArray
->dim1
;
166 /* assumes sign, 10 digits, ' ' */
167 rp
= result
= (char *) palloc(nnums
* 12 + 1);
168 for (num
= 0; num
< nnums
; num
++)
172 sprintf(rp
, "%u", oidArray
->values
[num
]);
173 while (*++rp
!= '\0')
177 PG_RETURN_CSTRING(result
);
181 * oidvectorrecv - converts external binary format to oidvector
184 oidvectorrecv(PG_FUNCTION_ARGS
)
186 LOCAL_FCINFO(locfcinfo
, 3);
187 StringInfo buf
= (StringInfo
) PG_GETARG_POINTER(0);
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
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)
216 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION
),
217 errmsg("invalid oidvector data")));
219 PG_RETURN_POINTER(result
);
223 * oidvectorsend - converts oidvector to binary format
226 oidvectorsend(PG_FUNCTION_ARGS
)
228 return array_send(fcinfo
);
232 * oidparse - get OID from ICONST/FCONST node
237 switch (nodeTag(node
))
244 * Values too large for int4 will be represented as Float
245 * constants by the lexer. Accept these if they are valid OID
248 return uint32in_subr(castNode(Float
, node
)->fval
, NULL
,
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 /*****************************************************************************
269 *****************************************************************************/
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
344 oidvectoreq(PG_FUNCTION_ARGS
)
346 int32 cmp
= DatumGetInt32(btoidvectorcmp(fcinfo
));
348 PG_RETURN_BOOL(cmp
== 0);
352 oidvectorne(PG_FUNCTION_ARGS
)
354 int32 cmp
= DatumGetInt32(btoidvectorcmp(fcinfo
));
356 PG_RETURN_BOOL(cmp
!= 0);
360 oidvectorlt(PG_FUNCTION_ARGS
)
362 int32 cmp
= DatumGetInt32(btoidvectorcmp(fcinfo
));
364 PG_RETURN_BOOL(cmp
< 0);
368 oidvectorle(PG_FUNCTION_ARGS
)
370 int32 cmp
= DatumGetInt32(btoidvectorcmp(fcinfo
));
372 PG_RETURN_BOOL(cmp
<= 0);
376 oidvectorge(PG_FUNCTION_ARGS
)
378 int32 cmp
= DatumGetInt32(btoidvectorcmp(fcinfo
));
380 PG_RETURN_BOOL(cmp
>= 0);
384 oidvectorgt(PG_FUNCTION_ARGS
)
386 int32 cmp
= DatumGetInt32(btoidvectorcmp(fcinfo
));
388 PG_RETURN_BOOL(cmp
> 0);