LCOV - code coverage report
Current view: top level - src/backend/utils/adt - oid.c (source / functions) Hit Total Coverage
Test: PostgreSQL 17devel Lines: 110 147 74.8 %
Date: 2023-12-01 19:11:07 Functions: 19 25 76.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * oid.c
       4             :  *    Functions for the built-in type Oid ... also oidvector.
       5             :  *
       6             :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
       7             :  * Portions Copyright (c) 1994, Regents of the University of California
       8             :  *
       9             :  *
      10             :  * IDENTIFICATION
      11             :  *    src/backend/utils/adt/oid.c
      12             :  *
      13             :  *-------------------------------------------------------------------------
      14             :  */
      15             : #include "postgres.h"
      16             : 
      17             : #include <ctype.h>
      18             : #include <limits.h>
      19             : 
      20             : #include "catalog/pg_type.h"
      21             : #include "libpq/pqformat.h"
      22             : #include "nodes/miscnodes.h"
      23             : #include "nodes/value.h"
      24             : #include "utils/array.h"
      25             : #include "utils/builtins.h"
      26             : 
      27             : 
      28             : #define OidVectorSize(n)    (offsetof(oidvector, values) + (n) * sizeof(Oid))
      29             : 
      30             : 
      31             : /*****************************************************************************
      32             :  *   USER I/O ROUTINES                                                       *
      33             :  *****************************************************************************/
      34             : 
      35             : Datum
      36     3756232 : oidin(PG_FUNCTION_ARGS)
      37             : {
      38     3756232 :     char       *s = PG_GETARG_CSTRING(0);
      39             :     Oid         result;
      40             : 
      41     3756232 :     result = uint32in_subr(s, NULL, "oid", fcinfo->context);
      42     3756172 :     PG_RETURN_OID(result);
      43             : }
      44             : 
      45             : Datum
      46    10843026 : oidout(PG_FUNCTION_ARGS)
      47             : {
      48    10843026 :     Oid         o = PG_GETARG_OID(0);
      49    10843026 :     char       *result = (char *) palloc(12);
      50             : 
      51    10843026 :     snprintf(result, 12, "%u", o);
      52    10843026 :     PG_RETURN_CSTRING(result);
      53             : }
      54             : 
      55             : /*
      56             :  *      oidrecv         - converts external binary format to oid
      57             :  */
      58             : Datum
      59         192 : oidrecv(PG_FUNCTION_ARGS)
      60             : {
      61         192 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
      62             : 
      63         192 :     PG_RETURN_OID((Oid) pq_getmsgint(buf, sizeof(Oid)));
      64             : }
      65             : 
      66             : /*
      67             :  *      oidsend         - converts oid to binary format
      68             :  */
      69             : Datum
      70          14 : oidsend(PG_FUNCTION_ARGS)
      71             : {
      72          14 :     Oid         arg1 = PG_GETARG_OID(0);
      73             :     StringInfoData buf;
      74             : 
      75          14 :     pq_begintypsend(&buf);
      76          14 :     pq_sendint32(&buf, arg1);
      77          14 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
      78             : }
      79             : 
      80             : /*
      81             :  * construct oidvector given a raw array of Oids
      82             :  *
      83             :  * If oids is NULL then caller must fill values[] afterward
      84             :  */
      85             : oidvector *
      86      104752 : buildoidvector(const Oid *oids, int n)
      87             : {
      88             :     oidvector  *result;
      89             : 
      90      104752 :     result = (oidvector *) palloc0(OidVectorSize(n));
      91             : 
      92      104752 :     if (n > 0 && oids)
      93      100510 :         memcpy(result->values, oids, n * sizeof(Oid));
      94             : 
      95             :     /*
      96             :      * Attach standard array header.  For historical reasons, we set the index
      97             :      * lower bound to 0 not 1.
      98             :      */
      99      104752 :     SET_VARSIZE(result, OidVectorSize(n));
     100      104752 :     result->ndim = 1;
     101      104752 :     result->dataoffset = 0;      /* never any nulls */
     102      104752 :     result->elemtype = OIDOID;
     103      104752 :     result->dim1 = n;
     104      104752 :     result->lbound1 = 0;
     105             : 
     106      104752 :     return result;
     107             : }
     108             : 
     109             : /*
     110             :  *      oidvectorin         - converts "num num ..." to internal form
     111             :  */
     112             : Datum
     113      211034 : oidvectorin(PG_FUNCTION_ARGS)
     114             : {
     115      211034 :     char       *oidString = PG_GETARG_CSTRING(0);
     116      211034 :     Node       *escontext = fcinfo->context;
     117             :     oidvector  *result;
     118             :     int         nalloc;
     119             :     int         n;
     120             : 
     121      211034 :     nalloc = 32;                /* arbitrary initial size guess */
     122      211034 :     result = (oidvector *) palloc0(OidVectorSize(nalloc));
     123             : 
     124      599552 :     for (n = 0;; n++)
     125             :     {
     126      786870 :         while (*oidString && isspace((unsigned char) *oidString))
     127      187318 :             oidString++;
     128      599552 :         if (*oidString == '\0')
     129      211010 :             break;
     130             : 
     131      388542 :         if (n >= nalloc)
     132             :         {
     133           0 :             nalloc *= 2;
     134           0 :             result = (oidvector *) repalloc(result, OidVectorSize(nalloc));
     135             :         }
     136             : 
     137      388542 :         result->values[n] = uint32in_subr(oidString, &oidString,
     138             :                                           "oid", escontext);
     139      388542 :         if (SOFT_ERROR_OCCURRED(escontext))
     140          24 :             PG_RETURN_NULL();
     141             :     }
     142             : 
     143      211010 :     SET_VARSIZE(result, OidVectorSize(n));
     144      211010 :     result->ndim = 1;
     145      211010 :     result->dataoffset = 0;      /* never any nulls */
     146      211010 :     result->elemtype = OIDOID;
     147      211010 :     result->dim1 = n;
     148      211010 :     result->lbound1 = 0;
     149             : 
     150      211010 :     PG_RETURN_POINTER(result);
     151             : }
     152             : 
     153             : /*
     154             :  *      oidvectorout - converts internal form to "num num ..."
     155             :  */
     156             : Datum
     157       15666 : oidvectorout(PG_FUNCTION_ARGS)
     158             : {
     159       15666 :     oidvector  *oidArray = (oidvector *) PG_GETARG_POINTER(0);
     160             :     int         num,
     161       15666 :                 nnums = oidArray->dim1;
     162             :     char       *rp;
     163             :     char       *result;
     164             : 
     165             :     /* assumes sign, 10 digits, ' ' */
     166       15666 :     rp = result = (char *) palloc(nnums * 12 + 1);
     167       40166 :     for (num = 0; num < nnums; num++)
     168             :     {
     169       24500 :         if (num != 0)
     170       10804 :             *rp++ = ' ';
     171       24500 :         sprintf(rp, "%u", oidArray->values[num]);
     172       68062 :         while (*++rp != '\0')
     173             :             ;
     174             :     }
     175       15666 :     *rp = '\0';
     176       15666 :     PG_RETURN_CSTRING(result);
     177             : }
     178             : 
     179             : /*
     180             :  *      oidvectorrecv           - converts external binary format to oidvector
     181             :  */
     182             : Datum
     183           0 : oidvectorrecv(PG_FUNCTION_ARGS)
     184             : {
     185           0 :     LOCAL_FCINFO(locfcinfo, 3);
     186           0 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
     187             :     oidvector  *result;
     188             : 
     189             :     /*
     190             :      * Normally one would call array_recv() using DirectFunctionCall3, but
     191             :      * that does not work since array_recv wants to cache some data using
     192             :      * fcinfo->flinfo->fn_extra.  So we need to pass it our own flinfo
     193             :      * parameter.
     194             :      */
     195           0 :     InitFunctionCallInfoData(*locfcinfo, fcinfo->flinfo, 3,
     196             :                              InvalidOid, NULL, NULL);
     197             : 
     198           0 :     locfcinfo->args[0].value = PointerGetDatum(buf);
     199           0 :     locfcinfo->args[0].isnull = false;
     200           0 :     locfcinfo->args[1].value = ObjectIdGetDatum(OIDOID);
     201           0 :     locfcinfo->args[1].isnull = false;
     202           0 :     locfcinfo->args[2].value = Int32GetDatum(-1);
     203           0 :     locfcinfo->args[2].isnull = false;
     204             : 
     205           0 :     result = (oidvector *) DatumGetPointer(array_recv(locfcinfo));
     206             : 
     207             :     Assert(!locfcinfo->isnull);
     208             : 
     209             :     /* sanity checks: oidvector must be 1-D, 0-based, no nulls */
     210           0 :     if (ARR_NDIM(result) != 1 ||
     211           0 :         ARR_HASNULL(result) ||
     212           0 :         ARR_ELEMTYPE(result) != OIDOID ||
     213           0 :         ARR_LBOUND(result)[0] != 0)
     214           0 :         ereport(ERROR,
     215             :                 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
     216             :                  errmsg("invalid oidvector data")));
     217             : 
     218           0 :     PG_RETURN_POINTER(result);
     219             : }
     220             : 
     221             : /*
     222             :  *      oidvectorsend           - converts oidvector to binary format
     223             :  */
     224             : Datum
     225           0 : oidvectorsend(PG_FUNCTION_ARGS)
     226             : {
     227           0 :     return array_send(fcinfo);
     228             : }
     229             : 
     230             : /*
     231             :  *      oidparse                - get OID from ICONST/FCONST node
     232             :  */
     233             : Oid
     234         136 : oidparse(Node *node)
     235             : {
     236         136 :     switch (nodeTag(node))
     237             :     {
     238         124 :         case T_Integer:
     239         124 :             return intVal(node);
     240          12 :         case T_Float:
     241             : 
     242             :             /*
     243             :              * Values too large for int4 will be represented as Float
     244             :              * constants by the lexer.  Accept these if they are valid OID
     245             :              * strings.
     246             :              */
     247          12 :             return uint32in_subr(castNode(Float, node)->fval, NULL,
     248             :                                  "oid", NULL);
     249           0 :         default:
     250           0 :             elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
     251             :     }
     252             :     return InvalidOid;          /* keep compiler quiet */
     253             : }
     254             : 
     255             : /* qsort comparison function for Oids */
     256             : int
     257      344466 : oid_cmp(const void *p1, const void *p2)
     258             : {
     259      344466 :     Oid         v1 = *((const Oid *) p1);
     260      344466 :     Oid         v2 = *((const Oid *) p2);
     261             : 
     262      344466 :     if (v1 < v2)
     263      281152 :         return -1;
     264       63314 :     if (v1 > v2)
     265       13392 :         return 1;
     266       49922 :     return 0;
     267             : }
     268             : 
     269             : 
     270             : /*****************************************************************************
     271             :  *   PUBLIC ROUTINES                                                         *
     272             :  *****************************************************************************/
     273             : 
     274             : Datum
     275    96044438 : oideq(PG_FUNCTION_ARGS)
     276             : {
     277    96044438 :     Oid         arg1 = PG_GETARG_OID(0);
     278    96044438 :     Oid         arg2 = PG_GETARG_OID(1);
     279             : 
     280    96044438 :     PG_RETURN_BOOL(arg1 == arg2);
     281             : }
     282             : 
     283             : Datum
     284     2342460 : oidne(PG_FUNCTION_ARGS)
     285             : {
     286     2342460 :     Oid         arg1 = PG_GETARG_OID(0);
     287     2342460 :     Oid         arg2 = PG_GETARG_OID(1);
     288             : 
     289     2342460 :     PG_RETURN_BOOL(arg1 != arg2);
     290             : }
     291             : 
     292             : Datum
     293     4244754 : oidlt(PG_FUNCTION_ARGS)
     294             : {
     295     4244754 :     Oid         arg1 = PG_GETARG_OID(0);
     296     4244754 :     Oid         arg2 = PG_GETARG_OID(1);
     297             : 
     298     4244754 :     PG_RETURN_BOOL(arg1 < arg2);
     299             : }
     300             : 
     301             : Datum
     302     1562006 : oidle(PG_FUNCTION_ARGS)
     303             : {
     304     1562006 :     Oid         arg1 = PG_GETARG_OID(0);
     305     1562006 :     Oid         arg2 = PG_GETARG_OID(1);
     306             : 
     307     1562006 :     PG_RETURN_BOOL(arg1 <= arg2);
     308             : }
     309             : 
     310             : Datum
     311       19654 : oidge(PG_FUNCTION_ARGS)
     312             : {
     313       19654 :     Oid         arg1 = PG_GETARG_OID(0);
     314       19654 :     Oid         arg2 = PG_GETARG_OID(1);
     315             : 
     316       19654 :     PG_RETURN_BOOL(arg1 >= arg2);
     317             : }
     318             : 
     319             : Datum
     320      334312 : oidgt(PG_FUNCTION_ARGS)
     321             : {
     322      334312 :     Oid         arg1 = PG_GETARG_OID(0);
     323      334312 :     Oid         arg2 = PG_GETARG_OID(1);
     324             : 
     325      334312 :     PG_RETURN_BOOL(arg1 > arg2);
     326             : }
     327             : 
     328             : Datum
     329           0 : oidlarger(PG_FUNCTION_ARGS)
     330             : {
     331           0 :     Oid         arg1 = PG_GETARG_OID(0);
     332           0 :     Oid         arg2 = PG_GETARG_OID(1);
     333             : 
     334           0 :     PG_RETURN_OID((arg1 > arg2) ? arg1 : arg2);
     335             : }
     336             : 
     337             : Datum
     338           0 : oidsmaller(PG_FUNCTION_ARGS)
     339             : {
     340           0 :     Oid         arg1 = PG_GETARG_OID(0);
     341           0 :     Oid         arg2 = PG_GETARG_OID(1);
     342             : 
     343           0 :     PG_RETURN_OID((arg1 < arg2) ? arg1 : arg2);
     344             : }
     345             : 
     346             : Datum
     347       29436 : oidvectoreq(PG_FUNCTION_ARGS)
     348             : {
     349       29436 :     int32       cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
     350             : 
     351       29436 :     PG_RETURN_BOOL(cmp == 0);
     352             : }
     353             : 
     354             : Datum
     355       21530 : oidvectorne(PG_FUNCTION_ARGS)
     356             : {
     357       21530 :     int32       cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
     358             : 
     359       21530 :     PG_RETURN_BOOL(cmp != 0);
     360             : }
     361             : 
     362             : Datum
     363        3684 : oidvectorlt(PG_FUNCTION_ARGS)
     364             : {
     365        3684 :     int32       cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
     366             : 
     367        3684 :     PG_RETURN_BOOL(cmp < 0);
     368             : }
     369             : 
     370             : Datum
     371        1272 : oidvectorle(PG_FUNCTION_ARGS)
     372             : {
     373        1272 :     int32       cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
     374             : 
     375        1272 :     PG_RETURN_BOOL(cmp <= 0);
     376             : }
     377             : 
     378             : Datum
     379           0 : oidvectorge(PG_FUNCTION_ARGS)
     380             : {
     381           0 :     int32       cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
     382             : 
     383           0 :     PG_RETURN_BOOL(cmp >= 0);
     384             : }
     385             : 
     386             : Datum
     387           0 : oidvectorgt(PG_FUNCTION_ARGS)
     388             : {
     389           0 :     int32       cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
     390             : 
     391           0 :     PG_RETURN_BOOL(cmp > 0);
     392             : }

Generated by: LCOV version 1.14