LCOV - code coverage report
Current view: top level - src/backend/utils/adt - name.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 94.0 % 150 141
Test Date: 2026-01-26 10:56:24 Functions: 100.0 % 20 20
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 53.1 % 32 17

             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                 :       71669 : namein(PG_FUNCTION_ARGS)
      49                 :             : {
      50                 :       71669 :         char       *s = PG_GETARG_CSTRING(0);
      51                 :       71669 :         Name            result;
      52                 :       71669 :         int                     len;
      53                 :             : 
      54                 :       71669 :         len = strlen(s);
      55                 :             : 
      56                 :             :         /* Truncate oversize input */
      57         [ +  + ]:       71669 :         if (len >= NAMEDATALEN)
      58                 :           9 :                 len = pg_mbcliplen(s, len, NAMEDATALEN - 1);
      59                 :             : 
      60                 :             :         /* We use palloc0 here to ensure result is zero-padded */
      61                 :       71669 :         result = (Name) palloc0(NAMEDATALEN);
      62                 :       71669 :         memcpy(NameStr(*result), s, len);
      63                 :             : 
      64                 :      143338 :         PG_RETURN_NAME(result);
      65                 :       71669 : }
      66                 :             : 
      67                 :             : /*
      68                 :             :  *              nameout - converts internal representation to cstring
      69                 :             :  */
      70                 :             : Datum
      71                 :       33928 : nameout(PG_FUNCTION_ARGS)
      72                 :             : {
      73                 :       33928 :         Name            s = PG_GETARG_NAME(0);
      74                 :             : 
      75                 :       67856 :         PG_RETURN_CSTRING(pstrdup(NameStr(*s)));
      76                 :       33928 : }
      77                 :             : 
      78                 :             : /*
      79                 :             :  *              namerecv                        - converts external binary format to name
      80                 :             :  */
      81                 :             : Datum
      82                 :           1 : namerecv(PG_FUNCTION_ARGS)
      83                 :             : {
      84                 :           1 :         StringInfo      buf = (StringInfo) PG_GETARG_POINTER(0);
      85                 :           1 :         Name            result;
      86                 :           1 :         char       *str;
      87                 :           1 :         int                     nbytes;
      88                 :             : 
      89                 :           1 :         str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
      90         [ +  - ]:           1 :         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                 :           1 :         result = (NameData *) palloc0(NAMEDATALEN);
      97                 :           1 :         memcpy(result, str, nbytes);
      98                 :           1 :         pfree(str);
      99                 :           2 :         PG_RETURN_NAME(result);
     100                 :           1 : }
     101                 :             : 
     102                 :             : /*
     103                 :             :  *              namesend                        - converts name to binary format
     104                 :             :  */
     105                 :             : Datum
     106                 :           1 : namesend(PG_FUNCTION_ARGS)
     107                 :             : {
     108                 :           1 :         Name            s = PG_GETARG_NAME(0);
     109                 :           1 :         StringInfoData buf;
     110                 :             : 
     111                 :           1 :         pq_begintypsend(&buf);
     112                 :           1 :         pq_sendtext(&buf, NameStr(*s), strlen(NameStr(*s)));
     113                 :           2 :         PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
     114                 :           1 : }
     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                 :     2245010 : namecmp(Name arg1, Name arg2, Oid collid)
     136                 :             : {
     137                 :             :         /* Fast path for common case used in system catalogs */
     138         [ +  - ]:     2245010 :         if (collid == C_COLLATION_OID)
     139                 :     2245010 :                 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                 :           0 :                                           collid);
     145                 :     2245010 : }
     146                 :             : 
     147                 :             : Datum
     148                 :      433720 : nameeq(PG_FUNCTION_ARGS)
     149                 :             : {
     150                 :      433720 :         Name            arg1 = PG_GETARG_NAME(0);
     151                 :      433720 :         Name            arg2 = PG_GETARG_NAME(1);
     152                 :             : 
     153                 :      867440 :         PG_RETURN_BOOL(namecmp(arg1, arg2, PG_GET_COLLATION()) == 0);
     154                 :      433720 : }
     155                 :             : 
     156                 :             : Datum
     157                 :        5929 : namene(PG_FUNCTION_ARGS)
     158                 :             : {
     159                 :        5929 :         Name            arg1 = PG_GETARG_NAME(0);
     160                 :        5929 :         Name            arg2 = PG_GETARG_NAME(1);
     161                 :             : 
     162                 :       11858 :         PG_RETURN_BOOL(namecmp(arg1, arg2, PG_GET_COLLATION()) != 0);
     163                 :        5929 : }
     164                 :             : 
     165                 :             : Datum
     166                 :       15589 : namelt(PG_FUNCTION_ARGS)
     167                 :             : {
     168                 :       15589 :         Name            arg1 = PG_GETARG_NAME(0);
     169                 :       15589 :         Name            arg2 = PG_GETARG_NAME(1);
     170                 :             : 
     171                 :       31178 :         PG_RETURN_BOOL(namecmp(arg1, arg2, PG_GET_COLLATION()) < 0);
     172                 :       15589 : }
     173                 :             : 
     174                 :             : Datum
     175                 :        2565 : namele(PG_FUNCTION_ARGS)
     176                 :             : {
     177                 :        2565 :         Name            arg1 = PG_GETARG_NAME(0);
     178                 :        2565 :         Name            arg2 = PG_GETARG_NAME(1);
     179                 :             : 
     180                 :        5130 :         PG_RETURN_BOOL(namecmp(arg1, arg2, PG_GET_COLLATION()) <= 0);
     181                 :        2565 : }
     182                 :             : 
     183                 :             : Datum
     184                 :        1170 : namegt(PG_FUNCTION_ARGS)
     185                 :             : {
     186                 :        1170 :         Name            arg1 = PG_GETARG_NAME(0);
     187                 :        1170 :         Name            arg2 = PG_GETARG_NAME(1);
     188                 :             : 
     189                 :        2340 :         PG_RETURN_BOOL(namecmp(arg1, arg2, PG_GET_COLLATION()) > 0);
     190                 :        1170 : }
     191                 :             : 
     192                 :             : Datum
     193                 :        3024 : namege(PG_FUNCTION_ARGS)
     194                 :             : {
     195                 :        3024 :         Name            arg1 = PG_GETARG_NAME(0);
     196                 :        3024 :         Name            arg2 = PG_GETARG_NAME(1);
     197                 :             : 
     198                 :        6048 :         PG_RETURN_BOOL(namecmp(arg1, arg2, PG_GET_COLLATION()) >= 0);
     199                 :        3024 : }
     200                 :             : 
     201                 :             : Datum
     202                 :     1783013 : btnamecmp(PG_FUNCTION_ARGS)
     203                 :             : {
     204                 :     1783013 :         Name            arg1 = PG_GETARG_NAME(0);
     205                 :     1783013 :         Name            arg2 = PG_GETARG_NAME(1);
     206                 :             : 
     207                 :     3566026 :         PG_RETURN_INT32(namecmp(arg1, arg2, PG_GET_COLLATION()));
     208                 :     1783013 : }
     209                 :             : 
     210                 :             : Datum
     211                 :        6068 : btnamesortsupport(PG_FUNCTION_ARGS)
     212                 :             : {
     213                 :        6068 :         SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
     214                 :        6068 :         Oid                     collid = ssup->ssup_collation;
     215                 :        6068 :         MemoryContext oldcontext;
     216                 :             : 
     217                 :        6068 :         oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
     218                 :             : 
     219                 :             :         /* Use generic string SortSupport */
     220                 :        6068 :         varstr_sortsupport(ssup, NAMEOID, collid);
     221                 :             : 
     222                 :        6068 :         MemoryContextSwitchTo(oldcontext);
     223                 :             : 
     224                 :        6068 :         PG_RETURN_VOID();
     225                 :        6068 : }
     226                 :             : 
     227                 :             : 
     228                 :             : /*****************************************************************************
     229                 :             :  *       MISCELLANEOUS PUBLIC ROUTINES                                                                                   *
     230                 :             :  *****************************************************************************/
     231                 :             : 
     232                 :             : void
     233                 :     2414458 : namestrcpy(Name name, const char *str)
     234                 :             : {
     235                 :             :         /* NB: We need to zero-pad the destination. */
     236                 :     2414458 :         strncpy(NameStr(*name), str, NAMEDATALEN);
     237                 :     2414458 :         NameStr(*name)[NAMEDATALEN - 1] = '\0';
     238                 :     2414458 : }
     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                 :       24146 : namestrcmp(Name name, const char *str)
     248                 :             : {
     249   [ -  +  #  # ]:       24146 :         if (!name && !str)
     250                 :           0 :                 return 0;
     251         [ +  - ]:       24146 :         if (!name)
     252                 :           0 :                 return -1;                              /* NULL < anything */
     253         [ +  - ]:       24146 :         if (!str)
     254                 :           0 :                 return 1;                               /* NULL < anything */
     255                 :       24146 :         return strncmp(NameStr(*name), str, NAMEDATALEN);
     256                 :       24146 : }
     257                 :             : 
     258                 :             : 
     259                 :             : /*
     260                 :             :  * SQL-functions CURRENT_USER, SESSION_USER
     261                 :             :  */
     262                 :             : Datum
     263                 :        1194 : current_user(PG_FUNCTION_ARGS)
     264                 :             : {
     265                 :        1194 :         PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(GetUserNameFromId(GetUserId(), false))));
     266                 :             : }
     267                 :             : 
     268                 :             : Datum
     269                 :          17 : session_user(PG_FUNCTION_ARGS)
     270                 :             : {
     271                 :          17 :         PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(GetUserNameFromId(GetSessionUserId(), false))));
     272                 :             : }
     273                 :             : 
     274                 :             : 
     275                 :             : /*
     276                 :             :  * SQL-functions CURRENT_SCHEMA, CURRENT_SCHEMAS
     277                 :             :  */
     278                 :             : Datum
     279                 :           4 : current_schema(PG_FUNCTION_ARGS)
     280                 :             : {
     281                 :           4 :         List       *search_path = fetch_search_path(false);
     282                 :           4 :         char       *nspname;
     283                 :             : 
     284         [ +  + ]:           4 :         if (search_path == NIL)
     285                 :           1 :                 PG_RETURN_NULL();
     286                 :           3 :         nspname = get_namespace_name(linitial_oid(search_path));
     287                 :           3 :         list_free(search_path);
     288         [ +  - ]:           3 :         if (!nspname)
     289                 :           0 :                 PG_RETURN_NULL();               /* recently-deleted namespace? */
     290                 :           3 :         PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(nspname)));
     291                 :           4 : }
     292                 :             : 
     293                 :             : Datum
     294                 :           4 : current_schemas(PG_FUNCTION_ARGS)
     295                 :             : {
     296                 :           4 :         List       *search_path = fetch_search_path(PG_GETARG_BOOL(0));
     297                 :           4 :         ListCell   *l;
     298                 :           4 :         Datum      *names;
     299                 :           4 :         int                     i;
     300                 :           4 :         ArrayType  *array;
     301                 :             : 
     302                 :           4 :         names = (Datum *) palloc(list_length(search_path) * sizeof(Datum));
     303                 :           4 :         i = 0;
     304   [ +  -  +  +  :          11 :         foreach(l, search_path)
                   +  + ]
     305                 :             :         {
     306                 :           7 :                 char       *nspname;
     307                 :             : 
     308                 :           7 :                 nspname = get_namespace_name(lfirst_oid(l));
     309         [ -  + ]:           7 :                 if (nspname)                    /* watch out for deleted namespace */
     310                 :             :                 {
     311                 :           7 :                         names[i] = DirectFunctionCall1(namein, CStringGetDatum(nspname));
     312                 :           7 :                         i++;
     313                 :           7 :                 }
     314                 :           7 :         }
     315                 :           4 :         list_free(search_path);
     316                 :             : 
     317                 :           4 :         array = construct_array_builtin(names, i, NAMEOID);
     318                 :             : 
     319                 :           8 :         PG_RETURN_POINTER(array);
     320                 :           4 : }
     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                 :        3667 : nameconcatoid(PG_FUNCTION_ARGS)
     334                 :             : {
     335                 :        3667 :         Name            nam = PG_GETARG_NAME(0);
     336                 :        3667 :         Oid                     oid = PG_GETARG_OID(1);
     337                 :        3667 :         Name            result;
     338                 :        3667 :         char            suffix[20];
     339                 :        3667 :         int                     suflen;
     340                 :        3667 :         int                     namlen;
     341                 :             : 
     342                 :        3667 :         suflen = snprintf(suffix, sizeof(suffix), "_%u", oid);
     343                 :        3667 :         namlen = strlen(NameStr(*nam));
     344                 :             : 
     345                 :             :         /* Truncate oversize input by truncating name part, not suffix */
     346         [ +  - ]:        3667 :         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                 :        3667 :         result = (Name) palloc0(NAMEDATALEN);
     351                 :        3667 :         memcpy(NameStr(*result), NameStr(*nam), namlen);
     352                 :        3667 :         memcpy(NameStr(*result) + namlen, suffix, suflen);
     353                 :             : 
     354                 :        7334 :         PG_RETURN_NAME(result);
     355                 :        3667 : }
        

Generated by: LCOV version 2.3.2-1