LCOV - code coverage report
Current view: top level - src/backend/utils/adt - name.c (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 92.9 % 113 105
Test Date: 2026-07-21 04:15:46 Functions: 100.0 % 20 20
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 60.0 % 30 18

             Branch data     Line data    Source code
       1                 :             : /*-------------------------------------------------------------------------
       2                 :             :  *
       3                 :             :  * name.c
       4                 :             :  *    Functions for the built-in type "name".
       5                 :             :  *
       6                 :             :  * name replaces char16 and is carefully implemented so that it
       7                 :             :  * is a string of physical length NAMEDATALEN.
       8                 :             :  * DO NOT use hard-coded constants anywhere
       9                 :             :  * always use NAMEDATALEN as the symbolic constant!   - jolly 8/21/95
      10                 :             :  *
      11                 :             :  *
      12                 :             :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
      13                 :             :  * Portions Copyright (c) 1994, Regents of the University of California
      14                 :             :  *
      15                 :             :  *
      16                 :             :  * IDENTIFICATION
      17                 :             :  *    src/backend/utils/adt/name.c
      18                 :             :  *
      19                 :             :  *-------------------------------------------------------------------------
      20                 :             :  */
      21                 :             : #include "postgres.h"
      22                 :             : 
      23                 :             : #include "catalog/namespace.h"
      24                 :             : #include "catalog/pg_collation.h"
      25                 :             : #include "catalog/pg_type.h"
      26                 :             : #include "libpq/pqformat.h"
      27                 :             : #include "mb/pg_wchar.h"
      28                 :             : #include "miscadmin.h"
      29                 :             : #include "utils/array.h"
      30                 :             : #include "utils/builtins.h"
      31                 :             : #include "utils/lsyscache.h"
      32                 :             : #include "utils/varlena.h"
      33                 :             : 
      34                 :             : 
      35                 :             : /*****************************************************************************
      36                 :             :  *   USER I/O ROUTINES (none)                                                *
      37                 :             :  *****************************************************************************/
      38                 :             : 
      39                 :             : 
      40                 :             : /*
      41                 :             :  *      namein  - converts cstring to internal representation
      42                 :             :  *
      43                 :             :  *      Note:
      44                 :             :  *              [Old] Currently if strlen(s) < NAMEDATALEN, the extra chars are nulls
      45                 :             :  *              Now, always NULL terminated
      46                 :             :  */
      47                 :             : Datum
      48                 :      595326 : namein(PG_FUNCTION_ARGS)
      49                 :             : {
      50                 :      595326 :     char       *s = PG_GETARG_CSTRING(0);
      51                 :             :     Name        result;
      52                 :             :     int         len;
      53                 :             : 
      54                 :      595326 :     len = strlen(s);
      55                 :             : 
      56                 :             :     /* Truncate oversize input */
      57         [ +  + ]:      595326 :     if (len >= NAMEDATALEN)
      58                 :          36 :         len = pg_mbcliplen(s, len, NAMEDATALEN - 1);
      59                 :             : 
      60                 :             :     /* We use palloc0 here to ensure result is zero-padded */
      61                 :      595326 :     result = (Name) palloc0(NAMEDATALEN);
      62                 :      595326 :     memcpy(NameStr(*result), s, len);
      63                 :             : 
      64                 :      595326 :     PG_RETURN_NAME(result);
      65                 :             : }
      66                 :             : 
      67                 :             : /*
      68                 :             :  *      nameout - converts internal representation to cstring
      69                 :             :  */
      70                 :             : Datum
      71                 :     1364632 : nameout(PG_FUNCTION_ARGS)
      72                 :             : {
      73                 :     1364632 :     Name        s = PG_GETARG_NAME(0);
      74                 :             : 
      75                 :     1364632 :     PG_RETURN_CSTRING(pstrdup(NameStr(*s)));
      76                 :             : }
      77                 :             : 
      78                 :             : /*
      79                 :             :  *      namerecv            - converts external binary format to name
      80                 :             :  */
      81                 :             : Datum
      82                 :           4 : namerecv(PG_FUNCTION_ARGS)
      83                 :             : {
      84                 :           4 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
      85                 :             :     Name        result;
      86                 :             :     char       *str;
      87                 :             :     int         nbytes;
      88                 :             : 
      89                 :           4 :     str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
      90         [ -  + ]:           4 :     if (nbytes >= NAMEDATALEN)
      91         [ #  # ]:           0 :         ereport(ERROR,
      92                 :             :                 (errcode(ERRCODE_NAME_TOO_LONG),
      93                 :             :                  errmsg("identifier too long"),
      94                 :             :                  errdetail("Identifier must be less than %d characters.",
      95                 :             :                            NAMEDATALEN)));
      96                 :           4 :     result = (NameData *) palloc0(NAMEDATALEN);
      97                 :           4 :     memcpy(result, str, nbytes);
      98                 :           4 :     pfree(str);
      99                 :           4 :     PG_RETURN_NAME(result);
     100                 :             : }
     101                 :             : 
     102                 :             : /*
     103                 :             :  *      namesend            - converts name to binary format
     104                 :             :  */
     105                 :             : Datum
     106                 :           4 : namesend(PG_FUNCTION_ARGS)
     107                 :             : {
     108                 :           4 :     Name        s = PG_GETARG_NAME(0);
     109                 :             :     StringInfoData buf;
     110                 :             : 
     111                 :           4 :     pq_begintypsend(&buf);
     112                 :           4 :     pq_sendtext(&buf, NameStr(*s), strlen(NameStr(*s)));
     113                 :           4 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
     114                 :             : }
     115                 :             : 
     116                 :             : 
     117                 :             : /*****************************************************************************
     118                 :             :  *   COMPARISON/SORTING ROUTINES                                             *
     119                 :             :  *****************************************************************************/
     120                 :             : 
     121                 :             : /*
     122                 :             :  *      nameeq  - returns 1 iff arguments are equal
     123                 :             :  *      namene  - returns 1 iff arguments are not equal
     124                 :             :  *      namelt  - returns 1 iff a < b
     125                 :             :  *      namele  - returns 1 iff a <= b
     126                 :             :  *      namegt  - returns 1 iff a > b
     127                 :             :  *      namege  - returns 1 iff a >= b
     128                 :             :  *
     129                 :             :  * Note that the use of strncmp with NAMEDATALEN limit is mostly historical;
     130                 :             :  * strcmp would do as well, because we do not allow NAME values that don't
     131                 :             :  * have a '\0' terminator.  Whatever might be past the terminator is not
     132                 :             :  * considered relevant to comparisons.
     133                 :             :  */
     134                 :             : static int
     135                 :    24490988 : namecmp(Name arg1, Name arg2, Oid collid)
     136                 :             : {
     137                 :             :     /* Fast path for common case used in system catalogs */
     138         [ +  - ]:    24490988 :     if (collid == C_COLLATION_OID)
     139                 :    24490988 :         return strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN);
     140                 :             : 
     141                 :             :     /* Else rely on the varstr infrastructure */
     142                 :           0 :     return varstr_cmp(NameStr(*arg1), strlen(NameStr(*arg1)),
     143                 :           0 :                       NameStr(*arg2), strlen(NameStr(*arg2)),
     144                 :             :                       collid);
     145                 :             : }
     146                 :             : 
     147                 :             : Datum
     148                 :     9352086 : nameeq(PG_FUNCTION_ARGS)
     149                 :             : {
     150                 :     9352086 :     Name        arg1 = PG_GETARG_NAME(0);
     151                 :     9352086 :     Name        arg2 = PG_GETARG_NAME(1);
     152                 :             : 
     153                 :     9352086 :     PG_RETURN_BOOL(namecmp(arg1, arg2, PG_GET_COLLATION()) == 0);
     154                 :             : }
     155                 :             : 
     156                 :             : Datum
     157                 :       35210 : namene(PG_FUNCTION_ARGS)
     158                 :             : {
     159                 :       35210 :     Name        arg1 = PG_GETARG_NAME(0);
     160                 :       35210 :     Name        arg2 = PG_GETARG_NAME(1);
     161                 :             : 
     162                 :       35210 :     PG_RETURN_BOOL(namecmp(arg1, arg2, PG_GET_COLLATION()) != 0);
     163                 :             : }
     164                 :             : 
     165                 :             : Datum
     166                 :       79936 : namelt(PG_FUNCTION_ARGS)
     167                 :             : {
     168                 :       79936 :     Name        arg1 = PG_GETARG_NAME(0);
     169                 :       79936 :     Name        arg2 = PG_GETARG_NAME(1);
     170                 :             : 
     171                 :       79936 :     PG_RETURN_BOOL(namecmp(arg1, arg2, PG_GET_COLLATION()) < 0);
     172                 :             : }
     173                 :             : 
     174                 :             : Datum
     175                 :       11034 : namele(PG_FUNCTION_ARGS)
     176                 :             : {
     177                 :       11034 :     Name        arg1 = PG_GETARG_NAME(0);
     178                 :       11034 :     Name        arg2 = PG_GETARG_NAME(1);
     179                 :             : 
     180                 :       11034 :     PG_RETURN_BOOL(namecmp(arg1, arg2, PG_GET_COLLATION()) <= 0);
     181                 :             : }
     182                 :             : 
     183                 :             : Datum
     184                 :        5755 : namegt(PG_FUNCTION_ARGS)
     185                 :             : {
     186                 :        5755 :     Name        arg1 = PG_GETARG_NAME(0);
     187                 :        5755 :     Name        arg2 = PG_GETARG_NAME(1);
     188                 :             : 
     189                 :        5755 :     PG_RETURN_BOOL(namecmp(arg1, arg2, PG_GET_COLLATION()) > 0);
     190                 :             : }
     191                 :             : 
     192                 :             : Datum
     193                 :       12764 : namege(PG_FUNCTION_ARGS)
     194                 :             : {
     195                 :       12764 :     Name        arg1 = PG_GETARG_NAME(0);
     196                 :       12764 :     Name        arg2 = PG_GETARG_NAME(1);
     197                 :             : 
     198                 :       12764 :     PG_RETURN_BOOL(namecmp(arg1, arg2, PG_GET_COLLATION()) >= 0);
     199                 :             : }
     200                 :             : 
     201                 :             : Datum
     202                 :    14994203 : btnamecmp(PG_FUNCTION_ARGS)
     203                 :             : {
     204                 :    14994203 :     Name        arg1 = PG_GETARG_NAME(0);
     205                 :    14994203 :     Name        arg2 = PG_GETARG_NAME(1);
     206                 :             : 
     207                 :    14994203 :     PG_RETURN_INT32(namecmp(arg1, arg2, PG_GET_COLLATION()));
     208                 :             : }
     209                 :             : 
     210                 :             : Datum
     211                 :       35388 : btnamesortsupport(PG_FUNCTION_ARGS)
     212                 :             : {
     213                 :       35388 :     SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
     214                 :       35388 :     Oid         collid = ssup->ssup_collation;
     215                 :             :     MemoryContext oldcontext;
     216                 :             : 
     217                 :       35388 :     oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
     218                 :             : 
     219                 :             :     /* Use generic string SortSupport */
     220                 :       35388 :     varstr_sortsupport(ssup, NAMEOID, collid);
     221                 :             : 
     222                 :       35388 :     MemoryContextSwitchTo(oldcontext);
     223                 :             : 
     224                 :       35388 :     PG_RETURN_VOID();
     225                 :             : }
     226                 :             : 
     227                 :             : 
     228                 :             : /*****************************************************************************
     229                 :             :  *   MISCELLANEOUS PUBLIC ROUTINES                                           *
     230                 :             :  *****************************************************************************/
     231                 :             : 
     232                 :             : void
     233                 :     6284805 : namestrcpy(Name name, const char *str)
     234                 :             : {
     235                 :             :     /* NB: We need to zero-pad the destination. */
     236                 :     6284805 :     strncpy(NameStr(*name), str, NAMEDATALEN);
     237                 :     6284805 :     NameStr(*name)[NAMEDATALEN - 1] = '\0';
     238                 :     6284805 : }
     239                 :             : 
     240                 :             : /*
     241                 :             :  * Compare a NAME to a C string
     242                 :             :  *
     243                 :             :  * Assumes C collation always; be careful when using this for
     244                 :             :  * anything but equality checks!
     245                 :             :  */
     246                 :             : int
     247                 :     5232866 : namestrcmp(Name name, const char *str)
     248                 :             : {
     249   [ -  +  -  - ]:     5232866 :     if (!name && !str)
     250                 :           0 :         return 0;
     251         [ -  + ]:     5232866 :     if (!name)
     252                 :           0 :         return -1;              /* NULL < anything */
     253         [ -  + ]:     5232866 :     if (!str)
     254                 :           0 :         return 1;               /* NULL < anything */
     255                 :     5232866 :     return strncmp(NameStr(*name), str, NAMEDATALEN);
     256                 :             : }
     257                 :             : 
     258                 :             : 
     259                 :             : /*
     260                 :             :  * SQL-functions CURRENT_USER, SESSION_USER
     261                 :             :  */
     262                 :             : Datum
     263                 :       10679 : current_user(PG_FUNCTION_ARGS)
     264                 :             : {
     265                 :       10679 :     PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(GetUserNameFromId(GetUserId(), false))));
     266                 :             : }
     267                 :             : 
     268                 :             : Datum
     269                 :         306 : session_user(PG_FUNCTION_ARGS)
     270                 :             : {
     271                 :         306 :     PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(GetUserNameFromId(GetSessionUserId(), false))));
     272                 :             : }
     273                 :             : 
     274                 :             : 
     275                 :             : /*
     276                 :             :  * SQL-functions CURRENT_SCHEMA, CURRENT_SCHEMAS
     277                 :             :  */
     278                 :             : Datum
     279                 :          21 : current_schema(PG_FUNCTION_ARGS)
     280                 :             : {
     281                 :          21 :     List       *search_path = fetch_search_path(false);
     282                 :             :     char       *nspname;
     283                 :             : 
     284         [ +  + ]:          21 :     if (search_path == NIL)
     285                 :           4 :         PG_RETURN_NULL();
     286                 :          17 :     nspname = get_namespace_name(linitial_oid(search_path));
     287                 :          17 :     list_free(search_path);
     288         [ -  + ]:          17 :     if (!nspname)
     289                 :           0 :         PG_RETURN_NULL();       /* recently-deleted namespace? */
     290                 :          17 :     PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(nspname)));
     291                 :             : }
     292                 :             : 
     293                 :             : Datum
     294                 :         279 : current_schemas(PG_FUNCTION_ARGS)
     295                 :             : {
     296                 :         279 :     List       *search_path = fetch_search_path(PG_GETARG_BOOL(0));
     297                 :             :     ListCell   *l;
     298                 :             :     Datum      *names;
     299                 :             :     int         i;
     300                 :             :     ArrayType  *array;
     301                 :             : 
     302                 :         279 :     names = (Datum *) palloc(list_length(search_path) * sizeof(Datum));
     303                 :         279 :     i = 0;
     304   [ +  +  +  +  :         451 :     foreach(l, search_path)
                   +  + ]
     305                 :             :     {
     306                 :             :         char       *nspname;
     307                 :             : 
     308                 :         172 :         nspname = get_namespace_name(lfirst_oid(l));
     309         [ +  - ]:         172 :         if (nspname)            /* watch out for deleted namespace */
     310                 :             :         {
     311                 :         172 :             names[i] = DirectFunctionCall1(namein, CStringGetDatum(nspname));
     312                 :         172 :             i++;
     313                 :             :         }
     314                 :             :     }
     315                 :         279 :     list_free(search_path);
     316                 :             : 
     317                 :         279 :     array = construct_array_builtin(names, i, NAMEOID);
     318                 :             : 
     319                 :         279 :     PG_RETURN_POINTER(array);
     320                 :             : }
     321                 :             : 
     322                 :             : /*
     323                 :             :  * SQL-function nameconcatoid(name, oid) returns name
     324                 :             :  *
     325                 :             :  * This is used in the information_schema to produce specific_name columns,
     326                 :             :  * which are supposed to be unique per schema.  We achieve that (in an ugly
     327                 :             :  * way) by appending the object's OID.  The result is the same as
     328                 :             :  *      ($1::text || '_' || $2::text)::name
     329                 :             :  * except that, if it would not fit in NAMEDATALEN, we make it do so by
     330                 :             :  * truncating the name input (not the oid).
     331                 :             :  */
     332                 :             : Datum
     333                 :       22164 : nameconcatoid(PG_FUNCTION_ARGS)
     334                 :             : {
     335                 :       22164 :     Name        nam = PG_GETARG_NAME(0);
     336                 :       22164 :     Oid         oid = PG_GETARG_OID(1);
     337                 :             :     Name        result;
     338                 :             :     char        suffix[20];
     339                 :             :     int         suflen;
     340                 :             :     int         namlen;
     341                 :             : 
     342                 :       22164 :     suflen = snprintf(suffix, sizeof(suffix), "_%u", oid);
     343                 :       22164 :     namlen = strlen(NameStr(*nam));
     344                 :             : 
     345                 :             :     /* Truncate oversize input by truncating name part, not suffix */
     346         [ -  + ]:       22164 :     if (namlen + suflen >= NAMEDATALEN)
     347                 :           0 :         namlen = pg_mbcliplen(NameStr(*nam), namlen, NAMEDATALEN - 1 - suflen);
     348                 :             : 
     349                 :             :     /* We use palloc0 here to ensure result is zero-padded */
     350                 :       22164 :     result = (Name) palloc0(NAMEDATALEN);
     351                 :       22164 :     memcpy(NameStr(*result), NameStr(*nam), namlen);
     352                 :       22164 :     memcpy(NameStr(*result) + namlen, suffix, suflen);
     353                 :             : 
     354                 :       22164 :     PG_RETURN_NAME(result);
     355                 :             : }
        

Generated by: LCOV version 2.0-1