LCOV - code coverage report
Current view: top level - src/backend/commands - define.c (source / functions) Hit Total Coverage
Test: PostgreSQL 16beta1 Lines: 88 138 63.8 %
Date: 2023-05-30 17:15:13 Functions: 10 11 90.9 %
Legend: Lines: hit not hit

          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 *
      49       71844 : defGetString(DefElem *def)
      50             : {
      51       71844 :     if (def->arg == NULL)
      52           0 :         ereport(ERROR,
      53             :                 (errcode(ERRCODE_SYNTAX_ERROR),
      54             :                  errmsg("%s requires a parameter",
      55             :                         def->defname)));
      56       71844 :     switch (nodeTag(def->arg))
      57             :     {
      58         970 :         case T_Integer:
      59         970 :             return psprintf("%ld", (long) intVal(def->arg));
      60         106 :         case T_Float:
      61         106 :             return castNode(Float, def->arg)->fval;
      62         368 :         case T_Boolean:
      63         368 :             return boolVal(def->arg) ? "true" : "false";
      64       43312 :         case T_String:
      65       43312 :             return strVal(def->arg);
      66       27088 :         case T_TypeName:
      67       27088 :             return TypeNameToString((TypeName *) def->arg);
      68           0 :         case T_List:
      69           0 :             return NameListToString((List *) def->arg);
      70           0 :         case T_A_Star:
      71           0 :             return pstrdup("*");
      72           0 :         default:
      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
      82       30146 : defGetNumeric(DefElem *def)
      83             : {
      84       30146 :     if (def->arg == NULL)
      85           0 :         ereport(ERROR,
      86             :                 (errcode(ERRCODE_SYNTAX_ERROR),
      87             :                  errmsg("%s requires a numeric value",
      88             :                         def->defname)));
      89       30146 :     switch (nodeTag(def->arg))
      90             :     {
      91       30126 :         case T_Integer:
      92       30126 :             return (double) intVal(def->arg);
      93          20 :         case T_Float:
      94          20 :             return floatVal(def->arg);
      95           0 :         default:
      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
     108       27952 : defGetBoolean(DefElem *def)
     109             : {
     110             :     /*
     111             :      * If no parameter value given, assume "true" is meant.
     112             :      */
     113       27952 :     if (def->arg == NULL)
     114       11914 :         return true;
     115             : 
     116             :     /*
     117             :      * Allow 0, 1, "true", "false", "on", "off"
     118             :      */
     119       16038 :     switch (nodeTag(def->arg))
     120             :     {
     121         378 :         case T_Integer:
     122         378 :             switch (intVal(def->arg))
     123             :             {
     124         314 :                 case 0:
     125         314 :                     return false;
     126          58 :                 case 1:
     127          58 :                     return true;
     128           6 :                 default:
     129             :                     /* otherwise, error out below */
     130           6 :                     break;
     131             :             }
     132           6 :             break;
     133       15660 :         default:
     134             :             {
     135       15660 :                 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             :                  */
     141       15660 :                 if (pg_strcasecmp(sval, "true") == 0)
     142        1922 :                     return true;
     143       13738 :                 if (pg_strcasecmp(sval, "false") == 0)
     144        1690 :                     return false;
     145       12048 :                 if (pg_strcasecmp(sval, "on") == 0)
     146         120 :                     return true;
     147       11928 :                 if (pg_strcasecmp(sval, "off") == 0)
     148       11910 :                     return false;
     149             :             }
     150          18 :             break;
     151             :     }
     152          24 :     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
     163        1558 : defGetInt32(DefElem *def)
     164             : {
     165        1558 :     if (def->arg == NULL)
     166           0 :         ereport(ERROR,
     167             :                 (errcode(ERRCODE_SYNTAX_ERROR),
     168             :                  errmsg("%s requires an integer value",
     169             :                         def->defname)));
     170        1558 :     switch (nodeTag(def->arg))
     171             :     {
     172        1558 :         case T_Integer:
     173        1558 :             return (int32) intVal(def->arg);
     174           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
     187         654 : defGetInt64(DefElem *def)
     188             : {
     189         654 :     if (def->arg == NULL)
     190           0 :         ereport(ERROR,
     191             :                 (errcode(ERRCODE_SYNTAX_ERROR),
     192             :                  errmsg("%s requires a numeric value",
     193             :                         def->defname)));
     194         654 :     switch (nodeTag(def->arg))
     195             :     {
     196         622 :         case T_Integer:
     197         622 :             return (int64) intVal(def->arg);
     198          32 :         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          32 :             return DatumGetInt64(DirectFunctionCall1(int8in,
     206             :                                                      CStringGetDatum(castNode(Float, def->arg)->fval)));
     207           0 :         default:
     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
     220        1222 : defGetObjectId(DefElem *def)
     221             : {
     222        1222 :     if (def->arg == NULL)
     223           0 :         ereport(ERROR,
     224             :                 (errcode(ERRCODE_SYNTAX_ERROR),
     225             :                  errmsg("%s requires a numeric value",
     226             :                         def->defname)));
     227        1222 :     switch (nodeTag(def->arg))
     228             :     {
     229        1222 :         case T_Integer:
     230        1222 :             return (Oid) intVal(def->arg);
     231           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 *
     253       44630 : defGetQualifiedName(DefElem *def)
     254             : {
     255       44630 :     if (def->arg == NULL)
     256           0 :         ereport(ERROR,
     257             :                 (errcode(ERRCODE_SYNTAX_ERROR),
     258             :                  errmsg("%s requires a parameter",
     259             :                         def->defname)));
     260       44630 :     switch (nodeTag(def->arg))
     261             :     {
     262       25028 :         case T_TypeName:
     263       44630 :             return ((TypeName *) def->arg)->names;
     264        2244 :         case T_List:
     265        2244 :             return (List *) def->arg;
     266       17358 :         case T_String:
     267             :             /* Allow quoted name for backwards compatibility */
     268       17358 :             return list_make1(def->arg);
     269           0 :         default:
     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 *
     285        5594 : defGetTypeName(DefElem *def)
     286             : {
     287        5594 :     if (def->arg == NULL)
     288           0 :         ereport(ERROR,
     289             :                 (errcode(ERRCODE_SYNTAX_ERROR),
     290             :                  errmsg("%s requires a parameter",
     291             :                         def->defname)));
     292        5594 :     switch (nodeTag(def->arg))
     293             :     {
     294        5588 :         case T_TypeName:
     295        5594 :             return (TypeName *) def->arg;
     296           6 :         case T_String:
     297             :             /* Allow quoted typename for backwards compatibility */
     298           6 :             return makeTypeNameFromNameList(list_make1(def->arg));
     299           0 :         default:
     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
     313         130 : defGetTypeLength(DefElem *def)
     314             : {
     315         130 :     if (def->arg == NULL)
     316           0 :         ereport(ERROR,
     317             :                 (errcode(ERRCODE_SYNTAX_ERROR),
     318             :                  errmsg("%s requires a parameter",
     319             :                         def->defname)));
     320         130 :     switch (nodeTag(def->arg))
     321             :     {
     322         100 :         case T_Integer:
     323         100 :             return intVal(def->arg);
     324           0 :         case T_Float:
     325           0 :             ereport(ERROR,
     326             :                     (errcode(ERRCODE_SYNTAX_ERROR),
     327             :                      errmsg("%s requires an integer value",
     328             :                             def->defname)));
     329             :             break;
     330           0 :         case T_String:
     331           0 :             if (pg_strcasecmp(strVal(def->arg), "variable") == 0)
     332           0 :                 return -1;      /* variable length */
     333           0 :             break;
     334          30 :         case T_TypeName:
     335             :             /* cope if grammar chooses to believe "variable" is a typename */
     336          30 :             if (pg_strcasecmp(TypeNameToString((TypeName *) def->arg),
     337             :                               "variable") == 0)
     338          30 :                 return -1;      /* variable length */
     339           0 :             break;
     340           0 :         case T_List:
     341             :             /* must be an operator name */
     342           0 :             break;
     343           0 :         default:
     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 *
     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             : 
     369           0 :     foreach(cell, (List *) def->arg)
     370             :     {
     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
     385         126 : errorConflictingDefElem(DefElem *defel, ParseState *pstate)
     386             : {
     387         126 :     ereport(ERROR,
     388             :             errcode(ERRCODE_SYNTAX_ERROR),
     389             :             errmsg("conflicting or redundant options"),
     390             :             parser_errposition(pstate, defel->location));
     391             : }

Generated by: LCOV version 1.14