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 HEAD vs 15 Lines: 63.8 % 138 88 50 88
Current Date: 2023-04-08 17:13:01 Functions: 90.9 % 11 10 1 10
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (120,180] days: 50.0 % 10 5 5 5
Legend: Lines: hit not hit (240..) days: 64.8 % 128 83 45 83
Function coverage date bins:
(120,180] days: 100.0 % 1 1 1
(240..) days: 90.0 % 10 9 1 9

 Age         Owner                  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-2023, 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 "parser/scansup.h"
                                 43                 : #include "utils/builtins.h"
                                 44                 : 
                                 45                 : /*
                                 46                 :  * Extract a string value (otherwise uninterpreted) from a DefElem.
                                 47                 :  */
                                 48                 : char *
 5118 tgl                        49 CBC       36022 : defGetString(DefElem *def)
                                 50                 : {
                                 51           36022 :     if (def->arg == NULL)
 7203 tgl                        52 UBC           0 :         ereport(ERROR,
                                 53                 :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                 54                 :                  errmsg("%s requires a parameter",
                                 55                 :                         def->defname)));
 5118 tgl                        56 CBC       36022 :     switch (nodeTag(def->arg))
                                 57                 :     {
 8219                            58             480 :         case T_Integer:
 3380 peter_e                    59             480 :             return psprintf("%ld", (long) intVal(def->arg));
 8219 tgl                        60              53 :         case T_Float:
  450 peter                      61              53 :             return castNode(Float, def->arg)->fval;
                                 62             184 :         case T_Boolean:
                                 63             184 :             return boolVal(def->arg) ? "true" : "false";
 8219 tgl                        64           21676 :         case T_String:
 5118                            65           21676 :             return strVal(def->arg);
 8219                            66           13629 :         case T_TypeName:
 5118                            67           13629 :             return TypeNameToString((TypeName *) def->arg);
 7547 tgl                        68 UBC           0 :         case T_List:
 5118                            69               0 :             return NameListToString((List *) def->arg);
 4948                            70               0 :         case T_A_Star:
                                 71               0 :             return pstrdup("*");
 8219                            72               0 :         default:
 5118                            73               0 :             elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
                                 74                 :     }
                                 75                 :     return NULL;                /* keep compiler quiet */
                                 76                 : }
                                 77                 : 
                                 78                 : /*
                                 79                 :  * Extract a numeric value (actually double) from a DefElem.
                                 80                 :  */
                                 81                 : double
 8590 tgl                        82 CBC       15173 : defGetNumeric(DefElem *def)
                                 83                 : {
                                 84           15173 :     if (def->arg == NULL)
 7203 tgl                        85 UBC           0 :         ereport(ERROR,
                                 86                 :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                 87                 :                  errmsg("%s requires a numeric value",
                                 88                 :                         def->defname)));
 8590 tgl                        89 CBC       15173 :     switch (nodeTag(def->arg))
                                 90                 :     {
                                 91           15163 :         case T_Integer:
                                 92           15163 :             return (double) intVal(def->arg);
                                 93              10 :         case T_Float:
                                 94              10 :             return floatVal(def->arg);
 8590 tgl                        95 UBC           0 :         default:
 7203                            96               0 :             ereport(ERROR,
                                 97                 :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                 98                 :                      errmsg("%s requires a numeric value",
                                 99                 :                             def->defname)));
                                100                 :     }
                                101                 :     return 0;                   /* keep compiler quiet */
                                102                 : }
                                103                 : 
                                104                 : /*
                                105                 :  * Extract a boolean value from a DefElem.
                                106                 :  */
                                107                 : bool
 5118 tgl                       108 CBC       13884 : defGetBoolean(DefElem *def)
                                109                 : {
                                110                 :     /*
                                111                 :      * If no parameter value given, assume "true" is meant.
                                112                 :      */
                                113           13884 :     if (def->arg == NULL)
 6904                           114            5910 :         return true;
                                115                 : 
                                116                 :     /*
                                117                 :      * Allow 0, 1, "true", "false", "on", "off"
                                118                 :      */
 5118                           119            7974 :     switch (nodeTag(def->arg))
                                120                 :     {
 6125 bruce                     121             198 :         case T_Integer:
 5118 tgl                       122             198 :             switch (intVal(def->arg))
                                123                 :             {
 6124                           124             166 :                 case 0:
                                125             166 :                     return false;
                                126              29 :                 case 1:
                                127              29 :                     return true;
                                128               3 :                 default:
                                129                 :                     /* otherwise, error out below */
                                130               3 :                     break;
                                131                 :             }
 6125 bruce                     132               3 :             break;
                                133            7776 :         default:
                                134                 :             {
 5118 tgl                       135            7776 :                 char       *sval = defGetString(def);
                                136                 : 
                                137                 :                 /*
                                138                 :                  * The set of strings accepted here should match up with the
                                139                 :                  * grammar's opt_boolean_or_string production.
                                140                 :                  */
 6124                           141            7776 :                 if (pg_strcasecmp(sval, "true") == 0)
                                142             967 :                     return true;
                                143            6809 :                 if (pg_strcasecmp(sval, "false") == 0)
                                144             850 :                     return false;
 5005                           145            5959 :                 if (pg_strcasecmp(sval, "on") == 0)
                                146              59 :                     return true;
                                147            5900 :                 if (pg_strcasecmp(sval, "off") == 0)
                                148            5891 :                     return false;
                                149                 :             }
 6125 bruce                     150               9 :             break;
                                151                 :     }
 6904 tgl                       152              12 :     ereport(ERROR,
                                153                 :             (errcode(ERRCODE_SYNTAX_ERROR),
                                154                 :              errmsg("%s requires a Boolean value",
                                155                 :                     def->defname)));
                                156                 :     return false;               /* keep compiler quiet */
                                157                 : }
                                158                 : 
                                159                 : /*
                                160                 :  * Extract an int32 value from a DefElem.
                                161                 :  */
                                162                 : int32
 3431                           163             775 : defGetInt32(DefElem *def)
                                164                 : {
                                165             775 :     if (def->arg == NULL)
 3431 tgl                       166 UBC           0 :         ereport(ERROR,
                                167                 :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                168                 :                  errmsg("%s requires an integer value",
                                169                 :                         def->defname)));
 3431 tgl                       170 CBC         775 :     switch (nodeTag(def->arg))
                                171                 :     {
                                172             775 :         case T_Integer:
                                173             775 :             return (int32) intVal(def->arg);
 3431 tgl                       174 UBC           0 :         default:
                                175               0 :             ereport(ERROR,
                                176                 :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                177                 :                      errmsg("%s requires an integer value",
                                178                 :                             def->defname)));
                                179                 :     }
                                180                 :     return 0;                   /* keep compiler quiet */
                                181                 : }
                                182                 : 
                                183                 : /*
                                184                 :  * Extract an int64 value from a DefElem.
                                185                 :  */
                                186                 : int64
 7627 tgl                       187 CBC         327 : defGetInt64(DefElem *def)
                                188                 : {
                                189             327 :     if (def->arg == NULL)
 7203 tgl                       190 UBC           0 :         ereport(ERROR,
                                191                 :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                192                 :                  errmsg("%s requires a numeric value",
                                193                 :                         def->defname)));
 7627 tgl                       194 CBC         327 :     switch (nodeTag(def->arg))
                                195                 :     {
                                196             311 :         case T_Integer:
                                197             311 :             return (int64) intVal(def->arg);
                                198              16 :         case T_Float:
                                199                 : 
                                200                 :             /*
                                201                 :              * Values too large for int4 will be represented as Float
                                202                 :              * constants by the lexer.  Accept these if they are valid int8
                                203                 :              * strings.
                                204                 :              */
                                205              16 :             return DatumGetInt64(DirectFunctionCall1(int8in,
                                206                 :                                                      CStringGetDatum(castNode(Float, def->arg)->fval)));
 7627 tgl                       207 UBC           0 :         default:
 7203                           208               0 :             ereport(ERROR,
                                209                 :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                210                 :                      errmsg("%s requires a numeric value",
                                211                 :                             def->defname)));
                                212                 :     }
                                213                 :     return 0;                   /* keep compiler quiet */
                                214                 : }
                                215                 : 
                                216                 : /*
                                217                 :  * Extract an OID value from a DefElem.
                                218                 :  */
                                219                 : Oid
  156 tgl                       220 CBC         615 : defGetObjectId(DefElem *def)
                                221                 : {
                                222             615 :     if (def->arg == NULL)
  156 tgl                       223 UBC           0 :         ereport(ERROR,
                                224                 :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                225                 :                  errmsg("%s requires a numeric value",
                                226                 :                         def->defname)));
  156 tgl                       227 CBC         615 :     switch (nodeTag(def->arg))
                                228                 :     {
                                229             615 :         case T_Integer:
                                230             615 :             return (Oid) intVal(def->arg);
  156 tgl                       231 UBC           0 :         case T_Float:
                                232                 : 
                                233                 :             /*
                                234                 :              * Values too large for int4 will be represented as Float
                                235                 :              * constants by the lexer.  Accept these if they are valid OID
                                236                 :              * strings.
                                237                 :              */
                                238               0 :             return DatumGetObjectId(DirectFunctionCall1(oidin,
                                239                 :                                                         CStringGetDatum(castNode(Float, def->arg)->fval)));
                                240               0 :         default:
                                241               0 :             ereport(ERROR,
                                242                 :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                243                 :                      errmsg("%s requires a numeric value",
                                244                 :                             def->defname)));
                                245                 :     }
                                246                 :     return 0;                   /* keep compiler quiet */
                                247                 : }
                                248                 : 
                                249                 : /*
                                250                 :  * Extract a possibly-qualified name (as a List of Strings) from a DefElem.
                                251                 :  */
                                252                 : List *
 7670 tgl                       253 CBC       22369 : defGetQualifiedName(DefElem *def)
                                254                 : {
                                255           22369 :     if (def->arg == NULL)
 7203 tgl                       256 UBC           0 :         ereport(ERROR,
                                257                 :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                258                 :                  errmsg("%s requires a parameter",
                                259                 :                         def->defname)));
 7670 tgl                       260 CBC       22369 :     switch (nodeTag(def->arg))
                                261                 :     {
                                262           12522 :         case T_TypeName:
                                263           22369 :             return ((TypeName *) def->arg)->names;
 7547                           264            1131 :         case T_List:
                                265            1131 :             return (List *) def->arg;
 7670                           266            8716 :         case T_String:
                                267                 :             /* Allow quoted name for backwards compatibility */
 6892 neilc                     268            8716 :             return list_make1(def->arg);
 7670 tgl                       269 UBC           0 :         default:
 7203                           270               0 :             ereport(ERROR,
                                271                 :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                272                 :                      errmsg("argument of %s must be a name",
                                273                 :                             def->defname)));
                                274                 :     }
                                275                 :     return NIL;                 /* keep compiler quiet */
                                276                 : }
                                277                 : 
                                278                 : /*
                                279                 :  * Extract a TypeName from a DefElem.
                                280                 :  *
                                281                 :  * Note: we do not accept a List arg here, because the parser will only
                                282                 :  * return a bare List when the name looks like an operator name.
                                283                 :  */
                                284                 : TypeName *
 7681 tgl                       285 CBC        2762 : defGetTypeName(DefElem *def)
                                286                 : {
                                287            2762 :     if (def->arg == NULL)
 7203 tgl                       288 UBC           0 :         ereport(ERROR,
                                289                 :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                290                 :                  errmsg("%s requires a parameter",
                                291                 :                         def->defname)));
 7681 tgl                       292 CBC        2762 :     switch (nodeTag(def->arg))
                                293                 :     {
                                294            2759 :         case T_TypeName:
                                295            2762 :             return (TypeName *) def->arg;
                                296               3 :         case T_String:
                                297                 :             /* Allow quoted typename for backwards compatibility */
 6235                           298               3 :             return makeTypeNameFromNameList(list_make1(def->arg));
 7681 tgl                       299 UBC           0 :         default:
 7203                           300               0 :             ereport(ERROR,
                                301                 :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                302                 :                      errmsg("argument of %s must be a type name",
                                303                 :                             def->defname)));
                                304                 :     }
                                305                 :     return NULL;                /* keep compiler quiet */
                                306                 : }
                                307                 : 
                                308                 : /*
                                309                 :  * Extract a type length indicator (either absolute bytes, or
                                310                 :  * -1 for "variable") from a DefElem.
                                311                 :  */
                                312                 : int
 9344 bruce                     313 CBC          64 : defGetTypeLength(DefElem *def)
                                314                 : {
 8219 tgl                       315              64 :     if (def->arg == NULL)
 7203 tgl                       316 UBC           0 :         ereport(ERROR,
                                317                 :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                318                 :                  errmsg("%s requires a parameter",
                                319                 :                         def->defname)));
 8219 tgl                       320 CBC          64 :     switch (nodeTag(def->arg))
                                321                 :     {
                                322              49 :         case T_Integer:
                                323              49 :             return intVal(def->arg);
 8219 tgl                       324 UBC           0 :         case T_Float:
 7203                           325               0 :             ereport(ERROR,
                                326                 :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                327                 :                      errmsg("%s requires an integer value",
                                328                 :                             def->defname)));
                                329                 :             break;
 8219                           330               0 :         case T_String:
 6911                           331               0 :             if (pg_strcasecmp(strVal(def->arg), "variable") == 0)
 8219                           332               0 :                 return -1;      /* variable length */
                                333               0 :             break;
 8219 tgl                       334 CBC          15 :         case T_TypeName:
                                335                 :             /* cope if grammar chooses to believe "variable" is a typename */
 6911                           336              15 :             if (pg_strcasecmp(TypeNameToString((TypeName *) def->arg),
                                337                 :                               "variable") == 0)
 8219                           338              15 :                 return -1;      /* variable length */
 8219 tgl                       339 UBC           0 :             break;
 7547                           340               0 :         case T_List:
                                341                 :             /* must be an operator name */
                                342               0 :             break;
 8219                           343               0 :         default:
 7203                           344               0 :             elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
                                345                 :     }
                                346               0 :     ereport(ERROR,
                                347                 :             (errcode(ERRCODE_SYNTAX_ERROR),
                                348                 :              errmsg("invalid argument for %s: \"%s\"",
                                349                 :                     def->defname, defGetString(def))));
                                350                 :     return 0;                   /* keep compiler quiet */
                                351                 : }
                                352                 : 
                                353                 : /*
                                354                 :  * Extract a list of string values (otherwise uninterpreted) from a DefElem.
                                355                 :  */
                                356                 : List *
 2271 peter_e                   357               0 : defGetStringList(DefElem *def)
                                358                 : {
                                359                 :     ListCell   *cell;
                                360                 : 
                                361               0 :     if (def->arg == NULL)
                                362               0 :         ereport(ERROR,
                                363                 :                 (errcode(ERRCODE_SYNTAX_ERROR),
                                364                 :                  errmsg("%s requires a parameter",
                                365                 :                         def->defname)));
                                366               0 :     if (nodeTag(def->arg) != T_List)
                                367               0 :         elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
                                368                 : 
 2153 bruce                     369               0 :     foreach(cell, (List *) def->arg)
                                370                 :     {
 2271 peter_e                   371               0 :         Node       *str = (Node *) lfirst(cell);
                                372                 : 
                                373               0 :         if (!IsA(str, String))
                                374               0 :             elog(ERROR, "unexpected node type in name list: %d",
                                375                 :                  (int) nodeTag(str));
                                376                 :     }
                                377                 : 
                                378               0 :     return (List *) def->arg;
                                379                 : }
                                380                 : 
                                381                 : /*
                                382                 :  * Raise an error about a conflicting DefElem.
                                383                 :  */
                                384                 : void
  633 dean.a.rasheed            385 CBC          63 : errorConflictingDefElem(DefElem *defel, ParseState *pstate)
                                386                 : {
                                387              63 :     ereport(ERROR,
                                388                 :             errcode(ERRCODE_SYNTAX_ERROR),
                                389                 :             errmsg("conflicting or redundant options"),
                                390                 :             parser_errposition(pstate, defel->location));
                                391                 : }
        

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