LCOV - differential code coverage report
Current view: top level - src/backend/commands - define.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 63.8 % 138 88 50 88
Current Date: 2024-04-14 14:21:10 Functions: 90.9 % 11 10 1 10
Baseline: 16@8cea358b128 Branches: 36.2 % 127 46 81 46
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed (240..) days: 63.8 % 138 88 50 88
Function coverage date bins:
(240..) days: 90.9 % 11 10 1 10
Branch coverage date bins:
(240..) days: 36.2 % 127 46 81 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-2024, 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                 :                :  *    The "DefineFoo" routines take the parse tree and pick out the
                                 16                 :                :  *    appropriate arguments/flags, passing the results to the
                                 17                 :                :  *    corresponding "FooDefine" routines (in src/catalog) that do
                                 18                 :                :  *    the actual catalog-munging.  These routines also verify permission
                                 19                 :                :  *    of the user to execute the command.
                                 20                 :                :  *
                                 21                 :                :  * NOTES
                                 22                 :                :  *    These things must be defined and committed in the following order:
                                 23                 :                :  *      "create function":
                                 24                 :                :  *              input/output, recv/send procedures
                                 25                 :                :  *      "create type":
                                 26                 :                :  *              type
                                 27                 :                :  *      "create operator":
                                 28                 :                :  *              operators
                                 29                 :                :  *
                                 30                 :                :  *
                                 31                 :                :  *-------------------------------------------------------------------------
                                 32                 :                :  */
                                 33                 :                : #include "postgres.h"
                                 34                 :                : 
                                 35                 :                : #include <ctype.h>
                                 36                 :                : #include <math.h>
                                 37                 :                : 
                                 38                 :                : #include "catalog/namespace.h"
                                 39                 :                : #include "commands/defrem.h"
                                 40                 :                : #include "nodes/makefuncs.h"
                                 41                 :                : #include "parser/parse_type.h"
                                 42                 :                : #include "utils/fmgrprotos.h"
                                 43                 :                : 
                                 44                 :                : /*
                                 45                 :                :  * Extract a string value (otherwise uninterpreted) from a DefElem.
                                 46                 :                :  */
                                 47                 :                : char *
 5489 tgl@sss.pgh.pa.us          48                 :CBC       27448 : defGetString(DefElem *def)
                                 49                 :                : {
                                 50         [ -  + ]:          27448 :     if (def->arg == NULL)
 7574 tgl@sss.pgh.pa.us          51         [ #  # ]:UBC           0 :         ereport(ERROR,
                                 52                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                 53                 :                :                  errmsg("%s requires a parameter",
                                 54                 :                :                         def->defname)));
 5489 tgl@sss.pgh.pa.us          55   [ +  +  +  +  :CBC       27448 :     switch (nodeTag(def->arg))
                                        +  -  -  - ]
                                 56                 :                :     {
 8590                            57                 :            524 :         case T_Integer:
 3751 peter_e@gmx.net            58                 :            524 :             return psprintf("%ld", (long) intVal(def->arg));
 8590 tgl@sss.pgh.pa.us          59                 :             53 :         case T_Float:
  821 peter@eisentraut.org       60                 :             53 :             return castNode(Float, def->arg)->fval;
                                 61                 :            275 :         case T_Boolean:
                                 62         [ +  + ]:            275 :             return boolVal(def->arg) ? "true" : "false";
 8590 tgl@sss.pgh.pa.us          63                 :          24359 :         case T_String:
 5489                            64                 :          24359 :             return strVal(def->arg);
 8590                            65                 :           2237 :         case T_TypeName:
 5489                            66                 :           2237 :             return TypeNameToString((TypeName *) def->arg);
 7918 tgl@sss.pgh.pa.us          67                 :UBC           0 :         case T_List:
 5489                            68                 :              0 :             return NameListToString((List *) def->arg);
 5319                            69                 :              0 :         case T_A_Star:
                                 70                 :              0 :             return pstrdup("*");
 8590                            71                 :              0 :         default:
 5489                            72         [ #  # ]:              0 :             elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
                                 73                 :                :     }
                                 74                 :                :     return NULL;                /* keep compiler quiet */
                                 75                 :                : }
                                 76                 :                : 
                                 77                 :                : /*
                                 78                 :                :  * Extract a numeric value (actually double) from a DefElem.
                                 79                 :                :  */
                                 80                 :                : double
 8961 tgl@sss.pgh.pa.us          81                 :CBC        1910 : defGetNumeric(DefElem *def)
                                 82                 :                : {
                                 83         [ -  + ]:           1910 :     if (def->arg == NULL)
 7574 tgl@sss.pgh.pa.us          84         [ #  # ]:UBC           0 :         ereport(ERROR,
                                 85                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                 86                 :                :                  errmsg("%s requires a numeric value",
                                 87                 :                :                         def->defname)));
 8961 tgl@sss.pgh.pa.us          88      [ +  +  - ]:CBC        1910 :     switch (nodeTag(def->arg))
                                 89                 :                :     {
                                 90                 :           1900 :         case T_Integer:
                                 91                 :           1900 :             return (double) intVal(def->arg);
                                 92                 :             10 :         case T_Float:
                                 93                 :             10 :             return floatVal(def->arg);
 8961 tgl@sss.pgh.pa.us          94                 :UBC           0 :         default:
 7574                            95         [ #  # ]:              0 :             ereport(ERROR,
                                 96                 :                :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                 97                 :                :                      errmsg("%s requires a numeric value",
                                 98                 :                :                             def->defname)));
                                 99                 :                :     }
                                100                 :                :     return 0;                   /* keep compiler quiet */
                                101                 :                : }
                                102                 :                : 
                                103                 :                : /*
                                104                 :                :  * Extract a boolean value from a DefElem.
                                105                 :                :  */
                                106                 :                : bool
 5489 tgl@sss.pgh.pa.us         107                 :CBC       15999 : defGetBoolean(DefElem *def)
                                108                 :                : {
                                109                 :                :     /*
                                110                 :                :      * If no parameter value given, assume "true" is meant.
                                111                 :                :      */
                                112         [ +  + ]:          15999 :     if (def->arg == NULL)
 7275                           113                 :           7479 :         return true;
                                114                 :                : 
                                115                 :                :     /*
                                116                 :                :      * Allow 0, 1, "true", "false", "on", "off"
                                117                 :                :      */
 5489                           118         [ +  + ]:           8520 :     switch (nodeTag(def->arg))
                                119                 :                :     {
 6496 bruce@momjian.us          120                 :            221 :         case T_Integer:
 5489 tgl@sss.pgh.pa.us         121      [ +  +  + ]:            221 :             switch (intVal(def->arg))
                                122                 :                :             {
 6495                           123                 :            189 :                 case 0:
                                124                 :            189 :                     return false;
                                125                 :             29 :                 case 1:
                                126                 :             29 :                     return true;
                                127                 :              3 :                 default:
                                128                 :                :                     /* otherwise, error out below */
                                129                 :              3 :                     break;
                                130                 :                :             }
 6496 bruce@momjian.us          131                 :              3 :             break;
                                132                 :           8299 :         default:
                                133                 :                :             {
 5489 tgl@sss.pgh.pa.us         134                 :           8299 :                 char       *sval = defGetString(def);
                                135                 :                : 
                                136                 :                :                 /*
                                137                 :                :                  * The set of strings accepted here should match up with the
                                138                 :                :                  * grammar's opt_boolean_or_string production.
                                139                 :                :                  */
 6495                           140         [ +  + ]:           8299 :                 if (pg_strcasecmp(sval, "true") == 0)
                                141                 :            769 :                     return true;
                                142         [ +  + ]:           7530 :                 if (pg_strcasecmp(sval, "false") == 0)
                                143                 :            676 :                     return false;
 5376                           144         [ +  + ]:           6854 :                 if (pg_strcasecmp(sval, "on") == 0)
                                145                 :             64 :                     return true;
                                146         [ +  + ]:           6790 :                 if (pg_strcasecmp(sval, "off") == 0)
                                147                 :           6781 :                     return false;
                                148                 :                :             }
 6496 bruce@momjian.us          149                 :              9 :             break;
                                150                 :                :     }
 7275 tgl@sss.pgh.pa.us         151         [ +  - ]:             12 :     ereport(ERROR,
                                152                 :                :             (errcode(ERRCODE_SYNTAX_ERROR),
                                153                 :                :              errmsg("%s requires a Boolean value",
                                154                 :                :                     def->defname)));
                                155                 :                :     return false;               /* keep compiler quiet */
                                156                 :                : }
                                157                 :                : 
                                158                 :                : /*
                                159                 :                :  * Extract an int32 value from a DefElem.
                                160                 :                :  */
                                161                 :                : int32
 3802                           162                 :            891 : defGetInt32(DefElem *def)
                                163                 :                : {
                                164         [ -  + ]:            891 :     if (def->arg == NULL)
 3802 tgl@sss.pgh.pa.us         165         [ #  # ]:UBC           0 :         ereport(ERROR,
                                166                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                167                 :                :                  errmsg("%s requires an integer value",
                                168                 :                :                         def->defname)));
 3802 tgl@sss.pgh.pa.us         169         [ +  - ]:CBC         891 :     switch (nodeTag(def->arg))
                                170                 :                :     {
                                171                 :            891 :         case T_Integer:
                                172                 :            891 :             return (int32) intVal(def->arg);
 3802 tgl@sss.pgh.pa.us         173                 :UBC           0 :         default:
                                174         [ #  # ]:              0 :             ereport(ERROR,
                                175                 :                :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                176                 :                :                      errmsg("%s requires an integer value",
                                177                 :                :                             def->defname)));
                                178                 :                :     }
                                179                 :                :     return 0;                   /* keep compiler quiet */
                                180                 :                : }
                                181                 :                : 
                                182                 :                : /*
                                183                 :                :  * Extract an int64 value from a DefElem.
                                184                 :                :  */
                                185                 :                : int64
 7998 tgl@sss.pgh.pa.us         186                 :CBC         375 : defGetInt64(DefElem *def)
                                187                 :                : {
                                188         [ -  + ]:            375 :     if (def->arg == NULL)
 7574 tgl@sss.pgh.pa.us         189         [ #  # ]:UBC           0 :         ereport(ERROR,
                                190                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                191                 :                :                  errmsg("%s requires a numeric value",
                                192                 :                :                         def->defname)));
 7998 tgl@sss.pgh.pa.us         193      [ +  +  - ]:CBC         375 :     switch (nodeTag(def->arg))
                                194                 :                :     {
                                195                 :            359 :         case T_Integer:
                                196                 :            359 :             return (int64) intVal(def->arg);
                                197                 :             16 :         case T_Float:
                                198                 :                : 
                                199                 :                :             /*
                                200                 :                :              * Values too large for int4 will be represented as Float
                                201                 :                :              * constants by the lexer.  Accept these if they are valid int8
                                202                 :                :              * strings.
                                203                 :                :              */
                                204                 :             16 :             return DatumGetInt64(DirectFunctionCall1(int8in,
                                205                 :                :                                                      CStringGetDatum(castNode(Float, def->arg)->fval)));
 7998 tgl@sss.pgh.pa.us         206                 :UBC           0 :         default:
 7574                           207         [ #  # ]:              0 :             ereport(ERROR,
                                208                 :                :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                209                 :                :                      errmsg("%s requires a numeric value",
                                210                 :                :                             def->defname)));
                                211                 :                :     }
                                212                 :                :     return 0;                   /* keep compiler quiet */
                                213                 :                : }
                                214                 :                : 
                                215                 :                : /*
                                216                 :                :  * Extract an OID value from a DefElem.
                                217                 :                :  */
                                218                 :                : Oid
  527 tgl@sss.pgh.pa.us         219                 :CBC          89 : defGetObjectId(DefElem *def)
                                220                 :                : {
                                221         [ -  + ]:             89 :     if (def->arg == NULL)
  527 tgl@sss.pgh.pa.us         222         [ #  # ]:UBC           0 :         ereport(ERROR,
                                223                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                224                 :                :                  errmsg("%s requires a numeric value",
                                225                 :                :                         def->defname)));
  527 tgl@sss.pgh.pa.us         226      [ +  -  - ]:CBC          89 :     switch (nodeTag(def->arg))
                                227                 :                :     {
                                228                 :             89 :         case T_Integer:
                                229                 :             89 :             return (Oid) intVal(def->arg);
  527 tgl@sss.pgh.pa.us         230                 :UBC           0 :         case T_Float:
                                231                 :                : 
                                232                 :                :             /*
                                233                 :                :              * Values too large for int4 will be represented as Float
                                234                 :                :              * constants by the lexer.  Accept these if they are valid OID
                                235                 :                :              * strings.
                                236                 :                :              */
                                237                 :              0 :             return DatumGetObjectId(DirectFunctionCall1(oidin,
                                238                 :                :                                                         CStringGetDatum(castNode(Float, def->arg)->fval)));
                                239                 :              0 :         default:
                                240         [ #  # ]:              0 :             ereport(ERROR,
                                241                 :                :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                242                 :                :                      errmsg("%s requires a numeric value",
                                243                 :                :                             def->defname)));
                                244                 :                :     }
                                245                 :                :     return 0;                   /* keep compiler quiet */
                                246                 :                : }
                                247                 :                : 
                                248                 :                : /*
                                249                 :                :  * Extract a possibly-qualified name (as a List of Strings) from a DefElem.
                                250                 :                :  */
                                251                 :                : List *
 8041 tgl@sss.pgh.pa.us         252                 :CBC        7242 : defGetQualifiedName(DefElem *def)
                                253                 :                : {
                                254         [ -  + ]:           7242 :     if (def->arg == NULL)
 7574 tgl@sss.pgh.pa.us         255         [ #  # ]:UBC           0 :         ereport(ERROR,
                                256                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                257                 :                :                  errmsg("%s requires a parameter",
                                258                 :                :                         def->defname)));
 8041 tgl@sss.pgh.pa.us         259   [ +  +  +  - ]:CBC        7242 :     switch (nodeTag(def->arg))
                                260                 :                :     {
                                261                 :           4643 :         case T_TypeName:
                                262                 :           7242 :             return ((TypeName *) def->arg)->names;
 7918                           263                 :           1300 :         case T_List:
                                264                 :           1300 :             return (List *) def->arg;
 8041                           265                 :           1299 :         case T_String:
                                266                 :                :             /* Allow quoted name for backwards compatibility */
 7263 neilc@samurai.com         267                 :           1299 :             return list_make1(def->arg);
 8041 tgl@sss.pgh.pa.us         268                 :UBC           0 :         default:
 7574                           269         [ #  # ]:              0 :             ereport(ERROR,
                                270                 :                :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                271                 :                :                      errmsg("argument of %s must be a name",
                                272                 :                :                             def->defname)));
                                273                 :                :     }
                                274                 :                :     return NIL;                 /* keep compiler quiet */
                                275                 :                : }
                                276                 :                : 
                                277                 :                : /*
                                278                 :                :  * Extract a TypeName from a DefElem.
                                279                 :                :  *
                                280                 :                :  * Note: we do not accept a List arg here, because the parser will only
                                281                 :                :  * return a bare List when the name looks like an operator name.
                                282                 :                :  */
                                283                 :                : TypeName *
 8052 tgl@sss.pgh.pa.us         284                 :CBC        2956 : defGetTypeName(DefElem *def)
                                285                 :                : {
                                286         [ -  + ]:           2956 :     if (def->arg == NULL)
 7574 tgl@sss.pgh.pa.us         287         [ #  # ]:UBC           0 :         ereport(ERROR,
                                288                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                289                 :                :                  errmsg("%s requires a parameter",
                                290                 :                :                         def->defname)));
 8052 tgl@sss.pgh.pa.us         291      [ +  +  - ]:CBC        2956 :     switch (nodeTag(def->arg))
                                292                 :                :     {
                                293                 :           2953 :         case T_TypeName:
                                294                 :           2956 :             return (TypeName *) def->arg;
                                295                 :              3 :         case T_String:
                                296                 :                :             /* Allow quoted typename for backwards compatibility */
 6606                           297                 :              3 :             return makeTypeNameFromNameList(list_make1(def->arg));
 8052 tgl@sss.pgh.pa.us         298                 :UBC           0 :         default:
 7574                           299         [ #  # ]:              0 :             ereport(ERROR,
                                300                 :                :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                301                 :                :                      errmsg("argument of %s must be a type name",
                                302                 :                :                             def->defname)));
                                303                 :                :     }
                                304                 :                :     return NULL;                /* keep compiler quiet */
                                305                 :                : }
                                306                 :                : 
                                307                 :                : /*
                                308                 :                :  * Extract a type length indicator (either absolute bytes, or
                                309                 :                :  * -1 for "variable") from a DefElem.
                                310                 :                :  */
                                311                 :                : int
 9715 bruce@momjian.us          312                 :CBC          65 : defGetTypeLength(DefElem *def)
                                313                 :                : {
 8590 tgl@sss.pgh.pa.us         314         [ -  + ]:             65 :     if (def->arg == NULL)
 7574 tgl@sss.pgh.pa.us         315         [ #  # ]:UBC           0 :         ereport(ERROR,
                                316                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                317                 :                :                  errmsg("%s requires a parameter",
                                318                 :                :                         def->defname)));
 8590 tgl@sss.pgh.pa.us         319   [ +  -  -  +  :CBC          65 :     switch (nodeTag(def->arg))
                                              -  - ]
                                320                 :                :     {
                                321                 :             50 :         case T_Integer:
                                322                 :             50 :             return intVal(def->arg);
 8590 tgl@sss.pgh.pa.us         323                 :UBC           0 :         case T_Float:
 7574                           324         [ #  # ]:              0 :             ereport(ERROR,
                                325                 :                :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                326                 :                :                      errmsg("%s requires an integer value",
                                327                 :                :                             def->defname)));
                                328                 :                :             break;
 8590                           329                 :              0 :         case T_String:
 7282                           330         [ #  # ]:              0 :             if (pg_strcasecmp(strVal(def->arg), "variable") == 0)
 8590                           331                 :              0 :                 return -1;      /* variable length */
                                332                 :              0 :             break;
 8590 tgl@sss.pgh.pa.us         333                 :CBC          15 :         case T_TypeName:
                                334                 :                :             /* cope if grammar chooses to believe "variable" is a typename */
 7282                           335         [ +  - ]:             15 :             if (pg_strcasecmp(TypeNameToString((TypeName *) def->arg),
                                336                 :                :                               "variable") == 0)
 8590                           337                 :             15 :                 return -1;      /* variable length */
 8590 tgl@sss.pgh.pa.us         338                 :UBC           0 :             break;
 7918                           339                 :              0 :         case T_List:
                                340                 :                :             /* must be an operator name */
                                341                 :              0 :             break;
 8590                           342                 :              0 :         default:
 7574                           343         [ #  # ]:              0 :             elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
                                344                 :                :     }
                                345         [ #  # ]:              0 :     ereport(ERROR,
                                346                 :                :             (errcode(ERRCODE_SYNTAX_ERROR),
                                347                 :                :              errmsg("invalid argument for %s: \"%s\"",
                                348                 :                :                     def->defname, defGetString(def))));
                                349                 :                :     return 0;                   /* keep compiler quiet */
                                350                 :                : }
                                351                 :                : 
                                352                 :                : /*
                                353                 :                :  * Extract a list of string values (otherwise uninterpreted) from a DefElem.
                                354                 :                :  */
                                355                 :                : List *
 2642 peter_e@gmx.net           356                 :              0 : defGetStringList(DefElem *def)
                                357                 :                : {
                                358                 :                :     ListCell   *cell;
                                359                 :                : 
                                360         [ #  # ]:              0 :     if (def->arg == NULL)
                                361         [ #  # ]:              0 :         ereport(ERROR,
                                362                 :                :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                363                 :                :                  errmsg("%s requires a parameter",
                                364                 :                :                         def->defname)));
                                365         [ #  # ]:              0 :     if (nodeTag(def->arg) != T_List)
                                366         [ #  # ]:              0 :         elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
                                367                 :                : 
 2524 bruce@momjian.us          368   [ #  #  #  #  :              0 :     foreach(cell, (List *) def->arg)
                                              #  # ]
                                369                 :                :     {
 2642 peter_e@gmx.net           370                 :              0 :         Node       *str = (Node *) lfirst(cell);
                                371                 :                : 
                                372         [ #  # ]:              0 :         if (!IsA(str, String))
                                373         [ #  # ]:              0 :             elog(ERROR, "unexpected node type in name list: %d",
                                374                 :                :                  (int) nodeTag(str));
                                375                 :                :     }
                                376                 :                : 
                                377                 :              0 :     return (List *) def->arg;
                                378                 :                : }
                                379                 :                : 
                                380                 :                : /*
                                381                 :                :  * Raise an error about a conflicting DefElem.
                                382                 :                :  */
                                383                 :                : void
 1004 dean.a.rasheed@gmail      384                 :CBC          75 : errorConflictingDefElem(DefElem *defel, ParseState *pstate)
                                385                 :                : {
                                386         [ +  - ]:             75 :     ereport(ERROR,
                                387                 :                :             errcode(ERRCODE_SYNTAX_ERROR),
                                388                 :                :             errmsg("conflicting or redundant options"),
                                389                 :                :             parser_errposition(pstate, defel->location));
                                390                 :                : }
        

Generated by: LCOV version 2.1-beta2-3-g6141622