]> granicus.if.org Git - postgresql/blob - src/backend/commands/define.c
For some reason access/tupmacs.h has been #including utils/memutils.h,
[postgresql] / src / backend / commands / define.c
1 /*-------------------------------------------------------------------------
2  *
3  * define.c
4  *        Support routines for various kinds of object creation.
5  *
6  *
7  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  *
11  * IDENTIFICATION
12  *        $PostgreSQL: pgsql/src/backend/commands/define.c,v 1.92 2004/12/31 21:59:41 pgsql Exp $
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 "parser/parse_type.h"
41 #include "parser/scansup.h"
42 #include "utils/int8.h"
43
44
45 /*
46  * Translate the input language name to lower case, and truncate if needed.
47  *
48  * Returns a palloc'd string
49  */
50 char *
51 case_translate_language_name(const char *input)
52 {
53         return downcase_truncate_identifier(input, strlen(input), false);
54 }
55
56
57 /*
58  * Extract a string value (otherwise uninterpreted) from a DefElem.
59  */
60 char *
61 defGetString(DefElem *def)
62 {
63         if (def->arg == NULL)
64                 ereport(ERROR,
65                                 (errcode(ERRCODE_SYNTAX_ERROR),
66                                  errmsg("%s requires a parameter",
67                                                 def->defname)));
68         switch (nodeTag(def->arg))
69         {
70                 case T_Integer:
71                         {
72                                 char       *str = palloc(32);
73
74                                 snprintf(str, 32, "%ld", (long) intVal(def->arg));
75                                 return str;
76                         }
77                 case T_Float:
78
79                         /*
80                          * T_Float values are kept in string form, so this type cheat
81                          * works (and doesn't risk losing precision)
82                          */
83                         return strVal(def->arg);
84                 case T_String:
85                         return strVal(def->arg);
86                 case T_TypeName:
87                         return TypeNameToString((TypeName *) def->arg);
88                 case T_List:
89                         return NameListToString((List *) def->arg);
90                 default:
91                         elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
92         }
93         return NULL;                            /* keep compiler quiet */
94 }
95
96 /*
97  * Extract a numeric value (actually double) from a DefElem.
98  */
99 double
100 defGetNumeric(DefElem *def)
101 {
102         if (def->arg == NULL)
103                 ereport(ERROR,
104                                 (errcode(ERRCODE_SYNTAX_ERROR),
105                                  errmsg("%s requires a numeric value",
106                                                 def->defname)));
107         switch (nodeTag(def->arg))
108         {
109                 case T_Integer:
110                         return (double) intVal(def->arg);
111                 case T_Float:
112                         return floatVal(def->arg);
113                 default:
114                         ereport(ERROR,
115                                         (errcode(ERRCODE_SYNTAX_ERROR),
116                                          errmsg("%s requires a numeric value",
117                                                         def->defname)));
118         }
119         return 0;                                       /* keep compiler quiet */
120 }
121
122 /*
123  * Extract a boolean value from a DefElem.
124  */
125 bool
126 defGetBoolean(DefElem *def)
127 {
128         /*
129          * Presently, boolean flags must simply be present or absent. Later we
130          * could allow 'flag = t', 'flag = f', etc.
131          */
132         if (def->arg == NULL)
133                 return true;
134         ereport(ERROR,
135                         (errcode(ERRCODE_SYNTAX_ERROR),
136                          errmsg("%s does not take a parameter",
137                                         def->defname)));
138         return false;                           /* keep compiler quiet */
139 }
140
141 /*
142  * Extract an int64 value from a DefElem.
143  */
144 int64
145 defGetInt64(DefElem *def)
146 {
147         if (def->arg == NULL)
148                 ereport(ERROR,
149                                 (errcode(ERRCODE_SYNTAX_ERROR),
150                                  errmsg("%s requires a numeric value",
151                                                 def->defname)));
152         switch (nodeTag(def->arg))
153         {
154                 case T_Integer:
155                         return (int64) intVal(def->arg);
156                 case T_Float:
157
158                         /*
159                          * Values too large for int4 will be represented as Float
160                          * constants by the lexer.      Accept these if they are valid
161                          * int8 strings.
162                          */
163                         return DatumGetInt64(DirectFunctionCall1(int8in,
164                                                                          CStringGetDatum(strVal(def->arg))));
165                 default:
166                         ereport(ERROR,
167                                         (errcode(ERRCODE_SYNTAX_ERROR),
168                                          errmsg("%s requires a numeric value",
169                                                         def->defname)));
170         }
171         return 0;                                       /* keep compiler quiet */
172 }
173
174 /*
175  * Extract a possibly-qualified name (as a List of Strings) from a DefElem.
176  */
177 List *
178 defGetQualifiedName(DefElem *def)
179 {
180         if (def->arg == NULL)
181                 ereport(ERROR,
182                                 (errcode(ERRCODE_SYNTAX_ERROR),
183                                  errmsg("%s requires a parameter",
184                                                 def->defname)));
185         switch (nodeTag(def->arg))
186         {
187                 case T_TypeName:
188                         return ((TypeName *) def->arg)->names;
189                 case T_List:
190                         return (List *) def->arg;
191                 case T_String:
192                         /* Allow quoted name for backwards compatibility */
193                         return list_make1(def->arg);
194                 default:
195                         ereport(ERROR,
196                                         (errcode(ERRCODE_SYNTAX_ERROR),
197                                          errmsg("argument of %s must be a name",
198                                                         def->defname)));
199         }
200         return NIL;                                     /* keep compiler quiet */
201 }
202
203 /*
204  * Extract a TypeName from a DefElem.
205  *
206  * Note: we do not accept a List arg here, because the parser will only
207  * return a bare List when the name looks like an operator name.
208  */
209 TypeName *
210 defGetTypeName(DefElem *def)
211 {
212         if (def->arg == NULL)
213                 ereport(ERROR,
214                                 (errcode(ERRCODE_SYNTAX_ERROR),
215                                  errmsg("%s requires a parameter",
216                                                 def->defname)));
217         switch (nodeTag(def->arg))
218         {
219                 case T_TypeName:
220                         return (TypeName *) def->arg;
221                 case T_String:
222                         {
223                                 /* Allow quoted typename for backwards compatibility */
224                                 TypeName   *n = makeNode(TypeName);
225
226                                 n->names = list_make1(def->arg);
227                                 n->typmod = -1;
228                                 return n;
229                         }
230                 default:
231                         ereport(ERROR,
232                                         (errcode(ERRCODE_SYNTAX_ERROR),
233                                          errmsg("argument of %s must be a type name",
234                                                         def->defname)));
235         }
236         return NULL;                            /* keep compiler quiet */
237 }
238
239 /*
240  * Extract a type length indicator (either absolute bytes, or
241  * -1 for "variable") from a DefElem.
242  */
243 int
244 defGetTypeLength(DefElem *def)
245 {
246         if (def->arg == NULL)
247                 ereport(ERROR,
248                                 (errcode(ERRCODE_SYNTAX_ERROR),
249                                  errmsg("%s requires a parameter",
250                                                 def->defname)));
251         switch (nodeTag(def->arg))
252         {
253                 case T_Integer:
254                         return intVal(def->arg);
255                 case T_Float:
256                         ereport(ERROR,
257                                         (errcode(ERRCODE_SYNTAX_ERROR),
258                                          errmsg("%s requires an integer value",
259                                                         def->defname)));
260                         break;
261                 case T_String:
262                         if (pg_strcasecmp(strVal(def->arg), "variable") == 0)
263                                 return -1;              /* variable length */
264                         break;
265                 case T_TypeName:
266                         /* cope if grammar chooses to believe "variable" is a typename */
267                         if (pg_strcasecmp(TypeNameToString((TypeName *) def->arg),
268                                                           "variable") == 0)
269                                 return -1;              /* variable length */
270                         break;
271                 case T_List:
272                         /* must be an operator name */
273                         break;
274                 default:
275                         elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
276         }
277         ereport(ERROR,
278                         (errcode(ERRCODE_SYNTAX_ERROR),
279                          errmsg("invalid argument for %s: \"%s\"",
280                                         def->defname, defGetString(def))));
281         return 0;                                       /* keep compiler quiet */
282 }