LCOV - differential code coverage report
Current view: top level - src/backend/parser - parse_type.c (source / functions) Coverage Total Hit UNC UBC GBC GNC CBC DCB
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 83.1 % 248 206 42 5 2 199 2
Current Date: 2024-04-14 14:21:10 Functions: 96.0 % 25 24 1 2 22 1
Baseline: 16@8cea358b128 Branches: 57.7 % 163 94 1 68 1 1 92
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed (60,120] days: 100.0 % 1 1 1
(240..) days: 83.0 % 247 205 42 5 1 199
Function coverage date bins:
(60,120] days: 100.0 % 1 1 1
(240..) days: 95.8 % 24 23 1 1 22
Branch coverage date bins:
(240..) days: 57.7 % 163 94 1 68 1 1 92

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * parse_type.c
                                  4                 :                :  *      handle type operations for parser
                                  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/parser/parse_type.c
                                 12                 :                :  *
                                 13                 :                :  *-------------------------------------------------------------------------
                                 14                 :                :  */
                                 15                 :                : #include "postgres.h"
                                 16                 :                : 
                                 17                 :                : #include "access/htup_details.h"
                                 18                 :                : #include "catalog/namespace.h"
                                 19                 :                : #include "catalog/pg_type.h"
                                 20                 :                : #include "lib/stringinfo.h"
                                 21                 :                : #include "nodes/makefuncs.h"
                                 22                 :                : #include "parser/parse_type.h"
                                 23                 :                : #include "parser/parser.h"
                                 24                 :                : #include "utils/array.h"
                                 25                 :                : #include "utils/builtins.h"
                                 26                 :                : #include "utils/lsyscache.h"
                                 27                 :                : #include "utils/syscache.h"
                                 28                 :                : 
                                 29                 :                : static int32 typenameTypeMod(ParseState *pstate, const TypeName *typeName,
                                 30                 :                :                              Type typ);
                                 31                 :                : 
                                 32                 :                : 
                                 33                 :                : /*
                                 34                 :                :  * LookupTypeName
                                 35                 :                :  *      Wrapper for typical case.
                                 36                 :                :  */
                                 37                 :                : Type
 1714 noah@leadboat.com          38                 :CBC      316185 : LookupTypeName(ParseState *pstate, const TypeName *typeName,
                                 39                 :                :                int32 *typmod_p, bool missing_ok)
                                 40                 :                : {
                                 41                 :         316185 :     return LookupTypeNameExtended(pstate,
                                 42                 :                :                                   typeName, typmod_p, true, missing_ok);
                                 43                 :                : }
                                 44                 :                : 
                                 45                 :                : /*
                                 46                 :                :  * LookupTypeNameExtended
                                 47                 :                :  *      Given a TypeName object, lookup the pg_type syscache entry of the type.
                                 48                 :                :  *      Returns NULL if no such type can be found.  If the type is found,
                                 49                 :                :  *      the typmod value represented in the TypeName struct is computed and
                                 50                 :                :  *      stored into *typmod_p.
                                 51                 :                :  *
                                 52                 :                :  * NB: on success, the caller must ReleaseSysCache the type tuple when done
                                 53                 :                :  * with it.
                                 54                 :                :  *
                                 55                 :                :  * NB: direct callers of this function MUST check typisdefined before assuming
                                 56                 :                :  * that the type is fully valid.  Most code should go through typenameType
                                 57                 :                :  * or typenameTypeId instead.
                                 58                 :                :  *
                                 59                 :                :  * typmod_p can be passed as NULL if the caller does not care to know the
                                 60                 :                :  * typmod value, but the typmod decoration (if any) will be validated anyway,
                                 61                 :                :  * except in the case where the type is not found.  Note that if the type is
                                 62                 :                :  * found but is a shell, and there is typmod decoration, an error will be
                                 63                 :                :  * thrown --- this is intentional.
                                 64                 :                :  *
                                 65                 :                :  * If temp_ok is false, ignore types in the temporary namespace.  Pass false
                                 66                 :                :  * when the caller will decide, using goodness of fit criteria, whether the
                                 67                 :                :  * typeName is actually a type or something else.  If typeName always denotes
                                 68                 :                :  * a type (or denotes nothing), pass true.
                                 69                 :                :  *
                                 70                 :                :  * pstate is only used for error location info, and may be NULL.
                                 71                 :                :  */
                                 72                 :                : Type
                                 73                 :         343378 : LookupTypeNameExtended(ParseState *pstate,
                                 74                 :                :                        const TypeName *typeName, int32 *typmod_p,
                                 75                 :                :                        bool temp_ok, bool missing_ok)
                                 76                 :                : {
                                 77                 :                :     Oid         typoid;
                                 78                 :                :     HeapTuple   tup;
                                 79                 :                :     int32       typmod;
                                 80                 :                : 
 5386 peter_e@gmx.net            81         [ +  + ]:         343378 :     if (typeName->names == NIL)
                                 82                 :                :     {
                                 83                 :                :         /* We have the OID already if it's an internally generated TypeName */
                                 84                 :          77047 :         typoid = typeName->typeOid;
                                 85                 :                :     }
                                 86         [ +  + ]:         266331 :     else if (typeName->pct_type)
                                 87                 :                :     {
                                 88                 :                :         /* Handle %TYPE reference to type of an existing field */
                                 89                 :             12 :         RangeVar   *rel = makeRangeVar(NULL, NULL, typeName->location);
 8052 tgl@sss.pgh.pa.us          90                 :             12 :         char       *field = NULL;
                                 91                 :                :         Oid         relid;
                                 92                 :                :         AttrNumber  attnum;
                                 93                 :                : 
                                 94                 :                :         /* deconstruct the name list */
 5386 peter_e@gmx.net            95   [ -  +  +  -  :             12 :         switch (list_length(typeName->names))
                                                 - ]
                                 96                 :                :         {
 8052 tgl@sss.pgh.pa.us          97                 :UBC           0 :             case 1:
 7575                            98         [ #  # ]:              0 :                 ereport(ERROR,
                                 99                 :                :                         (errcode(ERRCODE_SYNTAX_ERROR),
                                100                 :                :                          errmsg("improper %%TYPE reference (too few dotted names): %s",
                                101                 :                :                                 NameListToString(typeName->names)),
                                102                 :                :                          parser_errposition(pstate, typeName->location)));
                                103                 :                :                 break;
 8052 tgl@sss.pgh.pa.us         104                 :CBC           9 :             case 2:
 5386 peter_e@gmx.net           105                 :              9 :                 rel->relname = strVal(linitial(typeName->names));
                                106                 :              9 :                 field = strVal(lsecond(typeName->names));
 8052 tgl@sss.pgh.pa.us         107                 :              9 :                 break;
 8052 tgl@sss.pgh.pa.us         108                 :GBC           3 :             case 3:
 5386 peter_e@gmx.net           109                 :              3 :                 rel->schemaname = strVal(linitial(typeName->names));
                                110                 :              3 :                 rel->relname = strVal(lsecond(typeName->names));
                                111                 :              3 :                 field = strVal(lthird(typeName->names));
 8052 tgl@sss.pgh.pa.us         112                 :              3 :                 break;
 8052 tgl@sss.pgh.pa.us         113                 :UBC           0 :             case 4:
 5386 peter_e@gmx.net           114                 :              0 :                 rel->catalogname = strVal(linitial(typeName->names));
                                115                 :              0 :                 rel->schemaname = strVal(lsecond(typeName->names));
                                116                 :              0 :                 rel->relname = strVal(lthird(typeName->names));
                                117                 :              0 :                 field = strVal(lfourth(typeName->names));
 8052 tgl@sss.pgh.pa.us         118                 :              0 :                 break;
                                119                 :              0 :             default:
 7575                           120         [ #  # ]:              0 :                 ereport(ERROR,
                                121                 :                :                         (errcode(ERRCODE_SYNTAX_ERROR),
                                122                 :                :                          errmsg("improper %%TYPE reference (too many dotted names): %s",
                                123                 :                :                                 NameListToString(typeName->names)),
                                124                 :                :                          parser_errposition(pstate, typeName->location)));
                                125                 :                :                 break;
                                126                 :                :         }
                                127                 :                : 
                                128                 :                :         /*
                                129                 :                :          * Look up the field.
                                130                 :                :          *
                                131                 :                :          * XXX: As no lock is taken here, this might fail in the presence of
                                132                 :                :          * concurrent DDL.  But taking a lock would carry a performance
                                133                 :                :          * penalty and would also require a permissions check.
                                134                 :                :          */
 3734 alvherre@alvh.no-ip.      135                 :CBC          12 :         relid = RangeVarGetRelid(rel, NoLock, missing_ok);
 8052 tgl@sss.pgh.pa.us         136                 :             12 :         attnum = get_attnum(relid, field);
                                137         [ -  + ]:             12 :         if (attnum == InvalidAttrNumber)
                                138                 :                :         {
 3734 alvherre@alvh.no-ip.      139         [ #  # ]:UBC           0 :             if (missing_ok)
                                140                 :              0 :                 typoid = InvalidOid;
                                141                 :                :             else
                                142         [ #  # ]:              0 :                 ereport(ERROR,
                                143                 :                :                         (errcode(ERRCODE_UNDEFINED_COLUMN),
                                144                 :                :                          errmsg("column \"%s\" of relation \"%s\" does not exist",
                                145                 :                :                                 field, rel->relname),
                                146                 :                :                          parser_errposition(pstate, typeName->location)));
                                147                 :                :         }
                                148                 :                :         else
                                149                 :                :         {
 3734 alvherre@alvh.no-ip.      150                 :CBC          12 :             typoid = get_atttype(relid, attnum);
                                151                 :                : 
                                152                 :                :             /* this construct should never have an array indicator */
                                153         [ -  + ]:             12 :             Assert(typeName->arrayBounds == NIL);
                                154                 :                : 
                                155                 :                :             /* emit nuisance notice (intentionally not errposition'd) */
                                156         [ +  - ]:             12 :             ereport(NOTICE,
                                157                 :                :                     (errmsg("type reference %s converted to %s",
                                158                 :                :                             TypeNameToString(typeName),
                                159                 :                :                             format_type_be(typoid))));
                                160                 :                :         }
                                161                 :                :     }
                                162                 :                :     else
                                163                 :                :     {
                                164                 :                :         /* Normal reference to a type name */
                                165                 :                :         char       *schemaname;
                                166                 :                :         char       *typname;
                                167                 :                : 
                                168                 :                :         /* deconstruct the name list */
 5386 peter_e@gmx.net           169                 :         266319 :         DeconstructQualifiedName(typeName->names, &schemaname, &typname);
                                170                 :                : 
 8052 tgl@sss.pgh.pa.us         171         [ +  + ]:         266313 :         if (schemaname)
                                172                 :                :         {
                                173                 :                :             /* Look in specific schema only */
                                174                 :                :             Oid         namespaceId;
                                175                 :                :             ParseCallbackState pcbstate;
                                176                 :                : 
 3315 alvherre@alvh.no-ip.      177                 :         111757 :             setup_parser_errposition_callback(&pcbstate, pstate, typeName->location);
                                178                 :                : 
 3734                           179                 :         111757 :             namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
                                180         [ +  + ]:         111754 :             if (OidIsValid(namespaceId))
 1972 andres@anarazel.de        181                 :         111706 :                 typoid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid,
                                182                 :                :                                          PointerGetDatum(typname),
                                183                 :                :                                          ObjectIdGetDatum(namespaceId));
                                184                 :                :             else
 3734 alvherre@alvh.no-ip.      185                 :             48 :                 typoid = InvalidOid;
                                186                 :                : 
 3315                           187                 :         111754 :             cancel_parser_errposition_callback(&pcbstate);
                                188                 :                :         }
                                189                 :                :         else
                                190                 :                :         {
                                191                 :                :             /* Unqualified type name, so search the search path */
 1714 noah@leadboat.com         192                 :         154556 :             typoid = TypenameGetTypidExtended(typname, temp_ok);
                                193                 :                :         }
                                194                 :                : 
                                195                 :                :         /* If an array reference, return the array type instead */
 5386 peter_e@gmx.net           196         [ +  + ]:         266310 :         if (typeName->arrayBounds != NIL)
 5999 tgl@sss.pgh.pa.us         197                 :           6096 :             typoid = get_array_type(typoid);
                                198                 :                :     }
                                199                 :                : 
                                200         [ +  + ]:         343369 :     if (!OidIsValid(typoid))
                                201                 :                :     {
                                202         [ +  + ]:          27075 :         if (typmod_p)
                                203                 :             22 :             *typmod_p = -1;
                                204                 :          27075 :         return NULL;
                                205                 :                :     }
                                206                 :                : 
 5173 rhaas@postgresql.org      207                 :         316294 :     tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typoid));
 5999 tgl@sss.pgh.pa.us         208         [ -  + ]:         316294 :     if (!HeapTupleIsValid(tup)) /* should not happen */
 5999 tgl@sss.pgh.pa.us         209         [ #  # ]:UBC           0 :         elog(ERROR, "cache lookup failed for type %u", typoid);
                                210                 :                : 
 5386 peter_e@gmx.net           211                 :CBC      316294 :     typmod = typenameTypeMod(pstate, typeName, (Type) tup);
                                212                 :                : 
 5999 tgl@sss.pgh.pa.us         213         [ +  + ]:         316288 :     if (typmod_p)
                                214                 :         236615 :         *typmod_p = typmod;
                                215                 :                : 
                                216                 :         316288 :     return (Type) tup;
                                217                 :                : }
                                218                 :                : 
                                219                 :                : /*
                                220                 :                :  * LookupTypeNameOid
                                221                 :                :  *      Given a TypeName object, lookup the pg_type syscache entry of the type.
                                222                 :                :  *      Returns InvalidOid if no such type can be found.  If the type is found,
                                223                 :                :  *      return its Oid.
                                224                 :                :  *
                                225                 :                :  * NB: direct callers of this function need to be aware that the type OID
                                226                 :                :  * returned may correspond to a shell type.  Most code should go through
                                227                 :                :  * typenameTypeId instead.
                                228                 :                :  *
                                229                 :                :  * pstate is only used for error location info, and may be NULL.
                                230                 :                :  */
                                231                 :                : Oid
 3734 alvherre@alvh.no-ip.      232                 :          10338 : LookupTypeNameOid(ParseState *pstate, const TypeName *typeName, bool missing_ok)
                                233                 :                : {
                                234                 :                :     Oid         typoid;
                                235                 :                :     Type        tup;
                                236                 :                : 
                                237                 :          10338 :     tup = LookupTypeName(pstate, typeName, NULL, missing_ok);
                                238         [ +  + ]:          10338 :     if (tup == NULL)
                                239                 :                :     {
                                240         [ +  + ]:             90 :         if (!missing_ok)
                                241         [ +  - ]:             16 :             ereport(ERROR,
                                242                 :                :                     (errcode(ERRCODE_UNDEFINED_OBJECT),
                                243                 :                :                      errmsg("type \"%s\" does not exist",
                                244                 :                :                             TypeNameToString(typeName)),
                                245                 :                :                      parser_errposition(pstate, typeName->location)));
                                246                 :                : 
                                247                 :             74 :         return InvalidOid;
                                248                 :                :     }
                                249                 :                : 
 1972 andres@anarazel.de        250                 :          10248 :     typoid = ((Form_pg_type) GETSTRUCT(tup))->oid;
 3734 alvherre@alvh.no-ip.      251                 :          10248 :     ReleaseSysCache(tup);
                                252                 :                : 
                                253                 :          10248 :     return typoid;
                                254                 :                : }
                                255                 :                : 
                                256                 :                : /*
                                257                 :                :  * typenameType - given a TypeName, return a Type structure and typmod
                                258                 :                :  *
                                259                 :                :  * This is equivalent to LookupTypeName, except that this will report
                                260                 :                :  * a suitable error message if the type cannot be found or is not defined.
                                261                 :                :  * Callers of this can therefore assume the result is a fully valid type.
                                262                 :                :  */
                                263                 :                : Type
 4785 tgl@sss.pgh.pa.us         264                 :         271438 : typenameType(ParseState *pstate, const TypeName *typeName, int32 *typmod_p)
                                265                 :                : {
                                266                 :                :     Type        tup;
                                267                 :                : 
 3734 alvherre@alvh.no-ip.      268                 :         271438 :     tup = LookupTypeName(pstate, typeName, typmod_p, false);
 5999 tgl@sss.pgh.pa.us         269         [ +  + ]:         271435 :     if (tup == NULL)
 7575                           270         [ +  - ]:             16 :         ereport(ERROR,
                                271                 :                :                 (errcode(ERRCODE_UNDEFINED_OBJECT),
                                272                 :                :                  errmsg("type \"%s\" does not exist",
                                273                 :                :                         TypeNameToString(typeName)),
                                274                 :                :                  parser_errposition(pstate, typeName->location)));
 5999                           275         [ +  + ]:         271419 :     if (!((Form_pg_type) GETSTRUCT(tup))->typisdefined)
 7575                           276         [ +  - ]:              3 :         ereport(ERROR,
                                277                 :                :                 (errcode(ERRCODE_UNDEFINED_OBJECT),
                                278                 :                :                  errmsg("type \"%s\" is only a shell",
                                279                 :                :                         TypeNameToString(typeName)),
                                280                 :                :                  parser_errposition(pstate, typeName->location)));
 5999                           281                 :         271416 :     return tup;
                                282                 :                : }
                                283                 :                : 
                                284                 :                : /*
                                285                 :                :  * typenameTypeId - given a TypeName, return the type's OID
                                286                 :                :  *
                                287                 :                :  * This is similar to typenameType, but we only hand back the type OID
                                288                 :                :  * not the syscache entry.
                                289                 :                :  */
                                290                 :                : Oid
 4920 peter_e@gmx.net           291                 :           5138 : typenameTypeId(ParseState *pstate, const TypeName *typeName)
                                292                 :                : {
                                293                 :                :     Oid         typoid;
                                294                 :                :     Type        tup;
                                295                 :                : 
 4785 tgl@sss.pgh.pa.us         296                 :           5138 :     tup = typenameType(pstate, typeName, NULL);
 1972 andres@anarazel.de        297                 :           5131 :     typoid = ((Form_pg_type) GETSTRUCT(tup))->oid;
 5999 tgl@sss.pgh.pa.us         298                 :           5131 :     ReleaseSysCache(tup);
                                299                 :                : 
 8052                           300                 :           5131 :     return typoid;
                                301                 :                : }
                                302                 :                : 
                                303                 :                : /*
                                304                 :                :  * typenameTypeIdAndMod - given a TypeName, return the type's OID and typmod
                                305                 :                :  *
                                306                 :                :  * This is equivalent to typenameType, but we only hand back the type OID
                                307                 :                :  * and typmod, not the syscache entry.
                                308                 :                :  */
                                309                 :                : void
 4920 peter_e@gmx.net           310                 :         233941 : typenameTypeIdAndMod(ParseState *pstate, const TypeName *typeName,
                                311                 :                :                      Oid *typeid_p, int32 *typmod_p)
                                312                 :                : {
                                313                 :                :     Type        tup;
                                314                 :                : 
 4785 tgl@sss.pgh.pa.us         315                 :         233941 :     tup = typenameType(pstate, typeName, typmod_p);
 1972 andres@anarazel.de        316                 :         233939 :     *typeid_p = ((Form_pg_type) GETSTRUCT(tup))->oid;
 4920 peter_e@gmx.net           317                 :         233939 :     ReleaseSysCache(tup);
                                318                 :         233939 : }
                                319                 :                : 
                                320                 :                : /*
                                321                 :                :  * typenameTypeMod - given a TypeName, return the internal typmod value
                                322                 :                :  *
                                323                 :                :  * This will throw an error if the TypeName includes type modifiers that are
                                324                 :                :  * illegal for the data type.
                                325                 :                :  *
                                326                 :                :  * The actual type OID represented by the TypeName must already have been
                                327                 :                :  * looked up, and is passed as "typ".
                                328                 :                :  *
                                329                 :                :  * pstate is only used for error location info, and may be NULL.
                                330                 :                :  */
                                331                 :                : static int32
 5386                           332                 :         316294 : typenameTypeMod(ParseState *pstate, const TypeName *typeName, Type typ)
                                333                 :                : {
                                334                 :                :     int32       result;
                                335                 :                :     Oid         typmodin;
                                336                 :                :     Datum      *datums;
                                337                 :                :     int         n;
                                338                 :                :     ListCell   *l;
                                339                 :                :     ArrayType  *arrtypmod;
                                340                 :                :     ParseCallbackState pcbstate;
                                341                 :                : 
                                342                 :                :     /* Return prespecified typmod if no typmod expressions */
                                343         [ +  + ]:         316294 :     if (typeName->typmods == NIL)
                                344                 :         312305 :         return typeName->typemod;
                                345                 :                : 
                                346                 :                :     /*
                                347                 :                :      * Else, type had better accept typmods.  We give a special error message
                                348                 :                :      * for the shell-type case, since a shell couldn't possibly have a
                                349                 :                :      * typmodin function.
                                350                 :                :      */
 5999 tgl@sss.pgh.pa.us         351         [ -  + ]:           3989 :     if (!((Form_pg_type) GETSTRUCT(typ))->typisdefined)
 5999 tgl@sss.pgh.pa.us         352         [ #  # ]:UBC           0 :         ereport(ERROR,
                                353                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                354                 :                :                  errmsg("type modifier cannot be specified for shell type \"%s\"",
                                355                 :                :                         TypeNameToString(typeName)),
                                356                 :                :                  parser_errposition(pstate, typeName->location)));
                                357                 :                : 
 5999 tgl@sss.pgh.pa.us         358                 :CBC        3989 :     typmodin = ((Form_pg_type) GETSTRUCT(typ))->typmodin;
                                359                 :                : 
 6315                           360         [ -  + ]:           3989 :     if (typmodin == InvalidOid)
 6315 tgl@sss.pgh.pa.us         361         [ #  # ]:UBC           0 :         ereport(ERROR,
                                362                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                363                 :                :                  errmsg("type modifier is not allowed for type \"%s\"",
                                364                 :                :                         TypeNameToString(typeName)),
                                365                 :                :                  parser_errposition(pstate, typeName->location)));
                                366                 :                : 
                                367                 :                :     /*
                                368                 :                :      * Convert the list of raw-grammar-output expressions to a cstring array.
                                369                 :                :      * Currently, we allow simple numeric constants, string literals, and
                                370                 :                :      * identifiers; possibly this list could be extended.
                                371                 :                :      */
 5386 peter_e@gmx.net           372                 :CBC        3989 :     datums = (Datum *) palloc(list_length(typeName->typmods) * sizeof(Datum));
 6315 tgl@sss.pgh.pa.us         373                 :           3989 :     n = 0;
 5386 peter_e@gmx.net           374   [ +  -  +  +  :           8943 :     foreach(l, typeName->typmods)
                                              +  + ]
                                375                 :                :     {
 5995 bruce@momjian.us          376                 :           4954 :         Node       *tm = (Node *) lfirst(l);
                                377                 :           4954 :         char       *cstr = NULL;
                                378                 :                : 
 6148 tgl@sss.pgh.pa.us         379         [ +  - ]:           4954 :         if (IsA(tm, A_Const))
                                380                 :                :         {
 5995 bruce@momjian.us          381                 :           4954 :             A_Const    *ac = (A_Const *) tm;
                                382                 :                : 
 6148 tgl@sss.pgh.pa.us         383         [ +  - ]:           4954 :             if (IsA(&ac->val, Integer))
                                384                 :                :             {
  821 peter@eisentraut.org      385                 :           4954 :                 cstr = psprintf("%ld", (long) intVal(&ac->val));
                                386                 :                :             }
  948 peter@eisentraut.org      387         [ #  # ]:UBC           0 :             else if (IsA(&ac->val, Float))
                                388                 :                :             {
                                389                 :                :                 /* we can just use the string representation directly. */
  821                           390                 :              0 :                 cstr = ac->val.fval.fval;
                                391                 :                :             }
  948                           392         [ #  # ]:              0 :             else if (IsA(&ac->val, String))
                                393                 :                :             {
                                394                 :                :                 /* we can just use the string representation directly. */
  821                           395                 :              0 :                 cstr = strVal(&ac->val);
                                396                 :                :             }
                                397                 :                :         }
 6148 tgl@sss.pgh.pa.us         398         [ #  # ]:              0 :         else if (IsA(tm, ColumnRef))
                                399                 :                :         {
 5995 bruce@momjian.us          400                 :              0 :             ColumnRef  *cr = (ColumnRef *) tm;
                                401                 :                : 
 5706 tgl@sss.pgh.pa.us         402         [ #  # ]:              0 :             if (list_length(cr->fields) == 1 &&
                                403         [ #  # ]:              0 :                 IsA(linitial(cr->fields), String))
 6148                           404                 :              0 :                 cstr = strVal(linitial(cr->fields));
                                405                 :                :         }
 6148 tgl@sss.pgh.pa.us         406         [ -  + ]:CBC        4954 :         if (!cstr)
 6315 tgl@sss.pgh.pa.us         407         [ #  # ]:UBC           0 :             ereport(ERROR,
                                408                 :                :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                409                 :                :                      errmsg("type modifiers must be simple constants or identifiers"),
                                410                 :                :                      parser_errposition(pstate, typeName->location)));
 6148 tgl@sss.pgh.pa.us         411                 :CBC        4954 :         datums[n++] = CStringGetDatum(cstr);
                                412                 :                :     }
                                413                 :                : 
  653 peter@eisentraut.org      414                 :           3989 :     arrtypmod = construct_array_builtin(datums, n, CSTRINGOID);
                                415                 :                : 
                                416                 :                :     /* arrange to report location if type's typmodin function fails */
 5386 peter_e@gmx.net           417                 :           3989 :     setup_parser_errposition_callback(&pcbstate, pstate, typeName->location);
                                418                 :                : 
 6315 tgl@sss.pgh.pa.us         419                 :           3989 :     result = DatumGetInt32(OidFunctionCall1(typmodin,
                                420                 :                :                                             PointerGetDatum(arrtypmod)));
                                421                 :                : 
 5704                           422                 :           3983 :     cancel_parser_errposition_callback(&pcbstate);
                                423                 :                : 
 6315                           424                 :           3983 :     pfree(datums);
                                425                 :           3983 :     pfree(arrtypmod);
                                426                 :                : 
                                427                 :           3983 :     return result;
                                428                 :                : }
                                429                 :                : 
                                430                 :                : /*
                                431                 :                :  * appendTypeNameToBuffer
                                432                 :                :  *      Append a string representing the name of a TypeName to a StringInfo.
                                433                 :                :  *      This is the shared guts of TypeNameToString and TypeNameListToString.
                                434                 :                :  *
                                435                 :                :  * NB: this must work on TypeNames that do not describe any actual type;
                                436                 :                :  * it is mostly used for reporting lookup errors.
                                437                 :                :  */
                                438                 :                : static void
 5386 peter_e@gmx.net           439                 :           2722 : appendTypeNameToBuffer(const TypeName *typeName, StringInfo string)
                                440                 :                : {
                                441         [ +  - ]:           2722 :     if (typeName->names != NIL)
                                442                 :                :     {
                                443                 :                :         /* Emit possibly-qualified name as-is */
                                444                 :                :         ListCell   *l;
                                445                 :                : 
                                446   [ +  -  +  +  :           5549 :         foreach(l, typeName->names)
                                              +  + ]
                                447                 :                :         {
                                448         [ +  + ]:           2827 :             if (l != list_head(typeName->names))
 5999 tgl@sss.pgh.pa.us         449                 :            105 :                 appendStringInfoChar(string, '.');
                                450                 :           2827 :             appendStringInfoString(string, strVal(lfirst(l)));
                                451                 :                :         }
                                452                 :                :     }
                                453                 :                :     else
                                454                 :                :     {
                                455                 :                :         /* Look up internally-specified type */
 5386 peter_e@gmx.net           456                 :UBC           0 :         appendStringInfoString(string, format_type_be(typeName->typeOid));
                                457                 :                :     }
                                458                 :                : 
                                459                 :                :     /*
                                460                 :                :      * Add decoration as needed, but only for fields considered by
                                461                 :                :      * LookupTypeName
                                462                 :                :      */
 5386 peter_e@gmx.net           463         [ +  + ]:CBC        2722 :     if (typeName->pct_type)
 5999 tgl@sss.pgh.pa.us         464                 :             12 :         appendStringInfoString(string, "%TYPE");
                                465                 :                : 
 5386 peter_e@gmx.net           466         [ +  + ]:           2722 :     if (typeName->arrayBounds != NIL)
 5999 tgl@sss.pgh.pa.us         467                 :              3 :         appendStringInfoString(string, "[]");
                                468                 :           2722 : }
                                469                 :                : 
                                470                 :                : /*
                                471                 :                :  * TypeNameToString
                                472                 :                :  *      Produce a string representing the name of a TypeName.
                                473                 :                :  *
                                474                 :                :  * NB: this must work on TypeNames that do not describe any actual type;
                                475                 :                :  * it is mostly used for reporting lookup errors.
                                476                 :                :  */
                                477                 :                : char *
 5386 peter_e@gmx.net           478                 :           2710 : TypeNameToString(const TypeName *typeName)
                                479                 :                : {
                                480                 :                :     StringInfoData string;
                                481                 :                : 
 5999 tgl@sss.pgh.pa.us         482                 :           2710 :     initStringInfo(&string);
 5386 peter_e@gmx.net           483                 :           2710 :     appendTypeNameToBuffer(typeName, &string);
 5999 tgl@sss.pgh.pa.us         484                 :           2710 :     return string.data;
                                485                 :                : }
                                486                 :                : 
                                487                 :                : /*
                                488                 :                :  * TypeNameListToString
                                489                 :                :  *      Produce a string representing the name(s) of a List of TypeNames
                                490                 :                :  */
                                491                 :                : char *
                                492                 :             20 : TypeNameListToString(List *typenames)
                                493                 :                : {
                                494                 :                :     StringInfoData string;
                                495                 :                :     ListCell   *l;
                                496                 :                : 
                                497                 :             20 :     initStringInfo(&string);
                                498   [ +  +  +  +  :             32 :     foreach(l, typenames)
                                              +  + ]
                                499                 :                :     {
 2561                           500                 :             12 :         TypeName   *typeName = lfirst_node(TypeName, l);
                                501                 :                : 
 5999                           502         [ +  + ]:             12 :         if (l != list_head(typenames))
                                503                 :              6 :             appendStringInfoChar(&string, ',');
 5386 peter_e@gmx.net           504                 :             12 :         appendTypeNameToBuffer(typeName, &string);
                                505                 :                :     }
 5999 tgl@sss.pgh.pa.us         506                 :             20 :     return string.data;
                                507                 :                : }
                                508                 :                : 
                                509                 :                : /*
                                510                 :                :  * LookupCollation
                                511                 :                :  *
                                512                 :                :  * Look up collation by name, return OID, with support for error location.
                                513                 :                :  */
                                514                 :                : Oid
 4785                           515                 :           4265 : LookupCollation(ParseState *pstate, List *collnames, int location)
                                516                 :                : {
                                517                 :                :     Oid         colloid;
                                518                 :                :     ParseCallbackState pcbstate;
                                519                 :                : 
                                520         [ +  + ]:           4265 :     if (pstate)
                                521                 :           4060 :         setup_parser_errposition_callback(&pcbstate, pstate, location);
                                522                 :                : 
                                523                 :           4265 :     colloid = get_collation_oid(collnames, false);
                                524                 :                : 
                                525         [ +  + ]:           4259 :     if (pstate)
                                526                 :           4054 :         cancel_parser_errposition_callback(&pcbstate);
                                527                 :                : 
                                528                 :           4259 :     return colloid;
                                529                 :                : }
                                530                 :                : 
                                531                 :                : /*
                                532                 :                :  * GetColumnDefCollation
                                533                 :                :  *
                                534                 :                :  * Get the collation to be used for a column being defined, given the
                                535                 :                :  * ColumnDef node and the previously-determined column type OID.
                                536                 :                :  *
                                537                 :                :  * pstate is only used for error location purposes, and can be NULL.
                                538                 :                :  */
                                539                 :                : Oid
   80 peter@eisentraut.org      540                 :GNC      109573 : GetColumnDefCollation(ParseState *pstate, const ColumnDef *coldef, Oid typeOid)
                                541                 :                : {
                                542                 :                :     Oid         result;
 4785 tgl@sss.pgh.pa.us         543                 :CBC      109573 :     Oid         typcollation = get_typcollation(typeOid);
 3797                           544                 :         109573 :     int         location = coldef->location;
                                545                 :                : 
 4785                           546         [ +  + ]:         109573 :     if (coldef->collClause)
                                547                 :                :     {
                                548                 :                :         /* We have a raw COLLATE clause, so look up the collation */
                                549                 :            205 :         location = coldef->collClause->location;
 4783                           550                 :            205 :         result = LookupCollation(pstate, coldef->collClause->collname,
                                551                 :                :                                  location);
                                552                 :                :     }
 4785                           553         [ +  + ]:         109368 :     else if (OidIsValid(coldef->collOid))
                                554                 :                :     {
                                555                 :                :         /* Precooked collation spec, use that */
                                556                 :          35044 :         result = coldef->collOid;
                                557                 :                :     }
                                558                 :                :     else
                                559                 :                :     {
                                560                 :                :         /* Use the type's default collation if any */
                                561                 :          74324 :         result = typcollation;
                                562                 :                :     }
                                563                 :                : 
                                564                 :                :     /* Complain if COLLATE is applied to an uncollatable type */
                                565   [ +  +  -  + ]:         109573 :     if (OidIsValid(result) && !OidIsValid(typcollation))
 4785 tgl@sss.pgh.pa.us         566         [ #  # ]:UBC           0 :         ereport(ERROR,
                                567                 :                :                 (errcode(ERRCODE_DATATYPE_MISMATCH),
                                568                 :                :                  errmsg("collations are not supported by type %s",
                                569                 :                :                         format_type_be(typeOid)),
                                570                 :                :                  parser_errposition(pstate, location)));
                                571                 :                : 
 4785 tgl@sss.pgh.pa.us         572                 :CBC      109573 :     return result;
                                573                 :                : }
                                574                 :                : 
                                575                 :                : /* return a Type structure, given a type id */
                                576                 :                : /* NB: caller must ReleaseSysCache the type tuple when done with it */
                                577                 :                : Type
 9637 bruce@momjian.us          578                 :         321734 : typeidType(Oid id)
                                579                 :                : {
                                580                 :                :     HeapTuple   tup;
                                581                 :                : 
 5173 rhaas@postgresql.org      582                 :         321734 :     tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(id));
 8550 tgl@sss.pgh.pa.us         583         [ -  + ]:         321734 :     if (!HeapTupleIsValid(tup))
 7575 tgl@sss.pgh.pa.us         584         [ #  # ]:UBC           0 :         elog(ERROR, "cache lookup failed for type %u", id);
 9357 bruce@momjian.us          585                 :CBC      321734 :     return (Type) tup;
                                586                 :                : }
                                587                 :                : 
                                588                 :                : /* given type (as type struct), return the type OID */
                                589                 :                : Oid
 9637                           590                 :          33005 : typeTypeId(Type tp)
                                591                 :                : {
 7575 tgl@sss.pgh.pa.us         592         [ -  + ]:          33005 :     if (tp == NULL)             /* probably useless */
 9596 bruce@momjian.us          593         [ #  # ]:UBC           0 :         elog(ERROR, "typeTypeId() called with NULL type struct");
 1972 andres@anarazel.de        594                 :CBC       33005 :     return ((Form_pg_type) GETSTRUCT(tp))->oid;
                                595                 :                : }
                                596                 :                : 
                                597                 :                : /* given type (as type struct), return the length of type */
                                598                 :                : int16
 9637 bruce@momjian.us          599                 :         311701 : typeLen(Type t)
                                600                 :                : {
                                601                 :                :     Form_pg_type typ;
                                602                 :                : 
 9357                           603                 :         311701 :     typ = (Form_pg_type) GETSTRUCT(t);
                                604                 :         311701 :     return typ->typlen;
                                605                 :                : }
                                606                 :                : 
                                607                 :                : /* given type (as type struct), return its 'byval' attribute */
                                608                 :                : bool
 9637                           609                 :         311701 : typeByVal(Type t)
                                610                 :                : {
                                611                 :                :     Form_pg_type typ;
                                612                 :                : 
 9357                           613                 :         311701 :     typ = (Form_pg_type) GETSTRUCT(t);
                                614                 :         311701 :     return typ->typbyval;
                                615                 :                : }
                                616                 :                : 
                                617                 :                : /* given type (as type struct), return the type's name */
                                618                 :                : char *
 9637 bruce@momjian.us          619                 :UBC           0 : typeTypeName(Type t)
                                620                 :                : {
                                621                 :                :     Form_pg_type typ;
                                622                 :                : 
 9357                           623                 :              0 :     typ = (Form_pg_type) GETSTRUCT(t);
                                624                 :                :     /* pstrdup here because result may need to outlive the syscache entry */
 8713 tgl@sss.pgh.pa.us         625                 :              0 :     return pstrdup(NameStr(typ->typname));
                                626                 :                : }
                                627                 :                : 
                                628                 :                : /* given type (as type struct), return its 'typrelid' attribute */
                                629                 :                : Oid
 8550 tgl@sss.pgh.pa.us         630                 :CBC         333 : typeTypeRelid(Type typ)
                                631                 :                : {
                                632                 :                :     Form_pg_type typtup;
                                633                 :                : 
                                634                 :            333 :     typtup = (Form_pg_type) GETSTRUCT(typ);
                                635                 :            333 :     return typtup->typrelid;
                                636                 :                : }
                                637                 :                : 
                                638                 :                : /* given type (as type struct), return its 'typcollation' attribute */
                                639                 :                : Oid
 4755                           640                 :         311701 : typeTypeCollation(Type typ)
                                641                 :                : {
                                642                 :                :     Form_pg_type typtup;
                                643                 :                : 
                                644                 :         311701 :     typtup = (Form_pg_type) GETSTRUCT(typ);
                                645                 :         311701 :     return typtup->typcollation;
                                646                 :                : }
                                647                 :                : 
                                648                 :                : /*
                                649                 :                :  * Given a type structure and a string, returns the internal representation
                                650                 :                :  * of that string.  The "string" can be NULL to perform conversion of a NULL
                                651                 :                :  * (which might result in failure, if the input function rejects NULLs).
                                652                 :                :  */
                                653                 :                : Datum
 9019                           654                 :         311701 : stringTypeDatum(Type tp, char *string, int32 atttypmod)
                                655                 :                : {
 5847                           656                 :         311701 :     Form_pg_type typform = (Form_pg_type) GETSTRUCT(tp);
                                657                 :         311701 :     Oid         typinput = typform->typinput;
                                658                 :         311701 :     Oid         typioparam = getTypeIOParam(tp);
                                659                 :                : 
 3006                           660                 :         311701 :     return OidInputFunctionCall(typinput, string, typioparam, atttypmod);
                                661                 :                : }
                                662                 :                : 
                                663                 :                : /*
                                664                 :                :  * Given a typeid, return the type's typrelid (associated relation), if any.
                                665                 :                :  * Returns InvalidOid if type is not a composite type.
                                666                 :                :  */
                                667                 :                : Oid
 9637 bruce@momjian.us          668                 :           6572 : typeidTypeRelid(Oid type_id)
                                669                 :                : {
                                670                 :                :     HeapTuple   typeTuple;
                                671                 :                :     Form_pg_type type;
                                672                 :                :     Oid         result;
                                673                 :                : 
 5173 rhaas@postgresql.org      674                 :           6572 :     typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type_id));
 9637 bruce@momjian.us          675         [ -  + ]:           6572 :     if (!HeapTupleIsValid(typeTuple))
 7575 tgl@sss.pgh.pa.us         676         [ #  # ]:UBC           0 :         elog(ERROR, "cache lookup failed for type %u", type_id);
 9357 bruce@momjian.us          677                 :CBC        6572 :     type = (Form_pg_type) GETSTRUCT(typeTuple);
 8550 tgl@sss.pgh.pa.us         678                 :           6572 :     result = type->typrelid;
                                679                 :           6572 :     ReleaseSysCache(typeTuple);
 2362                           680                 :           6572 :     return result;
                                681                 :                : }
                                682                 :                : 
                                683                 :                : /*
                                684                 :                :  * Given a typeid, return the type's typrelid (associated relation), if any.
                                685                 :                :  * Returns InvalidOid if type is not a composite type or a domain over one.
                                686                 :                :  * This is the same as typeidTypeRelid(getBaseType(type_id)), but faster.
                                687                 :                :  */
                                688                 :                : Oid
                                689                 :         734321 : typeOrDomainTypeRelid(Oid type_id)
                                690                 :                : {
                                691                 :                :     HeapTuple   typeTuple;
                                692                 :                :     Form_pg_type type;
                                693                 :                :     Oid         result;
                                694                 :                : 
                                695                 :                :     for (;;)
                                696                 :                :     {
                                697                 :         759112 :         typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type_id));
                                698         [ -  + ]:         759112 :         if (!HeapTupleIsValid(typeTuple))
 2362 tgl@sss.pgh.pa.us         699         [ #  # ]:UBC           0 :             elog(ERROR, "cache lookup failed for type %u", type_id);
 2362 tgl@sss.pgh.pa.us         700                 :CBC      759112 :         type = (Form_pg_type) GETSTRUCT(typeTuple);
                                701         [ +  + ]:         759112 :         if (type->typtype != TYPTYPE_DOMAIN)
                                702                 :                :         {
                                703                 :                :             /* Not a domain, so done looking through domains */
                                704                 :         734321 :             break;
                                705                 :                :         }
                                706                 :                :         /* It is a domain, so examine the base type instead */
                                707                 :          24791 :         type_id = type->typbasetype;
                                708                 :          24791 :         ReleaseSysCache(typeTuple);
                                709                 :                :     }
                                710                 :         734321 :     result = type->typrelid;
                                711                 :         734321 :     ReleaseSysCache(typeTuple);
 8550                           712                 :         734321 :     return result;
                                713                 :                : }
                                714                 :                : 
                                715                 :                : /*
                                716                 :                :  * error context callback for parse failure during parseTypeString()
                                717                 :                :  */
                                718                 :                : static void
 7482                           719                 :              3 : pts_error_callback(void *arg)
                                720                 :                : {
                                721                 :              3 :     const char *str = (const char *) arg;
                                722                 :                : 
                                723                 :              3 :     errcontext("invalid type name \"%s\"", str);
                                724                 :              3 : }
                                725                 :                : 
                                726                 :                : /*
                                727                 :                :  * Given a string that is supposed to be a SQL-compatible type declaration,
                                728                 :                :  * such as "int4" or "integer" or "character varying(32)", parse
                                729                 :                :  * the string and return the result as a TypeName.
                                730                 :                :  *
                                731                 :                :  * If the string cannot be parsed as a type, an error is raised,
                                732                 :                :  * unless escontext is an ErrorSaveContext node, in which case we may
                                733                 :                :  * fill that and return NULL.  But note that the ErrorSaveContext option
                                734                 :                :  * is mostly aspirational at present: errors detected by the main
                                735                 :                :  * grammar, rather than here, will still be thrown.
                                736                 :                :  */
                                737                 :                : TypeName *
  474                           738                 :           5195 : typeStringToTypeName(const char *str, Node *escontext)
                                739                 :                : {
                                740                 :                :     List       *raw_parsetree_list;
                                741                 :                :     TypeName   *typeName;
                                742                 :                :     ErrorContextCallback ptserrcontext;
                                743                 :                : 
                                744                 :                :     /* make sure we give useful error for empty input */
  283 michael@paquier.xyz       745         [ -  + ]:GNC        5195 :     if (strspn(str, " \t\n\r\f\v") == strlen(str))
 7482 tgl@sss.pgh.pa.us         746                 :UBC           0 :         goto fail;
                                747                 :                : 
                                748                 :                :     /*
                                749                 :                :      * Setup error traceback support in case of ereport() during parse
                                750                 :                :      */
 7482 tgl@sss.pgh.pa.us         751                 :CBC        5195 :     ptserrcontext.callback = pts_error_callback;
 1902 peter@eisentraut.org      752                 :           5195 :     ptserrcontext.arg = unconstify(char *, str);
 7482 tgl@sss.pgh.pa.us         753                 :           5195 :     ptserrcontext.previous = error_context_stack;
                                754                 :           5195 :     error_context_stack = &ptserrcontext;
                                755                 :                : 
 1196                           756                 :           5195 :     raw_parsetree_list = raw_parser(str, RAW_PARSE_TYPE_NAME);
                                757                 :                : 
 7482                           758                 :           5192 :     error_context_stack = ptserrcontext.previous;
                                759                 :                : 
                                760                 :                :     /* We should get back exactly one TypeName node. */
 1196                           761         [ -  + ]:           5192 :     Assert(list_length(raw_parsetree_list) == 1);
                                762                 :           5192 :     typeName = linitial_node(TypeName, raw_parsetree_list);
                                763                 :                : 
                                764                 :                :     /* The grammar allows SETOF in TypeName, but we don't want that here. */
 5386 peter_e@gmx.net           765         [ -  + ]:           5192 :     if (typeName->setof)
 7060 tgl@sss.pgh.pa.us         766                 :UBC           0 :         goto fail;
                                767                 :                : 
 3400 alvherre@alvh.no-ip.      768                 :CBC        5192 :     return typeName;
                                769                 :                : 
 3400 alvherre@alvh.no-ip.      770                 :UBC           0 : fail:
  474 tgl@sss.pgh.pa.us         771         [ #  # ]:              0 :     ereturn(escontext, NULL,
                                772                 :                :             (errcode(ERRCODE_SYNTAX_ERROR),
                                773                 :                :              errmsg("invalid type name \"%s\"", str)));
                                774                 :                : }
                                775                 :                : 
                                776                 :                : /*
                                777                 :                :  * Given a string that is supposed to be a SQL-compatible type declaration,
                                778                 :                :  * such as "int4" or "integer" or "character varying(32)", parse
                                779                 :                :  * the string and convert it to a type OID and type modifier.
                                780                 :                :  *
                                781                 :                :  * If escontext is an ErrorSaveContext node, then errors are reported by
                                782                 :                :  * filling escontext and returning false, instead of throwing them.
                                783                 :                :  */
                                784                 :                : bool
  474 tgl@sss.pgh.pa.us         785                 :CBC        1675 : parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p,
                                786                 :                :                 Node *escontext)
                                787                 :                : {
                                788                 :                :     TypeName   *typeName;
                                789                 :                :     Type        tup;
                                790                 :                : 
                                791                 :           1675 :     typeName = typeStringToTypeName(str, escontext);
                                792         [ -  + ]:           1672 :     if (typeName == NULL)
  474 tgl@sss.pgh.pa.us         793                 :UBC           0 :         return false;
                                794                 :                : 
  474 tgl@sss.pgh.pa.us         795                 :CBC        1672 :     tup = LookupTypeName(NULL, typeName, typmod_p,
                                796   [ +  +  +  - ]:           1672 :                          (escontext && IsA(escontext, ErrorSaveContext)));
 3659 rhaas@postgresql.org      797         [ +  + ]:           1660 :     if (tup == NULL)
                                798                 :                :     {
  474 tgl@sss.pgh.pa.us         799         [ +  + ]:             20 :         ereturn(escontext, false,
                                800                 :                :                 (errcode(ERRCODE_UNDEFINED_OBJECT),
                                801                 :                :                  errmsg("type \"%s\" does not exist",
                                802                 :                :                         TypeNameToString(typeName))));
                                803                 :                :     }
                                804                 :                :     else
                                805                 :                :     {
 1972 andres@anarazel.de        806                 :           1640 :         Form_pg_type typ = (Form_pg_type) GETSTRUCT(tup);
                                807                 :                : 
                                808         [ -  + ]:           1640 :         if (!typ->typisdefined)
                                809                 :                :         {
  474 tgl@sss.pgh.pa.us         810                 :UBC           0 :             ReleaseSysCache(tup);
                                811         [ #  # ]:              0 :             ereturn(escontext, false,
                                812                 :                :                     (errcode(ERRCODE_UNDEFINED_OBJECT),
                                813                 :                :                      errmsg("type \"%s\" is only a shell",
                                814                 :                :                             TypeNameToString(typeName))));
                                815                 :                :         }
 1972 andres@anarazel.de        816                 :CBC        1640 :         *typeid_p = typ->oid;
 3659 rhaas@postgresql.org      817                 :           1640 :         ReleaseSysCache(tup);
                                818                 :                :     }
                                819                 :                : 
  474 tgl@sss.pgh.pa.us         820                 :           1640 :     return true;
                                821                 :                : }
        

Generated by: LCOV version 2.1-beta2-3-g6141622