LCOV - differential code coverage report
Current view: top level - src/backend/commands - define.c (source / functions) Coverage Total Hit UBC GBC GNC CBC DCB
Current: 7a15cff1f11193467898da1c1fabf06fd2caee04 vs 84a3778c79c2d28b4dc281d03ef2ab019b16483b Lines: 65.9 % 138 91 47 3 1 87 1
Current Date: 2025-12-15 18:36:29 -0500 Functions: 90.9 % 11 10 1 1 9
Baseline: lcov-20251216-010103-baseline Branches: 39.4 % 127 50 77 4 46
Baseline Date: 2025-12-15 13:30:48 -0800 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(1,7] days: 100.0 % 1 1 1
(360..) days: 65.7 % 137 90 47 3 87
Function coverage date bins:
(360..) days: 90.9 % 11 10 1 1 9
Branch coverage date bins:
(360..) days: 39.4 % 127 50 77 4 46

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * define.c
                                  4                 :                :  *    Support routines for various kinds of object creation.
                                  5                 :                :  *
                                  6                 :                :  *
                                  7                 :                :  * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
                                  8                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                  9                 :                :  *
                                 10                 :                :  *
                                 11                 :                :  * IDENTIFICATION
                                 12                 :                :  *    src/backend/commands/define.c
                                 13                 :                :  *
                                 14                 :                :  * DESCRIPTION
                                 15                 :                :  *    Support routines for dealing with DefElem nodes.
                                 16                 :                :  *
                                 17                 :                :  *
                                 18                 :                :  *-------------------------------------------------------------------------
                                 19                 :                :  */
                                 20                 :                : #include "postgres.h"
                                 21                 :                : 
                                 22                 :                : #include <ctype.h>
                                 23                 :                : #include <math.h>
                                 24                 :                : 
                                 25                 :                : #include "catalog/namespace.h"
                                 26                 :                : #include "commands/defrem.h"
                                 27                 :                : #include "nodes/makefuncs.h"
                                 28                 :                : #include "parser/parse_type.h"
                                 29                 :                : #include "utils/fmgrprotos.h"
                                 30                 :                : 
                                 31                 :                : /*
                                 32                 :                :  * Extract a string value (otherwise uninterpreted) from a DefElem.
                                 33                 :                :  */
                                 34                 :                : char *
 6100 tgl@sss.pgh.pa.us          35                 :CBC       31994 : defGetString(DefElem *def)
                                 36                 :                : {
                                 37         [ -  + ]:          31994 :     if (def->arg == NULL)
 8185 tgl@sss.pgh.pa.us          38         [ #  # ]:UBC           0 :         ereport(ERROR,
                                 39                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                 40                 :                :                  errmsg("%s requires a parameter",
                                 41                 :                :                         def->defname)));
 6100 tgl@sss.pgh.pa.us          42   [ +  +  +  +  :CBC       31994 :     switch (nodeTag(def->arg))
                                        +  -  -  - ]
                                 43                 :                :     {
 9201                            44                 :            543 :         case T_Integer:
    7 peter@eisentraut.org       45                 :GNC         543 :             return psprintf("%d", intVal(def->arg));
 9201 tgl@sss.pgh.pa.us          46                 :CBC          56 :         case T_Float:
 1432 peter@eisentraut.org       47                 :             56 :             return castNode(Float, def->arg)->fval;
                                 48                 :            291 :         case T_Boolean:
                                 49         [ +  + ]:            291 :             return boolVal(def->arg) ? "true" : "false";
 9201 tgl@sss.pgh.pa.us          50                 :          28255 :         case T_String:
 6100                            51                 :          28255 :             return strVal(def->arg);
 9201                            52                 :           2849 :         case T_TypeName:
 6100                            53                 :           2849 :             return TypeNameToString((TypeName *) def->arg);
 8529 tgl@sss.pgh.pa.us          54                 :UBC           0 :         case T_List:
 6100                            55                 :              0 :             return NameListToString((List *) def->arg);
 5930                            56                 :              0 :         case T_A_Star:
                                 57                 :              0 :             return pstrdup("*");
 9201                            58                 :              0 :         default:
 6100                            59         [ #  # ]:              0 :             elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
                                 60                 :                :     }
                                 61                 :                :     return NULL;                /* keep compiler quiet */
                                 62                 :                : }
                                 63                 :                : 
                                 64                 :                : /*
                                 65                 :                :  * Extract a numeric value (actually double) from a DefElem.
                                 66                 :                :  */
                                 67                 :                : double
 9572 tgl@sss.pgh.pa.us          68                 :CBC        2531 : defGetNumeric(DefElem *def)
                                 69                 :                : {
                                 70         [ -  + ]:           2531 :     if (def->arg == NULL)
 8185 tgl@sss.pgh.pa.us          71         [ #  # ]:UBC           0 :         ereport(ERROR,
                                 72                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                 73                 :                :                  errmsg("%s requires a numeric value",
                                 74                 :                :                         def->defname)));
 9572 tgl@sss.pgh.pa.us          75      [ +  +  - ]:CBC        2531 :     switch (nodeTag(def->arg))
                                 76                 :                :     {
                                 77                 :           2521 :         case T_Integer:
                                 78                 :           2521 :             return (double) intVal(def->arg);
                                 79                 :             10 :         case T_Float:
                                 80                 :             10 :             return floatVal(def->arg);
 9572 tgl@sss.pgh.pa.us          81                 :UBC           0 :         default:
 8185                            82         [ #  # ]:              0 :             ereport(ERROR,
                                 83                 :                :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                 84                 :                :                      errmsg("%s requires a numeric value",
                                 85                 :                :                             def->defname)));
                                 86                 :                :     }
                                 87                 :                :     return 0;                   /* keep compiler quiet */
                                 88                 :                : }
                                 89                 :                : 
                                 90                 :                : /*
                                 91                 :                :  * Extract a boolean value from a DefElem.
                                 92                 :                :  */
                                 93                 :                : bool
 6100 tgl@sss.pgh.pa.us          94                 :CBC       21753 : defGetBoolean(DefElem *def)
                                 95                 :                : {
                                 96                 :                :     /*
                                 97                 :                :      * If no parameter value given, assume "true" is meant.
                                 98                 :                :      */
                                 99         [ +  + ]:          21753 :     if (def->arg == NULL)
 7886                           100                 :          11242 :         return true;
                                101                 :                : 
                                102                 :                :     /*
                                103                 :                :      * Allow 0, 1, "true", "false", "on", "off"
                                104                 :                :      */
 6100                           105         [ +  + ]:          10511 :     switch (nodeTag(def->arg))
                                106                 :                :     {
 7107 bruce@momjian.us          107                 :            238 :         case T_Integer:
 6100 tgl@sss.pgh.pa.us         108      [ +  +  + ]:            238 :             switch (intVal(def->arg))
                                109                 :                :             {
 7106                           110                 :            206 :                 case 0:
                                111                 :            206 :                     return false;
                                112                 :             29 :                 case 1:
                                113                 :             29 :                     return true;
                                114                 :              3 :                 default:
                                115                 :                :                     /* otherwise, error out below */
                                116                 :              3 :                     break;
                                117                 :                :             }
 7107 bruce@momjian.us          118                 :              3 :             break;
                                119                 :          10273 :         default:
                                120                 :                :             {
 6100 tgl@sss.pgh.pa.us         121                 :          10273 :                 char       *sval = defGetString(def);
                                122                 :                : 
                                123                 :                :                 /*
                                124                 :                :                  * The set of strings accepted here should match up with the
                                125                 :                :                  * grammar's opt_boolean_or_string production.
                                126                 :                :                  */
 7106                           127         [ +  + ]:          10273 :                 if (pg_strcasecmp(sval, "true") == 0)
                                128                 :            854 :                     return true;
                                129         [ +  + ]:           9419 :                 if (pg_strcasecmp(sval, "false") == 0)
                                130                 :            733 :                     return false;
 5987                           131         [ +  + ]:           8686 :                 if (pg_strcasecmp(sval, "on") == 0)
                                132                 :            149 :                     return true;
                                133         [ +  + ]:           8537 :                 if (pg_strcasecmp(sval, "off") == 0)
                                134                 :           8525 :                     return false;
                                135                 :                :             }
 7107 bruce@momjian.us          136                 :             12 :             break;
                                137                 :                :     }
 7886 tgl@sss.pgh.pa.us         138         [ +  - ]:             15 :     ereport(ERROR,
                                139                 :                :             (errcode(ERRCODE_SYNTAX_ERROR),
                                140                 :                :              errmsg("%s requires a Boolean value",
                                141                 :                :                     def->defname)));
                                142                 :                :     return false;               /* keep compiler quiet */
                                143                 :                : }
                                144                 :                : 
                                145                 :                : /*
                                146                 :                :  * Extract an int32 value from a DefElem.
                                147                 :                :  */
                                148                 :                : int32
 4413                           149                 :            991 : defGetInt32(DefElem *def)
                                150                 :                : {
                                151         [ +  + ]:            991 :     if (def->arg == NULL)
 4413 tgl@sss.pgh.pa.us         152         [ +  - ]:GBC           3 :         ereport(ERROR,
                                153                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                154                 :                :                  errmsg("%s requires an integer value",
                                155                 :                :                         def->defname)));
 4413 tgl@sss.pgh.pa.us         156         [ +  + ]:CBC         988 :     switch (nodeTag(def->arg))
                                157                 :                :     {
                                158                 :            985 :         case T_Integer:
                                159                 :            985 :             return (int32) intVal(def->arg);
 4413 tgl@sss.pgh.pa.us         160                 :GBC           3 :         default:
                                161         [ +  - ]:              3 :             ereport(ERROR,
                                162                 :                :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                163                 :                :                      errmsg("%s requires an integer value",
                                164                 :                :                             def->defname)));
                                165                 :                :     }
                                166                 :                :     return 0;                   /* keep compiler quiet */
                                167                 :                : }
                                168                 :                : 
                                169                 :                : /*
                                170                 :                :  * Extract an int64 value from a DefElem.
                                171                 :                :  */
                                172                 :                : int64
 8609 tgl@sss.pgh.pa.us         173                 :CBC         437 : defGetInt64(DefElem *def)
                                174                 :                : {
                                175         [ -  + ]:            437 :     if (def->arg == NULL)
 8185 tgl@sss.pgh.pa.us         176         [ #  # ]:UBC           0 :         ereport(ERROR,
                                177                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                178                 :                :                  errmsg("%s requires a numeric value",
                                179                 :                :                         def->defname)));
 8609 tgl@sss.pgh.pa.us         180      [ +  +  - ]:CBC         437 :     switch (nodeTag(def->arg))
                                181                 :                :     {
                                182                 :            405 :         case T_Integer:
                                183                 :            405 :             return (int64) intVal(def->arg);
                                184                 :             32 :         case T_Float:
                                185                 :                : 
                                186                 :                :             /*
                                187                 :                :              * Values too large for int4 will be represented as Float
                                188                 :                :              * constants by the lexer.  Accept these if they are valid int8
                                189                 :                :              * strings.
                                190                 :                :              */
                                191                 :             32 :             return DatumGetInt64(DirectFunctionCall1(int8in,
                                192                 :                :                                                      CStringGetDatum(castNode(Float, def->arg)->fval)));
 8609 tgl@sss.pgh.pa.us         193                 :UBC           0 :         default:
 8185                           194         [ #  # ]:              0 :             ereport(ERROR,
                                195                 :                :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                196                 :                :                      errmsg("%s requires a numeric value",
                                197                 :                :                             def->defname)));
                                198                 :                :     }
                                199                 :                :     return 0;                   /* keep compiler quiet */
                                200                 :                : }
                                201                 :                : 
                                202                 :                : /*
                                203                 :                :  * Extract an OID value from a DefElem.
                                204                 :                :  */
                                205                 :                : Oid
 1138 tgl@sss.pgh.pa.us         206                 :CBC         133 : defGetObjectId(DefElem *def)
                                207                 :                : {
                                208         [ -  + ]:            133 :     if (def->arg == NULL)
 1138 tgl@sss.pgh.pa.us         209         [ #  # ]:UBC           0 :         ereport(ERROR,
                                210                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                211                 :                :                  errmsg("%s requires a numeric value",
                                212                 :                :                         def->defname)));
 1138 tgl@sss.pgh.pa.us         213      [ +  -  - ]:CBC         133 :     switch (nodeTag(def->arg))
                                214                 :                :     {
                                215                 :            133 :         case T_Integer:
                                216                 :            133 :             return (Oid) intVal(def->arg);
 1138 tgl@sss.pgh.pa.us         217                 :UBC           0 :         case T_Float:
                                218                 :                : 
                                219                 :                :             /*
                                220                 :                :              * Values too large for int4 will be represented as Float
                                221                 :                :              * constants by the lexer.  Accept these if they are valid OID
                                222                 :                :              * strings.
                                223                 :                :              */
                                224                 :              0 :             return DatumGetObjectId(DirectFunctionCall1(oidin,
                                225                 :                :                                                         CStringGetDatum(castNode(Float, def->arg)->fval)));
                                226                 :              0 :         default:
                                227         [ #  # ]:              0 :             ereport(ERROR,
                                228                 :                :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                229                 :                :                      errmsg("%s requires a numeric value",
                                230                 :                :                             def->defname)));
                                231                 :                :     }
                                232                 :                :     return 0;                   /* keep compiler quiet */
                                233                 :                : }
                                234                 :                : 
                                235                 :                : /*
                                236                 :                :  * Extract a possibly-qualified name (as a List of Strings) from a DefElem.
                                237                 :                :  */
                                238                 :                : List *
 8652 tgl@sss.pgh.pa.us         239                 :CBC        8195 : defGetQualifiedName(DefElem *def)
                                240                 :                : {
                                241         [ -  + ]:           8195 :     if (def->arg == NULL)
 8185 tgl@sss.pgh.pa.us         242         [ #  # ]:UBC           0 :         ereport(ERROR,
                                243                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                244                 :                :                  errmsg("%s requires a parameter",
                                245                 :                :                         def->defname)));
 8652 tgl@sss.pgh.pa.us         246   [ +  +  +  - ]:CBC        8195 :     switch (nodeTag(def->arg))
                                247                 :                :     {
                                248                 :           5112 :         case T_TypeName:
                                249                 :           8195 :             return ((TypeName *) def->arg)->names;
 8529                           250                 :           1375 :         case T_List:
                                251                 :           1375 :             return (List *) def->arg;
 8652                           252                 :           1708 :         case T_String:
                                253                 :                :             /* Allow quoted name for backwards compatibility */
 7874 neilc@samurai.com         254                 :           1708 :             return list_make1(def->arg);
 8652 tgl@sss.pgh.pa.us         255                 :UBC           0 :         default:
 8185                           256         [ #  # ]:              0 :             ereport(ERROR,
                                257                 :                :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                258                 :                :                      errmsg("argument of %s must be a name",
                                259                 :                :                             def->defname)));
                                260                 :                :     }
                                261                 :                :     return NIL;                 /* keep compiler quiet */
                                262                 :                : }
                                263                 :                : 
                                264                 :                : /*
                                265                 :                :  * Extract a TypeName from a DefElem.
                                266                 :                :  *
                                267                 :                :  * Note: we do not accept a List arg here, because the parser will only
                                268                 :                :  * return a bare List when the name looks like an operator name.
                                269                 :                :  */
                                270                 :                : TypeName *
 8663 tgl@sss.pgh.pa.us         271                 :CBC        3098 : defGetTypeName(DefElem *def)
                                272                 :                : {
                                273         [ -  + ]:           3098 :     if (def->arg == NULL)
 8185 tgl@sss.pgh.pa.us         274         [ #  # ]:UBC           0 :         ereport(ERROR,
                                275                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                276                 :                :                  errmsg("%s requires a parameter",
                                277                 :                :                         def->defname)));
 8663 tgl@sss.pgh.pa.us         278      [ +  +  - ]:CBC        3098 :     switch (nodeTag(def->arg))
                                279                 :                :     {
                                280                 :           3095 :         case T_TypeName:
                                281                 :           3098 :             return (TypeName *) def->arg;
                                282                 :              3 :         case T_String:
                                283                 :                :             /* Allow quoted typename for backwards compatibility */
 7217                           284                 :              3 :             return makeTypeNameFromNameList(list_make1(def->arg));
 8663 tgl@sss.pgh.pa.us         285                 :UBC           0 :         default:
 8185                           286         [ #  # ]:              0 :             ereport(ERROR,
                                287                 :                :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                288                 :                :                      errmsg("argument of %s must be a type name",
                                289                 :                :                             def->defname)));
                                290                 :                :     }
                                291                 :                :     return NULL;                /* keep compiler quiet */
                                292                 :                : }
                                293                 :                : 
                                294                 :                : /*
                                295                 :                :  * Extract a type length indicator (either absolute bytes, or
                                296                 :                :  * -1 for "variable") from a DefElem.
                                297                 :                :  */
                                298                 :                : int
10326 bruce@momjian.us          299                 :CBC          78 : defGetTypeLength(DefElem *def)
                                300                 :                : {
 9201 tgl@sss.pgh.pa.us         301         [ -  + ]:             78 :     if (def->arg == NULL)
 8185 tgl@sss.pgh.pa.us         302         [ #  # ]:UBC           0 :         ereport(ERROR,
                                303                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                304                 :                :                  errmsg("%s requires a parameter",
                                305                 :                :                         def->defname)));
 9201 tgl@sss.pgh.pa.us         306   [ +  -  -  +  :CBC          78 :     switch (nodeTag(def->arg))
                                              -  - ]
                                307                 :                :     {
                                308                 :             60 :         case T_Integer:
                                309                 :             60 :             return intVal(def->arg);
 9201 tgl@sss.pgh.pa.us         310                 :UBC           0 :         case T_Float:
 8185                           311         [ #  # ]:              0 :             ereport(ERROR,
                                312                 :                :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                313                 :                :                      errmsg("%s requires an integer value",
                                314                 :                :                             def->defname)));
                                315                 :                :             break;
 9201                           316                 :              0 :         case T_String:
 7893                           317         [ #  # ]:              0 :             if (pg_strcasecmp(strVal(def->arg), "variable") == 0)
 9201                           318                 :              0 :                 return -1;      /* variable length */
                                319                 :              0 :             break;
 9201 tgl@sss.pgh.pa.us         320                 :CBC          18 :         case T_TypeName:
                                321                 :                :             /* cope if grammar chooses to believe "variable" is a typename */
 7893                           322         [ +  - ]:             18 :             if (pg_strcasecmp(TypeNameToString((TypeName *) def->arg),
                                323                 :                :                               "variable") == 0)
 9201                           324                 :             18 :                 return -1;      /* variable length */
 9201 tgl@sss.pgh.pa.us         325                 :UBC           0 :             break;
 8529                           326                 :              0 :         case T_List:
                                327                 :                :             /* must be an operator name */
                                328                 :              0 :             break;
 9201                           329                 :              0 :         default:
 8185                           330         [ #  # ]:              0 :             elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
                                331                 :                :     }
                                332         [ #  # ]:              0 :     ereport(ERROR,
                                333                 :                :             (errcode(ERRCODE_SYNTAX_ERROR),
                                334                 :                :              errmsg("invalid argument for %s: \"%s\"",
                                335                 :                :                     def->defname, defGetString(def))));
                                336                 :                :     return 0;                   /* keep compiler quiet */
                                337                 :                : }
                                338                 :                : 
                                339                 :                : /*
                                340                 :                :  * Extract a list of string values (otherwise uninterpreted) from a DefElem.
                                341                 :                :  */
                                342                 :                : List *
 3253 peter_e@gmx.net           343                 :              0 : defGetStringList(DefElem *def)
                                344                 :                : {
                                345                 :                :     ListCell   *cell;
                                346                 :                : 
                                347         [ #  # ]:              0 :     if (def->arg == NULL)
                                348         [ #  # ]:              0 :         ereport(ERROR,
                                349                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                350                 :                :                  errmsg("%s requires a parameter",
                                351                 :                :                         def->defname)));
                                352         [ #  # ]:              0 :     if (nodeTag(def->arg) != T_List)
                                353         [ #  # ]:              0 :         elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
                                354                 :                : 
 3135 bruce@momjian.us          355   [ #  #  #  #  :              0 :     foreach(cell, (List *) def->arg)
                                              #  # ]
                                356                 :                :     {
 3253 peter_e@gmx.net           357                 :              0 :         Node       *str = (Node *) lfirst(cell);
                                358                 :                : 
                                359         [ #  # ]:              0 :         if (!IsA(str, String))
                                360         [ #  # ]:              0 :             elog(ERROR, "unexpected node type in name list: %d",
                                361                 :                :                  (int) nodeTag(str));
                                362                 :                :     }
                                363                 :                : 
                                364                 :              0 :     return (List *) def->arg;
                                365                 :                : }
                                366                 :                : 
                                367                 :                : /*
                                368                 :                :  * Raise an error about a conflicting DefElem.
                                369                 :                :  */
                                370                 :                : void
 1615 dean.a.rasheed@gmail      371                 :CBC          80 : errorConflictingDefElem(DefElem *defel, ParseState *pstate)
                                372                 :                : {
                                373         [ +  - ]:             80 :     ereport(ERROR,
                                374                 :                :             errcode(ERRCODE_SYNTAX_ERROR),
                                375                 :                :             errmsg("conflicting or redundant options"),
                                376                 :                :             parser_errposition(pstate, defel->location));
                                377                 :                : }
        

Generated by: LCOV version 2.4-beta