LCOV - differential code coverage report
Current view: top level - src/backend/utils/adt - name.c (source / functions) Coverage Total Hit LBC UBC GBC GIC GNC CBC ECB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 92.9 % 113 105 1 7 1 7 1 96 6 2
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 20 20 1 1 18 1
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

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

Generated by: LCOV version v1.16-55-g56c0a2a