LCOV - differential code coverage report
Current view: top level - src/backend/commands - define.c (source / functions) Coverage Total Hit UBC GBC CBC
Current: c70b6db34ffeab48beef1fb4ce61bcad3772b8dd vs 06473f5a344df8c9594ead90a609b86f6724cff8 Lines: 65.2 % 138 90 48 2 88
Current Date: 2025-09-06 07:49:51 +0900 Functions: 90.9 % 11 10 1 10
Baseline: lcov-20250906-005545-baseline Branches: 37.8 % 127 48 79 2 46
Baseline Date: 2025-09-05 08:21:35 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(360..) days: 65.2 % 138 90 48 2 88
Function coverage date bins:
(360..) days: 90.9 % 11 10 1 10
Branch coverage date bins:
(360..) days: 37.8 % 127 48 79 2 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 *
 5999 tgl@sss.pgh.pa.us          35                 :CBC       31432 : defGetString(DefElem *def)
                                 36                 :                : {
                                 37         [ -  + ]:          31432 :     if (def->arg == NULL)
 8084 tgl@sss.pgh.pa.us          38         [ #  # ]:UBC           0 :         ereport(ERROR,
                                 39                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                 40                 :                :                  errmsg("%s requires a parameter",
                                 41                 :                :                         def->defname)));
 5999 tgl@sss.pgh.pa.us          42   [ +  +  +  +  :CBC       31432 :     switch (nodeTag(def->arg))
                                        +  -  -  - ]
                                 43                 :                :     {
 9100                            44                 :            537 :         case T_Integer:
 4261 peter_e@gmx.net            45                 :            537 :             return psprintf("%ld", (long) intVal(def->arg));
 9100 tgl@sss.pgh.pa.us          46                 :             56 :         case T_Float:
 1331 peter@eisentraut.org       47                 :             56 :             return castNode(Float, def->arg)->fval;
                                 48                 :            290 :         case T_Boolean:
                                 49         [ +  + ]:            290 :             return boolVal(def->arg) ? "true" : "false";
 9100 tgl@sss.pgh.pa.us          50                 :          27745 :         case T_String:
 5999                            51                 :          27745 :             return strVal(def->arg);
 9100                            52                 :           2804 :         case T_TypeName:
 5999                            53                 :           2804 :             return TypeNameToString((TypeName *) def->arg);
 8428 tgl@sss.pgh.pa.us          54                 :UBC           0 :         case T_List:
 5999                            55                 :              0 :             return NameListToString((List *) def->arg);
 5829                            56                 :              0 :         case T_A_Star:
                                 57                 :              0 :             return pstrdup("*");
 9100                            58                 :              0 :         default:
 5999                            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
 9471 tgl@sss.pgh.pa.us          68                 :CBC        2480 : defGetNumeric(DefElem *def)
                                 69                 :                : {
                                 70         [ -  + ]:           2480 :     if (def->arg == NULL)
 8084 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)));
 9471 tgl@sss.pgh.pa.us          75      [ +  +  - ]:CBC        2480 :     switch (nodeTag(def->arg))
                                 76                 :                :     {
                                 77                 :           2470 :         case T_Integer:
                                 78                 :           2470 :             return (double) intVal(def->arg);
                                 79                 :             10 :         case T_Float:
                                 80                 :             10 :             return floatVal(def->arg);
 9471 tgl@sss.pgh.pa.us          81                 :UBC           0 :         default:
 8084                            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
 5999 tgl@sss.pgh.pa.us          94                 :CBC       20774 : defGetBoolean(DefElem *def)
                                 95                 :                : {
                                 96                 :                :     /*
                                 97                 :                :      * If no parameter value given, assume "true" is meant.
                                 98                 :                :      */
                                 99         [ +  + ]:          20774 :     if (def->arg == NULL)
 7785                           100                 :          10562 :         return true;
                                101                 :                : 
                                102                 :                :     /*
                                103                 :                :      * Allow 0, 1, "true", "false", "on", "off"
                                104                 :                :      */
 5999                           105         [ +  + ]:          10212 :     switch (nodeTag(def->arg))
                                106                 :                :     {
 7006 bruce@momjian.us          107                 :            235 :         case T_Integer:
 5999 tgl@sss.pgh.pa.us         108      [ +  +  + ]:            235 :             switch (intVal(def->arg))
                                109                 :                :             {
 7005                           110                 :            203 :                 case 0:
                                111                 :            203 :                     return false;
                                112                 :             29 :                 case 1:
                                113                 :             29 :                     return true;
                                114                 :              3 :                 default:
                                115                 :                :                     /* otherwise, error out below */
                                116                 :              3 :                     break;
                                117                 :                :             }
 7006 bruce@momjian.us          118                 :              3 :             break;
                                119                 :           9977 :         default:
                                120                 :                :             {
 5999 tgl@sss.pgh.pa.us         121                 :           9977 :                 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                 :                :                  */
 7005                           127         [ +  + ]:           9977 :                 if (pg_strcasecmp(sval, "true") == 0)
                                128                 :            833 :                     return true;
                                129         [ +  + ]:           9144 :                 if (pg_strcasecmp(sval, "false") == 0)
                                130                 :            728 :                     return false;
 5886                           131         [ +  + ]:           8416 :                 if (pg_strcasecmp(sval, "on") == 0)
                                132                 :            150 :                     return true;
                                133         [ +  + ]:           8266 :                 if (pg_strcasecmp(sval, "off") == 0)
                                134                 :           8254 :                     return false;
                                135                 :                :             }
 7006 bruce@momjian.us          136                 :             12 :             break;
                                137                 :                :     }
 7785 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
 4312                           149                 :            939 : defGetInt32(DefElem *def)
                                150                 :                : {
                                151         [ -  + ]:            939 :     if (def->arg == NULL)
 4312 tgl@sss.pgh.pa.us         152         [ #  # ]:UBC           0 :         ereport(ERROR,
                                153                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                154                 :                :                  errmsg("%s requires an integer value",
                                155                 :                :                         def->defname)));
 4312 tgl@sss.pgh.pa.us         156         [ +  + ]:CBC         939 :     switch (nodeTag(def->arg))
                                157                 :                :     {
                                158                 :            936 :         case T_Integer:
                                159                 :            936 :             return (int32) intVal(def->arg);
 4312 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
 8508 tgl@sss.pgh.pa.us         173                 :CBC         429 : defGetInt64(DefElem *def)
                                174                 :                : {
                                175         [ -  + ]:            429 :     if (def->arg == NULL)
 8084 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)));
 8508 tgl@sss.pgh.pa.us         180      [ +  +  - ]:CBC         429 :     switch (nodeTag(def->arg))
                                181                 :                :     {
                                182                 :            397 :         case T_Integer:
                                183                 :            397 :             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)));
 8508 tgl@sss.pgh.pa.us         193                 :UBC           0 :         default:
 8084                           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
 1037 tgl@sss.pgh.pa.us         206                 :CBC         129 : defGetObjectId(DefElem *def)
                                207                 :                : {
                                208         [ -  + ]:            129 :     if (def->arg == NULL)
 1037 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)));
 1037 tgl@sss.pgh.pa.us         213      [ +  -  - ]:CBC         129 :     switch (nodeTag(def->arg))
                                214                 :                :     {
                                215                 :            129 :         case T_Integer:
                                216                 :            129 :             return (Oid) intVal(def->arg);
 1037 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 *
 8551 tgl@sss.pgh.pa.us         239                 :CBC        8092 : defGetQualifiedName(DefElem *def)
                                240                 :                : {
                                241         [ -  + ]:           8092 :     if (def->arg == NULL)
 8084 tgl@sss.pgh.pa.us         242         [ #  # ]:UBC           0 :         ereport(ERROR,
                                243                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                244                 :                :                  errmsg("%s requires a parameter",
                                245                 :                :                         def->defname)));
 8551 tgl@sss.pgh.pa.us         246   [ +  +  +  - ]:CBC        8092 :     switch (nodeTag(def->arg))
                                247                 :                :     {
                                248                 :           5081 :         case T_TypeName:
                                249                 :           8092 :             return ((TypeName *) def->arg)->names;
 8428                           250                 :           1332 :         case T_List:
                                251                 :           1332 :             return (List *) def->arg;
 8551                           252                 :           1679 :         case T_String:
                                253                 :                :             /* Allow quoted name for backwards compatibility */
 7773 neilc@samurai.com         254                 :           1679 :             return list_make1(def->arg);
 8551 tgl@sss.pgh.pa.us         255                 :UBC           0 :         default:
 8084                           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 *
 8562 tgl@sss.pgh.pa.us         271                 :CBC        3059 : defGetTypeName(DefElem *def)
                                272                 :                : {
                                273         [ -  + ]:           3059 :     if (def->arg == NULL)
 8084 tgl@sss.pgh.pa.us         274         [ #  # ]:UBC           0 :         ereport(ERROR,
                                275                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                276                 :                :                  errmsg("%s requires a parameter",
                                277                 :                :                         def->defname)));
 8562 tgl@sss.pgh.pa.us         278      [ +  +  - ]:CBC        3059 :     switch (nodeTag(def->arg))
                                279                 :                :     {
                                280                 :           3056 :         case T_TypeName:
                                281                 :           3059 :             return (TypeName *) def->arg;
                                282                 :              3 :         case T_String:
                                283                 :                :             /* Allow quoted typename for backwards compatibility */
 7116                           284                 :              3 :             return makeTypeNameFromNameList(list_make1(def->arg));
 8562 tgl@sss.pgh.pa.us         285                 :UBC           0 :         default:
 8084                           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
10225 bruce@momjian.us          299                 :CBC          78 : defGetTypeLength(DefElem *def)
                                300                 :                : {
 9100 tgl@sss.pgh.pa.us         301         [ -  + ]:             78 :     if (def->arg == NULL)
 8084 tgl@sss.pgh.pa.us         302         [ #  # ]:UBC           0 :         ereport(ERROR,
                                303                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                304                 :                :                  errmsg("%s requires a parameter",
                                305                 :                :                         def->defname)));
 9100 tgl@sss.pgh.pa.us         306   [ +  -  -  +  :CBC          78 :     switch (nodeTag(def->arg))
                                              -  - ]
                                307                 :                :     {
                                308                 :             60 :         case T_Integer:
                                309                 :             60 :             return intVal(def->arg);
 9100 tgl@sss.pgh.pa.us         310                 :UBC           0 :         case T_Float:
 8084                           311         [ #  # ]:              0 :             ereport(ERROR,
                                312                 :                :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                313                 :                :                      errmsg("%s requires an integer value",
                                314                 :                :                             def->defname)));
                                315                 :                :             break;
 9100                           316                 :              0 :         case T_String:
 7792                           317         [ #  # ]:              0 :             if (pg_strcasecmp(strVal(def->arg), "variable") == 0)
 9100                           318                 :              0 :                 return -1;      /* variable length */
                                319                 :              0 :             break;
 9100 tgl@sss.pgh.pa.us         320                 :CBC          18 :         case T_TypeName:
                                321                 :                :             /* cope if grammar chooses to believe "variable" is a typename */
 7792                           322         [ +  - ]:             18 :             if (pg_strcasecmp(TypeNameToString((TypeName *) def->arg),
                                323                 :                :                               "variable") == 0)
 9100                           324                 :             18 :                 return -1;      /* variable length */
 9100 tgl@sss.pgh.pa.us         325                 :UBC           0 :             break;
 8428                           326                 :              0 :         case T_List:
                                327                 :                :             /* must be an operator name */
                                328                 :              0 :             break;
 9100                           329                 :              0 :         default:
 8084                           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 *
 3152 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                 :                : 
 3034 bruce@momjian.us          355   [ #  #  #  #  :              0 :     foreach(cell, (List *) def->arg)
                                              #  # ]
                                356                 :                :     {
 3152 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
 1514 dean.a.rasheed@gmail      371                 :CBC          78 : errorConflictingDefElem(DefElem *defel, ParseState *pstate)
                                372                 :                : {
                                373         [ +  - ]:             78 :     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