LCOV - code coverage report
Current view: top level - src/backend/utils/adt - oid.c (source / functions) Hit Total Coverage
Test: PostgreSQL 17devel Lines: 106 143 74.1 %
Date: 2024-04-16 22:11:39 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-2024, 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 "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"
      27             : 
      28             : 
      29             : #define OidVectorSize(n)    (offsetof(oidvector, values) + (n) * sizeof(Oid))
      30             : 
      31             : 
      32             : /*****************************************************************************
      33             :  *   USER I/O ROUTINES                                                       *
      34             :  *****************************************************************************/
      35             : 
      36             : Datum
      37     4689252 : oidin(PG_FUNCTION_ARGS)
      38             : {
      39     4689252 :     char       *s = PG_GETARG_CSTRING(0);
      40             :     Oid         result;
      41             : 
      42     4689252 :     result = uint32in_subr(s, NULL, "oid", fcinfo->context);
      43     4689192 :     PG_RETURN_OID(result);
      44             : }
      45             : 
      46             : Datum
      47    11587486 : oidout(PG_FUNCTION_ARGS)
      48             : {
      49    11587486 :     Oid         o = PG_GETARG_OID(0);
      50    11587486 :     char       *result = (char *) palloc(12);
      51             : 
      52    11587486 :     snprintf(result, 12, "%u", o);
      53    11587486 :     PG_RETURN_CSTRING(result);
      54             : }
      55             : 
      56             : /*
      57             :  *      oidrecv         - converts external binary format to oid
      58             :  */
      59             : Datum
      60         192 : oidrecv(PG_FUNCTION_ARGS)
      61             : {
      62         192 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
      63             : 
      64         192 :     PG_RETURN_OID((Oid) pq_getmsgint(buf, sizeof(Oid)));
      65             : }
      66             : 
      67             : /*
      68             :  *      oidsend         - converts oid to binary format
      69             :  */
      70             : Datum
      71          14 : oidsend(PG_FUNCTION_ARGS)
      72             : {
      73          14 :     Oid         arg1 = PG_GETARG_OID(0);
      74             :     StringInfoData buf;
      75             : 
      76          14 :     pq_begintypsend(&buf);
      77          14 :     pq_sendint32(&buf, arg1);
      78          14 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
      79             : }
      80             : 
      81             : /*
      82             :  * construct oidvector given a raw array of Oids
      83             :  *
      84             :  * If oids is NULL then caller must fill values[] afterward
      85             :  */
      86             : oidvector *
      87      117816 : buildoidvector(const Oid *oids, int n)
      88             : {
      89             :     oidvector  *result;
      90             : 
      91      117816 :     result = (oidvector *) palloc0(OidVectorSize(n));
      92             : 
      93      117816 :     if (n > 0 && oids)
      94      113412 :         memcpy(result->values, oids, n * sizeof(Oid));
      95             : 
      96             :     /*
      97             :      * Attach standard array header.  For historical reasons, we set the index
      98             :      * lower bound to 0 not 1.
      99             :      */
     100      117816 :     SET_VARSIZE(result, OidVectorSize(n));
     101      117816 :     result->ndim = 1;
     102      117816 :     result->dataoffset = 0;      /* never any nulls */
     103      117816 :     result->elemtype = OIDOID;
     104      117816 :     result->dim1 = n;
     105      117816 :     result->lbound1 = 0;
     106             : 
     107      117816 :     return result;
     108             : }
     109             : 
     110             : /*
     111             :  *      oidvectorin         - converts "num num ..." to internal form
     112             :  */
     113             : Datum
     114      265290 : oidvectorin(PG_FUNCTION_ARGS)
     115             : {
     116      265290 :     char       *oidString = PG_GETARG_CSTRING(0);
     117      265290 :     Node       *escontext = fcinfo->context;
     118             :     oidvector  *result;
     119             :     int         nalloc;
     120             :     int         n;
     121             : 
     122      265290 :     nalloc = 32;                /* arbitrary initial size guess */
     123      265290 :     result = (oidvector *) palloc0(OidVectorSize(nalloc));
     124             : 
     125      752704 :     for (n = 0;; n++)
     126             :     {
     127      987510 :         while (*oidString && isspace((unsigned char) *oidString))
     128      234806 :             oidString++;
     129      752704 :         if (*oidString == '\0')
     130      265266 :             break;
     131             : 
     132      487438 :         if (n >= nalloc)
     133             :         {
     134           0 :             nalloc *= 2;
     135           0 :             result = (oidvector *) repalloc(result, OidVectorSize(nalloc));
     136             :         }
     137             : 
     138      487438 :         result->values[n] = uint32in_subr(oidString, &oidString,
     139             :                                           "oid", escontext);
     140      487438 :         if (SOFT_ERROR_OCCURRED(escontext))
     141          24 :             PG_RETURN_NULL();
     142             :     }
     143             : 
     144      265266 :     SET_VARSIZE(result, OidVectorSize(n));
     145      265266 :     result->ndim = 1;
     146      265266 :     result->dataoffset = 0;      /* never any nulls */
     147      265266 :     result->elemtype = OIDOID;
     148      265266 :     result->dim1 = n;
     149      265266 :     result->lbound1 = 0;
     150             : 
     151      265266 :     PG_RETURN_POINTER(result);
     152             : }
     153             : 
     154             : /*
     155             :  *      oidvectorout - converts internal form to "num num ..."
     156             :  */
     157             : Datum
     158       15998 : oidvectorout(PG_FUNCTION_ARGS)
     159             : {
     160       15998 :     oidvector  *oidArray = (oidvector *) PG_GETARG_POINTER(0);
     161             :     int         num,
     162       15998 :                 nnums = oidArray->dim1;
     163             :     char       *rp;
     164             :     char       *result;
     165             : 
     166             :     /* assumes sign, 10 digits, ' ' */
     167       15998 :     rp = result = (char *) palloc(nnums * 12 + 1);
     168       41000 :     for (num = 0; num < nnums; num++)
     169             :     {
     170       25002 :         if (num != 0)
     171       11036 :             *rp++ = ' ';
     172       25002 :         sprintf(rp, "%u", oidArray->values[num]);
     173       69194 :         while (*++rp != '\0')
     174             :             ;
     175             :     }
     176       15998 :     *rp = '\0';
     177       15998 :     PG_RETURN_CSTRING(result);
     178             : }
     179             : 
     180             : /*
     181             :  *      oidvectorrecv           - converts external binary format to oidvector
     182             :  */
     183             : Datum
     184           0 : oidvectorrecv(PG_FUNCTION_ARGS)
     185             : {
     186           0 :     LOCAL_FCINFO(locfcinfo, 3);
     187           0 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
     188             :     oidvector  *result;
     189             : 
     190             :     /*
     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.
     195             :      */
     196           0 :     InitFunctionCallInfoData(*locfcinfo, fcinfo->flinfo, 3,
     197             :                              InvalidOid, NULL, NULL);
     198             : 
     199           0 :     locfcinfo->args[0].value = PointerGetDatum(buf);
     200           0 :     locfcinfo->args[0].isnull = false;
     201           0 :     locfcinfo->args[1].value = ObjectIdGetDatum(OIDOID);
     202           0 :     locfcinfo->args[1].isnull = false;
     203           0 :     locfcinfo->args[2].value = Int32GetDatum(-1);
     204           0 :     locfcinfo->args[2].isnull = false;
     205             : 
     206           0 :     result = (oidvector *) DatumGetPointer(array_recv(locfcinfo));
     207             : 
     208             :     Assert(!locfcinfo->isnull);
     209             : 
     210             :     /* sanity checks: oidvector must be 1-D, 0-based, no nulls */
     211           0 :     if (ARR_NDIM(result) != 1 ||
     212           0 :         ARR_HASNULL(result) ||
     213           0 :         ARR_ELEMTYPE(result) != OIDOID ||
     214           0 :         ARR_LBOUND(result)[0] != 0)
     215           0 :         ereport(ERROR,
     216             :                 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
     217             :                  errmsg("invalid oidvector data")));
     218             : 
     219           0 :     PG_RETURN_POINTER(result);
     220             : }
     221             : 
     222             : /*
     223             :  *      oidvectorsend           - converts oidvector to binary format
     224             :  */
     225             : Datum
     226           0 : oidvectorsend(PG_FUNCTION_ARGS)
     227             : {
     228           0 :     return array_send(fcinfo);
     229             : }
     230             : 
     231             : /*
     232             :  *      oidparse                - get OID from ICONST/FCONST node
     233             :  */
     234             : Oid
     235         136 : oidparse(Node *node)
     236             : {
     237         136 :     switch (nodeTag(node))
     238             :     {
     239         124 :         case T_Integer:
     240         124 :             return intVal(node);
     241          12 :         case T_Float:
     242             : 
     243             :             /*
     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.
     247             :              */
     248          12 :             return uint32in_subr(castNode(Float, node)->fval, NULL,
     249             :                                  "oid", NULL);
     250           0 :         default:
     251           0 :             elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
     252             :     }
     253             :     return InvalidOid;          /* keep compiler quiet */
     254             : }
     255             : 
     256             : /* qsort comparison function for Oids */
     257             : int
     258      358222 : oid_cmp(const void *p1, const void *p2)
     259             : {
     260      358222 :     Oid         v1 = *((const Oid *) p1);
     261      358222 :     Oid         v2 = *((const Oid *) p2);
     262             : 
     263      358222 :     return pg_cmp_u32(v1, v2);
     264             : }
     265             : 
     266             : 
     267             : /*****************************************************************************
     268             :  *   PUBLIC ROUTINES                                                         *
     269             :  *****************************************************************************/
     270             : 
     271             : Datum
     272   108733770 : oideq(PG_FUNCTION_ARGS)
     273             : {
     274   108733770 :     Oid         arg1 = PG_GETARG_OID(0);
     275   108733770 :     Oid         arg2 = PG_GETARG_OID(1);
     276             : 
     277   108733770 :     PG_RETURN_BOOL(arg1 == arg2);
     278             : }
     279             : 
     280             : Datum
     281     2425186 : oidne(PG_FUNCTION_ARGS)
     282             : {
     283     2425186 :     Oid         arg1 = PG_GETARG_OID(0);
     284     2425186 :     Oid         arg2 = PG_GETARG_OID(1);
     285             : 
     286     2425186 :     PG_RETURN_BOOL(arg1 != arg2);
     287             : }
     288             : 
     289             : Datum
     290     4261222 : oidlt(PG_FUNCTION_ARGS)
     291             : {
     292     4261222 :     Oid         arg1 = PG_GETARG_OID(0);
     293     4261222 :     Oid         arg2 = PG_GETARG_OID(1);
     294             : 
     295     4261222 :     PG_RETURN_BOOL(arg1 < arg2);
     296             : }
     297             : 
     298             : Datum
     299     1562486 : oidle(PG_FUNCTION_ARGS)
     300             : {
     301     1562486 :     Oid         arg1 = PG_GETARG_OID(0);
     302     1562486 :     Oid         arg2 = PG_GETARG_OID(1);
     303             : 
     304     1562486 :     PG_RETURN_BOOL(arg1 <= arg2);
     305             : }
     306             : 
     307             : Datum
     308       17114 : oidge(PG_FUNCTION_ARGS)
     309             : {
     310       17114 :     Oid         arg1 = PG_GETARG_OID(0);
     311       17114 :     Oid         arg2 = PG_GETARG_OID(1);
     312             : 
     313       17114 :     PG_RETURN_BOOL(arg1 >= arg2);
     314             : }
     315             : 
     316             : Datum
     317      336376 : oidgt(PG_FUNCTION_ARGS)
     318             : {
     319      336376 :     Oid         arg1 = PG_GETARG_OID(0);
     320      336376 :     Oid         arg2 = PG_GETARG_OID(1);
     321             : 
     322      336376 :     PG_RETURN_BOOL(arg1 > arg2);
     323             : }
     324             : 
     325             : Datum
     326           0 : oidlarger(PG_FUNCTION_ARGS)
     327             : {
     328           0 :     Oid         arg1 = PG_GETARG_OID(0);
     329           0 :     Oid         arg2 = PG_GETARG_OID(1);
     330             : 
     331           0 :     PG_RETURN_OID((arg1 > arg2) ? arg1 : arg2);
     332             : }
     333             : 
     334             : Datum
     335           0 : oidsmaller(PG_FUNCTION_ARGS)
     336             : {
     337           0 :     Oid         arg1 = PG_GETARG_OID(0);
     338           0 :     Oid         arg2 = PG_GETARG_OID(1);
     339             : 
     340           0 :     PG_RETURN_OID((arg1 < arg2) ? arg1 : arg2);
     341             : }
     342             : 
     343             : Datum
     344       31044 : oidvectoreq(PG_FUNCTION_ARGS)
     345             : {
     346       31044 :     int32       cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
     347             : 
     348       31044 :     PG_RETURN_BOOL(cmp == 0);
     349             : }
     350             : 
     351             : Datum
     352       21666 : oidvectorne(PG_FUNCTION_ARGS)
     353             : {
     354       21666 :     int32       cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
     355             : 
     356       21666 :     PG_RETURN_BOOL(cmp != 0);
     357             : }
     358             : 
     359             : Datum
     360        3684 : oidvectorlt(PG_FUNCTION_ARGS)
     361             : {
     362        3684 :     int32       cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
     363             : 
     364        3684 :     PG_RETURN_BOOL(cmp < 0);
     365             : }
     366             : 
     367             : Datum
     368        1272 : oidvectorle(PG_FUNCTION_ARGS)
     369             : {
     370        1272 :     int32       cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
     371             : 
     372        1272 :     PG_RETURN_BOOL(cmp <= 0);
     373             : }
     374             : 
     375             : Datum
     376           0 : oidvectorge(PG_FUNCTION_ARGS)
     377             : {
     378           0 :     int32       cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
     379             : 
     380           0 :     PG_RETURN_BOOL(cmp >= 0);
     381             : }
     382             : 
     383             : Datum
     384           0 : oidvectorgt(PG_FUNCTION_ARGS)
     385             : {
     386           0 :     int32       cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
     387             : 
     388           0 :     PG_RETURN_BOOL(cmp > 0);
     389             : }

Generated by: LCOV version 1.14