Header And Logo

PostgreSQL
| The world's most advanced open source database.

define.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * define.c
00004  *    Support routines for various kinds of object creation.
00005  *
00006  *
00007  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00008  * Portions Copyright (c) 1994, Regents of the University of California
00009  *
00010  *
00011  * IDENTIFICATION
00012  *    src/backend/commands/define.c
00013  *
00014  * DESCRIPTION
00015  *    The "DefineFoo" routines take the parse tree and pick out the
00016  *    appropriate arguments/flags, passing the results to the
00017  *    corresponding "FooDefine" routines (in src/catalog) that do
00018  *    the actual catalog-munging.  These routines also verify permission
00019  *    of the user to execute the command.
00020  *
00021  * NOTES
00022  *    These things must be defined and committed in the following order:
00023  *      "create function":
00024  *              input/output, recv/send procedures
00025  *      "create type":
00026  *              type
00027  *      "create operator":
00028  *              operators
00029  *
00030  *
00031  *-------------------------------------------------------------------------
00032  */
00033 #include "postgres.h"
00034 
00035 #include <ctype.h>
00036 #include <math.h>
00037 
00038 #include "catalog/namespace.h"
00039 #include "commands/defrem.h"
00040 #include "nodes/makefuncs.h"
00041 #include "parser/parse_type.h"
00042 #include "parser/scansup.h"
00043 #include "utils/int8.h"
00044 
00045 /*
00046  * Extract a string value (otherwise uninterpreted) from a DefElem.
00047  */
00048 char *
00049 defGetString(DefElem *def)
00050 {
00051     if (def->arg == NULL)
00052         ereport(ERROR,
00053                 (errcode(ERRCODE_SYNTAX_ERROR),
00054                  errmsg("%s requires a parameter",
00055                         def->defname)));
00056     switch (nodeTag(def->arg))
00057     {
00058         case T_Integer:
00059             {
00060                 char       *str = palloc(32);
00061 
00062                 snprintf(str, 32, "%ld", (long) intVal(def->arg));
00063                 return str;
00064             }
00065         case T_Float:
00066 
00067             /*
00068              * T_Float values are kept in string form, so this type cheat
00069              * works (and doesn't risk losing precision)
00070              */
00071             return strVal(def->arg);
00072         case T_String:
00073             return strVal(def->arg);
00074         case T_TypeName:
00075             return TypeNameToString((TypeName *) def->arg);
00076         case T_List:
00077             return NameListToString((List *) def->arg);
00078         case T_A_Star:
00079             return pstrdup("*");
00080         default:
00081             elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
00082     }
00083     return NULL;                /* keep compiler quiet */
00084 }
00085 
00086 /*
00087  * Extract a numeric value (actually double) from a DefElem.
00088  */
00089 double
00090 defGetNumeric(DefElem *def)
00091 {
00092     if (def->arg == NULL)
00093         ereport(ERROR,
00094                 (errcode(ERRCODE_SYNTAX_ERROR),
00095                  errmsg("%s requires a numeric value",
00096                         def->defname)));
00097     switch (nodeTag(def->arg))
00098     {
00099         case T_Integer:
00100             return (double) intVal(def->arg);
00101         case T_Float:
00102             return floatVal(def->arg);
00103         default:
00104             ereport(ERROR,
00105                     (errcode(ERRCODE_SYNTAX_ERROR),
00106                      errmsg("%s requires a numeric value",
00107                             def->defname)));
00108     }
00109     return 0;                   /* keep compiler quiet */
00110 }
00111 
00112 /*
00113  * Extract a boolean value from a DefElem.
00114  */
00115 bool
00116 defGetBoolean(DefElem *def)
00117 {
00118     /*
00119      * If no parameter given, assume "true" is meant.
00120      */
00121     if (def->arg == NULL)
00122         return true;
00123 
00124     /*
00125      * Allow 0, 1, "true", "false", "on", "off"
00126      */
00127     switch (nodeTag(def->arg))
00128     {
00129         case T_Integer:
00130             switch (intVal(def->arg))
00131             {
00132                 case 0:
00133                     return false;
00134                 case 1:
00135                     return true;
00136                 default:
00137                     /* otherwise, error out below */
00138                     break;
00139             }
00140             break;
00141         default:
00142             {
00143                 char       *sval = defGetString(def);
00144 
00145                 /*
00146                  * The set of strings accepted here should match up with the
00147                  * grammar's opt_boolean production.
00148                  */
00149                 if (pg_strcasecmp(sval, "true") == 0)
00150                     return true;
00151                 if (pg_strcasecmp(sval, "false") == 0)
00152                     return false;
00153                 if (pg_strcasecmp(sval, "on") == 0)
00154                     return true;
00155                 if (pg_strcasecmp(sval, "off") == 0)
00156                     return false;
00157             }
00158             break;
00159     }
00160     ereport(ERROR,
00161             (errcode(ERRCODE_SYNTAX_ERROR),
00162              errmsg("%s requires a Boolean value",
00163                     def->defname)));
00164     return false;               /* keep compiler quiet */
00165 }
00166 
00167 /*
00168  * Extract an int64 value from a DefElem.
00169  */
00170 int64
00171 defGetInt64(DefElem *def)
00172 {
00173     if (def->arg == NULL)
00174         ereport(ERROR,
00175                 (errcode(ERRCODE_SYNTAX_ERROR),
00176                  errmsg("%s requires a numeric value",
00177                         def->defname)));
00178     switch (nodeTag(def->arg))
00179     {
00180         case T_Integer:
00181             return (int64) intVal(def->arg);
00182         case T_Float:
00183 
00184             /*
00185              * Values too large for int4 will be represented as Float
00186              * constants by the lexer.  Accept these if they are valid int8
00187              * strings.
00188              */
00189             return DatumGetInt64(DirectFunctionCall1(int8in,
00190                                          CStringGetDatum(strVal(def->arg))));
00191         default:
00192             ereport(ERROR,
00193                     (errcode(ERRCODE_SYNTAX_ERROR),
00194                      errmsg("%s requires a numeric value",
00195                             def->defname)));
00196     }
00197     return 0;                   /* keep compiler quiet */
00198 }
00199 
00200 /*
00201  * Extract a possibly-qualified name (as a List of Strings) from a DefElem.
00202  */
00203 List *
00204 defGetQualifiedName(DefElem *def)
00205 {
00206     if (def->arg == NULL)
00207         ereport(ERROR,
00208                 (errcode(ERRCODE_SYNTAX_ERROR),
00209                  errmsg("%s requires a parameter",
00210                         def->defname)));
00211     switch (nodeTag(def->arg))
00212     {
00213         case T_TypeName:
00214             return ((TypeName *) def->arg)->names;
00215         case T_List:
00216             return (List *) def->arg;
00217         case T_String:
00218             /* Allow quoted name for backwards compatibility */
00219             return list_make1(def->arg);
00220         default:
00221             ereport(ERROR,
00222                     (errcode(ERRCODE_SYNTAX_ERROR),
00223                      errmsg("argument of %s must be a name",
00224                             def->defname)));
00225     }
00226     return NIL;                 /* keep compiler quiet */
00227 }
00228 
00229 /*
00230  * Extract a TypeName from a DefElem.
00231  *
00232  * Note: we do not accept a List arg here, because the parser will only
00233  * return a bare List when the name looks like an operator name.
00234  */
00235 TypeName *
00236 defGetTypeName(DefElem *def)
00237 {
00238     if (def->arg == NULL)
00239         ereport(ERROR,
00240                 (errcode(ERRCODE_SYNTAX_ERROR),
00241                  errmsg("%s requires a parameter",
00242                         def->defname)));
00243     switch (nodeTag(def->arg))
00244     {
00245         case T_TypeName:
00246             return (TypeName *) def->arg;
00247         case T_String:
00248             /* Allow quoted typename for backwards compatibility */
00249             return makeTypeNameFromNameList(list_make1(def->arg));
00250         default:
00251             ereport(ERROR,
00252                     (errcode(ERRCODE_SYNTAX_ERROR),
00253                      errmsg("argument of %s must be a type name",
00254                             def->defname)));
00255     }
00256     return NULL;                /* keep compiler quiet */
00257 }
00258 
00259 /*
00260  * Extract a type length indicator (either absolute bytes, or
00261  * -1 for "variable") from a DefElem.
00262  */
00263 int
00264 defGetTypeLength(DefElem *def)
00265 {
00266     if (def->arg == NULL)
00267         ereport(ERROR,
00268                 (errcode(ERRCODE_SYNTAX_ERROR),
00269                  errmsg("%s requires a parameter",
00270                         def->defname)));
00271     switch (nodeTag(def->arg))
00272     {
00273         case T_Integer:
00274             return intVal(def->arg);
00275         case T_Float:
00276             ereport(ERROR,
00277                     (errcode(ERRCODE_SYNTAX_ERROR),
00278                      errmsg("%s requires an integer value",
00279                             def->defname)));
00280             break;
00281         case T_String:
00282             if (pg_strcasecmp(strVal(def->arg), "variable") == 0)
00283                 return -1;      /* variable length */
00284             break;
00285         case T_TypeName:
00286             /* cope if grammar chooses to believe "variable" is a typename */
00287             if (pg_strcasecmp(TypeNameToString((TypeName *) def->arg),
00288                               "variable") == 0)
00289                 return -1;      /* variable length */
00290             break;
00291         case T_List:
00292             /* must be an operator name */
00293             break;
00294         default:
00295             elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
00296     }
00297     ereport(ERROR,
00298             (errcode(ERRCODE_SYNTAX_ERROR),
00299              errmsg("invalid argument for %s: \"%s\"",
00300                     def->defname, defGetString(def))));
00301     return 0;                   /* keep compiler quiet */
00302 }
00303 
00304 /*
00305  * Create a DefElem setting "oids" to the specified value.
00306  */
00307 DefElem *
00308 defWithOids(bool value)
00309 {
00310     return makeDefElem("oids", (Node *) makeInteger(value));
00311 }