LCOV - code coverage report
Current view: top level - src/backend/utils/adt - format_type.c (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 83.0 % 176 146
Test Date: 2026-07-03 19:57:34 Functions: 87.5 % 8 7
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 80.4 % 102 82

             Branch data     Line data    Source code
       1                 :             : /*-------------------------------------------------------------------------
       2                 :             :  *
       3                 :             :  * format_type.c
       4                 :             :  *    Display type names "nicely".
       5                 :             :  *
       6                 :             :  *
       7                 :             :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       8                 :             :  * Portions Copyright (c) 1994, Regents of the University of California
       9                 :             :  *
      10                 :             :  * IDENTIFICATION
      11                 :             :  *    src/backend/utils/adt/format_type.c
      12                 :             :  *
      13                 :             :  *-------------------------------------------------------------------------
      14                 :             :  */
      15                 :             : 
      16                 :             : #include "postgres.h"
      17                 :             : 
      18                 :             : #include <ctype.h>
      19                 :             : 
      20                 :             : #include "access/htup_details.h"
      21                 :             : #include "catalog/namespace.h"
      22                 :             : #include "catalog/pg_type.h"
      23                 :             : #include "mb/pg_wchar.h"
      24                 :             : #include "utils/builtins.h"
      25                 :             : #include "utils/fmgroids.h"
      26                 :             : #include "utils/lsyscache.h"
      27                 :             : #include "utils/numeric.h"
      28                 :             : #include "utils/syscache.h"
      29                 :             : 
      30                 :             : static char *printTypmod(const char *typname, int32 typmod, Oid typmodout);
      31                 :             : 
      32                 :             : 
      33                 :             : /*
      34                 :             :  * SQL function: format_type(type_oid, typemod)
      35                 :             :  *
      36                 :             :  * `type_oid' is from pg_type.oid, `typemod' is from
      37                 :             :  * pg_attribute.atttypmod. This function will get the type name and
      38                 :             :  * format it and the modifier to canonical SQL format, if the type is
      39                 :             :  * a standard type. Otherwise you just get pg_type.typname back,
      40                 :             :  * double quoted if it contains funny characters or matches a keyword.
      41                 :             :  *
      42                 :             :  * If typemod is NULL then we are formatting a type name in a context where
      43                 :             :  * no typemod is available, eg a function argument or result type.  This
      44                 :             :  * yields a slightly different result from specifying typemod = -1 in some
      45                 :             :  * cases.  Given typemod = -1 we feel compelled to produce an output that
      46                 :             :  * the parser will interpret as having typemod -1, so that pg_dump will
      47                 :             :  * produce CREATE TABLE commands that recreate the original state.  But
      48                 :             :  * given NULL typemod, we assume that the parser's interpretation of
      49                 :             :  * typemod doesn't matter, and so we are willing to output a slightly
      50                 :             :  * "prettier" representation of the same type.  For example, type = bpchar
      51                 :             :  * and typemod = NULL gets you "character", whereas typemod = -1 gets you
      52                 :             :  * "bpchar" --- the former will be interpreted as character(1) by the
      53                 :             :  * parser, which does not yield typemod -1.
      54                 :             :  *
      55                 :             :  * XXX encoding a meaning in typemod = NULL is ugly; it'd have been
      56                 :             :  * cleaner to make two functions of one and two arguments respectively.
      57                 :             :  * Not worth changing it now, however.
      58                 :             :  */
      59                 :             : Datum
      60                 :       63658 : format_type(PG_FUNCTION_ARGS)
      61                 :             : {
      62                 :             :     Oid         type_oid;
      63                 :             :     int32       typemod;
      64                 :             :     char       *result;
      65                 :       63658 :     uint16      flags = FORMAT_TYPE_ALLOW_INVALID;
      66                 :             : 
      67                 :             :     /* Since this function is not strict, we must test for null args */
      68         [ +  + ]:       63658 :     if (PG_ARGISNULL(0))
      69                 :         466 :         PG_RETURN_NULL();
      70                 :             : 
      71                 :       63192 :     type_oid = PG_GETARG_OID(0);
      72                 :             : 
      73         [ +  + ]:       63192 :     if (PG_ARGISNULL(1))
      74                 :       30152 :         typemod = -1;
      75                 :             :     else
      76                 :             :     {
      77                 :       33040 :         typemod = PG_GETARG_INT32(1);
      78                 :       33040 :         flags |= FORMAT_TYPE_TYPEMOD_GIVEN;
      79                 :             :     }
      80                 :             : 
      81                 :       63192 :     result = format_type_extended(type_oid, typemod, flags);
      82                 :             : 
      83                 :       63192 :     PG_RETURN_TEXT_P(cstring_to_text(result));
      84                 :             : }
      85                 :             : 
      86                 :             : /*
      87                 :             :  * format_type_extended
      88                 :             :  *      Generate a possibly-qualified type name.
      89                 :             :  *
      90                 :             :  * The default behavior is to only qualify if the type is not in the search
      91                 :             :  * path, to ignore the given typmod, and to raise an error if a non-existent
      92                 :             :  * type_oid is given.
      93                 :             :  *
      94                 :             :  * The following bits in 'flags' modify the behavior:
      95                 :             :  * - FORMAT_TYPE_TYPEMOD_GIVEN
      96                 :             :  *          include the typmod in the output (typmod could still be -1 though)
      97                 :             :  * - FORMAT_TYPE_ALLOW_INVALID
      98                 :             :  *          if the type OID is invalid or unknown, return ??? or such instead
      99                 :             :  *          of failing
     100                 :             :  * - FORMAT_TYPE_INVALID_AS_NULL
     101                 :             :  *          if the type OID is invalid or unknown, return NULL instead of ???
     102                 :             :  *          or such
     103                 :             :  * - FORMAT_TYPE_FORCE_QUALIFY
     104                 :             :  *          always schema-qualify type names, regardless of search_path
     105                 :             :  *
     106                 :             :  * Note that TYPEMOD_GIVEN is not interchangeable with "typemod == -1";
     107                 :             :  * see the comments above for format_type().
     108                 :             :  *
     109                 :             :  * Returns a palloc'd string, or NULL.
     110                 :             :  */
     111                 :             : char *
     112                 :      394131 : format_type_extended(Oid type_oid, int32 typemod, uint16 flags)
     113                 :             : {
     114                 :             :     HeapTuple   tuple;
     115                 :             :     Form_pg_type typeform;
     116                 :             :     Oid         array_base_type;
     117                 :             :     bool        is_array;
     118                 :             :     char       *buf;
     119                 :             :     bool        with_typemod;
     120                 :             : 
     121         [ +  + ]:      394131 :     if (type_oid == InvalidOid)
     122                 :             :     {
     123         [ +  + ]:          22 :         if ((flags & FORMAT_TYPE_INVALID_AS_NULL) != 0)
     124                 :          12 :             return NULL;
     125         [ +  - ]:          10 :         else if ((flags & FORMAT_TYPE_ALLOW_INVALID) != 0)
     126                 :          10 :             return pstrdup("-");
     127                 :             :     }
     128                 :             : 
     129                 :      394109 :     tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type_oid));
     130         [ +  + ]:      394109 :     if (!HeapTupleIsValid(tuple))
     131                 :             :     {
     132         [ -  + ]:           2 :         if ((flags & FORMAT_TYPE_INVALID_AS_NULL) != 0)
     133                 :           0 :             return NULL;
     134         [ +  - ]:           2 :         else if ((flags & FORMAT_TYPE_ALLOW_INVALID) != 0)
     135                 :           2 :             return pstrdup("???");
     136                 :             :         else
     137         [ #  # ]:           0 :             elog(ERROR, "cache lookup failed for type %u", type_oid);
     138                 :             :     }
     139                 :      394107 :     typeform = (Form_pg_type) GETSTRUCT(tuple);
     140                 :             : 
     141                 :             :     /*
     142                 :             :      * Check if it's a "true" array type.  Pseudo-array types such as "name"
     143                 :             :      * shouldn't get deconstructed.  Also check the toast property, and don't
     144                 :             :      * deconstruct "plain storage" array types --- this is because we don't
     145                 :             :      * want to show oidvector as oid[].
     146                 :             :      */
     147                 :      394107 :     array_base_type = typeform->typelem;
     148                 :             : 
     149   [ +  +  +  + ]:      394107 :     if (IsTrueArrayType(typeform) &&
     150         [ +  + ]:       41312 :         typeform->typstorage != TYPSTORAGE_PLAIN)
     151                 :             :     {
     152                 :             :         /* Switch our attention to the array element type */
     153                 :       41074 :         ReleaseSysCache(tuple);
     154                 :       41074 :         tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(array_base_type));
     155         [ -  + ]:       41074 :         if (!HeapTupleIsValid(tuple))
     156                 :             :         {
     157         [ #  # ]:           0 :             if ((flags & FORMAT_TYPE_INVALID_AS_NULL) != 0)
     158                 :           0 :                 return NULL;
     159         [ #  # ]:           0 :             else if ((flags & FORMAT_TYPE_ALLOW_INVALID) != 0)
     160                 :           0 :                 return pstrdup("???[]");
     161                 :             :             else
     162         [ #  # ]:           0 :                 elog(ERROR, "cache lookup failed for type %u", type_oid);
     163                 :             :         }
     164                 :       41074 :         typeform = (Form_pg_type) GETSTRUCT(tuple);
     165                 :       41074 :         type_oid = array_base_type;
     166                 :       41074 :         is_array = true;
     167                 :             :     }
     168                 :             :     else
     169                 :      353033 :         is_array = false;
     170                 :             : 
     171   [ +  +  +  + ]:      394107 :     with_typemod = (flags & FORMAT_TYPE_TYPEMOD_GIVEN) != 0 && (typemod >= 0);
     172                 :             : 
     173                 :             :     /*
     174                 :             :      * See if we want to special-case the output for certain built-in types.
     175                 :             :      * Note that these special cases should all correspond to special
     176                 :             :      * productions in gram.y, to ensure that the type name will be taken as a
     177                 :             :      * system type, not a user type of the same name.
     178                 :             :      *
     179                 :             :      * If we do not provide a special-case output here, the type name will be
     180                 :             :      * handled the same way as a user type name --- in particular, it will be
     181                 :             :      * double-quoted if it matches any lexer keyword.  This behavior is
     182                 :             :      * essential for some cases, such as types "bit" and "char".
     183                 :             :      */
     184                 :      394107 :     buf = NULL;                 /* flag for no special case */
     185                 :             : 
     186   [ +  +  +  +  :      394107 :     switch (type_oid)
          +  +  +  +  +  
          +  +  +  +  +  
             +  +  +  + ]
     187                 :             :     {
     188                 :         652 :         case BITOID:
     189         [ +  + ]:         652 :             if (with_typemod)
     190                 :         133 :                 buf = printTypmod("bit", typemod, typeform->typmodout);
     191         [ +  + ]:         519 :             else if ((flags & FORMAT_TYPE_TYPEMOD_GIVEN) != 0)
     192                 :             :             {
     193                 :             :                 /*
     194                 :             :                  * bit with typmod -1 is not the same as BIT, which means
     195                 :             :                  * BIT(1) per SQL spec.  Report it as the quoted typename so
     196                 :             :                  * that parser will not assign a bogus typmod.
     197                 :             :                  */
     198                 :             :             }
     199                 :             :             else
     200                 :         484 :                 buf = pstrdup("bit");
     201                 :         652 :             break;
     202                 :             : 
     203                 :        7162 :         case BOOLOID:
     204                 :        7162 :             buf = pstrdup("boolean");
     205                 :        7162 :             break;
     206                 :             : 
     207                 :        1808 :         case BPCHAROID:
     208         [ +  + ]:        1808 :             if (with_typemod)
     209                 :         442 :                 buf = printTypmod("character", typemod, typeform->typmodout);
     210         [ +  + ]:        1366 :             else if ((flags & FORMAT_TYPE_TYPEMOD_GIVEN) != 0)
     211                 :             :             {
     212                 :             :                 /*
     213                 :             :                  * bpchar with typmod -1 is not the same as CHARACTER, which
     214                 :             :                  * means CHARACTER(1) per SQL spec.  Report it as bpchar so
     215                 :             :                  * that parser will not assign a bogus typmod.
     216                 :             :                  */
     217                 :             :             }
     218                 :             :             else
     219                 :         908 :                 buf = pstrdup("character");
     220                 :        1808 :             break;
     221                 :             : 
     222                 :        1525 :         case FLOAT4OID:
     223                 :        1525 :             buf = pstrdup("real");
     224                 :        1525 :             break;
     225                 :             : 
     226                 :        3205 :         case FLOAT8OID:
     227                 :        3205 :             buf = pstrdup("double precision");
     228                 :        3205 :             break;
     229                 :             : 
     230                 :        4073 :         case INT2OID:
     231                 :        4073 :             buf = pstrdup("smallint");
     232                 :        4073 :             break;
     233                 :             : 
     234                 :       86105 :         case INT4OID:
     235                 :       86105 :             buf = pstrdup("integer");
     236                 :       86105 :             break;
     237                 :             : 
     238                 :        6363 :         case INT8OID:
     239                 :        6363 :             buf = pstrdup("bigint");
     240                 :        6363 :             break;
     241                 :             : 
     242                 :        2194 :         case NUMERICOID:
     243         [ +  + ]:        2194 :             if (with_typemod)
     244                 :         205 :                 buf = printTypmod("numeric", typemod, typeform->typmodout);
     245                 :             :             else
     246                 :        1989 :                 buf = pstrdup("numeric");
     247                 :        2194 :             break;
     248                 :             : 
     249                 :         876 :         case INTERVALOID:
     250         [ -  + ]:         876 :             if (with_typemod)
     251                 :           0 :                 buf = printTypmod("interval", typemod, typeform->typmodout);
     252                 :             :             else
     253                 :         876 :                 buf = pstrdup("interval");
     254                 :         876 :             break;
     255                 :             : 
     256                 :         714 :         case TIMEOID:
     257         [ +  + ]:         714 :             if (with_typemod)
     258                 :           5 :                 buf = printTypmod("time", typemod, typeform->typmodout);
     259                 :             :             else
     260                 :         709 :                 buf = pstrdup("time without time zone");
     261                 :         714 :             break;
     262                 :             : 
     263                 :         597 :         case TIMETZOID:
     264         [ +  + ]:         597 :             if (with_typemod)
     265                 :           5 :                 buf = printTypmod("time", typemod, typeform->typmodout);
     266                 :             :             else
     267                 :         592 :                 buf = pstrdup("time with time zone");
     268                 :         597 :             break;
     269                 :             : 
     270                 :         920 :         case TIMESTAMPOID:
     271         [ +  + ]:         920 :             if (with_typemod)
     272                 :           5 :                 buf = printTypmod("timestamp", typemod, typeform->typmodout);
     273                 :             :             else
     274                 :         915 :                 buf = pstrdup("timestamp without time zone");
     275                 :         920 :             break;
     276                 :             : 
     277                 :        1335 :         case TIMESTAMPTZOID:
     278         [ +  + ]:        1335 :             if (with_typemod)
     279                 :           5 :                 buf = printTypmod("timestamp", typemod, typeform->typmodout);
     280                 :             :             else
     281                 :        1330 :                 buf = pstrdup("timestamp with time zone");
     282                 :        1335 :             break;
     283                 :             : 
     284                 :         514 :         case VARBITOID:
     285         [ +  + ]:         514 :             if (with_typemod)
     286                 :          83 :                 buf = printTypmod("bit varying", typemod, typeform->typmodout);
     287                 :             :             else
     288                 :         431 :                 buf = pstrdup("bit varying");
     289                 :         514 :             break;
     290                 :             : 
     291                 :        1067 :         case VARCHAROID:
     292         [ +  + ]:        1067 :             if (with_typemod)
     293                 :         213 :                 buf = printTypmod("character varying", typemod, typeform->typmodout);
     294                 :             :             else
     295                 :         854 :                 buf = pstrdup("character varying");
     296                 :        1067 :             break;
     297                 :             : 
     298                 :         258 :         case JSONOID:
     299                 :         258 :             buf = pstrdup("json");
     300                 :         258 :             break;
     301                 :             :     }
     302                 :             : 
     303         [ +  + ]:      394107 :     if (buf == NULL)
     304                 :             :     {
     305                 :             :         /*
     306                 :             :          * Default handling: report the name as it appears in the catalog.
     307                 :             :          * Here, we must qualify the name if it is not visible in the search
     308                 :             :          * path or if caller requests it; and we must double-quote it if it's
     309                 :             :          * not a standard identifier or if it matches any keyword.
     310                 :             :          */
     311                 :             :         char       *nspname;
     312                 :             :         char       *typname;
     313                 :             : 
     314   [ +  +  +  + ]:      549360 :         if ((flags & FORMAT_TYPE_FORCE_QUALIFY) == 0 &&
     315                 :      274128 :             TypeIsVisible(type_oid))
     316                 :      259391 :             nspname = NULL;
     317                 :             :         else
     318                 :       15841 :             nspname = get_namespace_name_or_temp(typeform->typnamespace);
     319                 :             : 
     320                 :      275232 :         typname = NameStr(typeform->typname);
     321                 :             : 
     322                 :      275232 :         buf = quote_qualified_identifier(nspname, typname);
     323                 :             : 
     324         [ +  + ]:      275232 :         if (with_typemod)
     325                 :           4 :             buf = printTypmod(buf, typemod, typeform->typmodout);
     326                 :             :     }
     327                 :             : 
     328         [ +  + ]:      394107 :     if (is_array)
     329                 :       41074 :         buf = psprintf("%s[]", buf);
     330                 :             : 
     331                 :      394107 :     ReleaseSysCache(tuple);
     332                 :             : 
     333                 :      394107 :     return buf;
     334                 :             : }
     335                 :             : 
     336                 :             : /*
     337                 :             :  * This version is for use within the backend in error messages, etc.
     338                 :             :  * One difference is that it will fail for an invalid type.
     339                 :             :  *
     340                 :             :  * The result is always a palloc'd string.
     341                 :             :  */
     342                 :             : char *
     343                 :      251254 : format_type_be(Oid type_oid)
     344                 :             : {
     345                 :      251254 :     return format_type_extended(type_oid, -1, 0);
     346                 :             : }
     347                 :             : 
     348                 :             : /*
     349                 :             :  * This version returns a name that is always qualified (unless it's one
     350                 :             :  * of the SQL-keyword type names, such as TIMESTAMP WITH TIME ZONE).
     351                 :             :  */
     352                 :             : char *
     353                 :         610 : format_type_be_qualified(Oid type_oid)
     354                 :             : {
     355                 :         610 :     return format_type_extended(type_oid, -1, FORMAT_TYPE_FORCE_QUALIFY);
     356                 :             : }
     357                 :             : 
     358                 :             : /*
     359                 :             :  * This version allows a nondefault typemod to be specified.
     360                 :             :  */
     361                 :             : char *
     362                 :       21373 : format_type_with_typemod(Oid type_oid, int32 typemod)
     363                 :             : {
     364                 :       21373 :     return format_type_extended(type_oid, typemod, FORMAT_TYPE_TYPEMOD_GIVEN);
     365                 :             : }
     366                 :             : 
     367                 :             : /*
     368                 :             :  * Add typmod decoration to the basic type name
     369                 :             :  */
     370                 :             : static char *
     371                 :        1100 : printTypmod(const char *typname, int32 typmod, Oid typmodout)
     372                 :             : {
     373                 :             :     char       *res;
     374                 :             : 
     375                 :             :     /* Shouldn't be called if typmod is -1 */
     376                 :             :     Assert(typmod >= 0);
     377                 :             : 
     378         [ -  + ]:        1100 :     if (typmodout == InvalidOid)
     379                 :             :     {
     380                 :             :         /* Default behavior: just print the integer typmod with parens */
     381                 :           0 :         res = psprintf("%s(%d)", typname, typmod);
     382                 :             :     }
     383                 :             :     else
     384                 :             :     {
     385                 :             :         /* Use the type-specific typmodout procedure */
     386                 :             :         char       *tmstr;
     387                 :             : 
     388                 :        1100 :         tmstr = DatumGetCString(OidFunctionCall1(typmodout,
     389                 :             :                                                  Int32GetDatum(typmod)));
     390                 :        1100 :         res = psprintf("%s%s", typname, tmstr);
     391                 :             :     }
     392                 :             : 
     393                 :        1100 :     return res;
     394                 :             : }
     395                 :             : 
     396                 :             : 
     397                 :             : /*
     398                 :             :  * type_maximum_size --- determine maximum width of a variable-width column
     399                 :             :  *
     400                 :             :  * If the max width is indeterminate, return -1.  In particular, we return
     401                 :             :  * -1 for any type not known to this routine.  We assume the caller has
     402                 :             :  * already determined that the type is a variable-width type, so it's not
     403                 :             :  * necessary to look up the type's pg_type tuple here.
     404                 :             :  *
     405                 :             :  * This may appear unrelated to format_type(), but in fact the two routines
     406                 :             :  * share knowledge of the encoding of typmod for different types, so it's
     407                 :             :  * convenient to keep them together.  (XXX now that most of this knowledge
     408                 :             :  * has been pushed out of format_type into the typmodout functions, it's
     409                 :             :  * interesting to wonder if it's worth trying to factor this code too...)
     410                 :             :  */
     411                 :             : int32
     412                 :      523491 : type_maximum_size(Oid type_oid, int32 typemod)
     413                 :             : {
     414         [ +  + ]:      523491 :     if (typemod < 0)
     415                 :      483270 :         return -1;
     416                 :             : 
     417   [ +  +  +  + ]:       40221 :     switch (type_oid)
     418                 :             :     {
     419                 :       23951 :         case BPCHAROID:
     420                 :             :         case VARCHAROID:
     421                 :             :             /* typemod includes varlena header */
     422                 :             : 
     423                 :             :             /* typemod is in characters not bytes */
     424                 :       47902 :             return (typemod - VARHDRSZ) *
     425                 :       23951 :                 pg_encoding_max_length(GetDatabaseEncoding())
     426                 :       23951 :                 + VARHDRSZ;
     427                 :             : 
     428                 :        4900 :         case NUMERICOID:
     429                 :        4900 :             return numeric_maximum_size(typemod);
     430                 :             : 
     431                 :       11001 :         case VARBITOID:
     432                 :             :         case BITOID:
     433                 :             :             /* typemod is the (max) number of bits */
     434                 :       11001 :             return (typemod + (BITS_PER_BYTE - 1)) / BITS_PER_BYTE
     435                 :       11001 :                 + 2 * sizeof(int32);
     436                 :             :     }
     437                 :             : 
     438                 :             :     /* Unknown type, or unlimited-width type such as 'text' */
     439                 :         369 :     return -1;
     440                 :             : }
     441                 :             : 
     442                 :             : 
     443                 :             : /*
     444                 :             :  * oidvectortypes           - converts a vector of type OIDs to "typname" list
     445                 :             :  */
     446                 :             : Datum
     447                 :           0 : oidvectortypes(PG_FUNCTION_ARGS)
     448                 :             : {
     449                 :           0 :     oidvector  *oidArray = (oidvector *) PG_GETARG_POINTER(0);
     450                 :             :     char       *result;
     451                 :             :     int         numargs;
     452                 :             :     int         num;
     453                 :             :     size_t      total;
     454                 :             :     size_t      left;
     455                 :             : 
     456                 :             :     /* validate input before fetching dim1 */
     457                 :           0 :     check_valid_oidvector(oidArray);
     458                 :           0 :     numargs = oidArray->dim1;
     459                 :             : 
     460                 :           0 :     total = 20 * numargs + 1;
     461                 :           0 :     result = palloc(total);
     462                 :           0 :     result[0] = '\0';
     463                 :           0 :     left = total - 1;
     464                 :             : 
     465         [ #  # ]:           0 :     for (num = 0; num < numargs; num++)
     466                 :             :     {
     467                 :           0 :         char       *typename = format_type_extended(oidArray->values[num], -1,
     468                 :             :                                                     FORMAT_TYPE_ALLOW_INVALID);
     469                 :           0 :         size_t      slen = strlen(typename);
     470                 :             : 
     471         [ #  # ]:           0 :         if (left < (slen + 2))
     472                 :             :         {
     473                 :           0 :             total += slen + 2;
     474                 :           0 :             result = repalloc(result, total);
     475                 :           0 :             left += slen + 2;
     476                 :             :         }
     477                 :             : 
     478         [ #  # ]:           0 :         if (num > 0)
     479                 :             :         {
     480                 :           0 :             strcat(result, ", ");
     481                 :           0 :             left -= 2;
     482                 :             :         }
     483                 :           0 :         strcat(result, typename);
     484                 :           0 :         left -= slen;
     485                 :             :     }
     486                 :             : 
     487                 :           0 :     PG_RETURN_TEXT_P(cstring_to_text(result));
     488                 :             : }
        

Generated by: LCOV version 2.0-1