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-2017, 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 1173 : defGetString(DefElem *def)
50 : {
51 1173 : if (def->arg == NULL)
52 0 : ereport(ERROR,
53 : (errcode(ERRCODE_SYNTAX_ERROR),
54 : errmsg("%s requires a parameter",
55 : def->defname)));
56 1173 : switch (nodeTag(def->arg))
57 : {
58 : case T_Integer:
59 24 : return psprintf("%ld", (long) intVal(def->arg));
60 : case T_Float:
61 :
62 : /*
63 : * T_Float values are kept in string form, so this type cheat
64 : * works (and doesn't risk losing precision)
65 : */
66 2 : return strVal(def->arg);
67 : case T_String:
68 1070 : return strVal(def->arg);
69 : case T_TypeName:
70 77 : return TypeNameToString((TypeName *) def->arg);
71 : case T_List:
72 0 : return NameListToString((List *) def->arg);
73 : case T_A_Star:
74 0 : return pstrdup("*");
75 : default:
76 0 : elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
77 : }
78 : return NULL; /* keep compiler quiet */
79 : }
80 :
81 : /*
82 : * Extract a numeric value (actually double) from a DefElem.
83 : */
84 : double
85 14 : defGetNumeric(DefElem *def)
86 : {
87 14 : if (def->arg == NULL)
88 0 : ereport(ERROR,
89 : (errcode(ERRCODE_SYNTAX_ERROR),
90 : errmsg("%s requires a numeric value",
91 : def->defname)));
92 14 : switch (nodeTag(def->arg))
93 : {
94 : case T_Integer:
95 11 : return (double) intVal(def->arg);
96 : case T_Float:
97 3 : return floatVal(def->arg);
98 : default:
99 0 : ereport(ERROR,
100 : (errcode(ERRCODE_SYNTAX_ERROR),
101 : errmsg("%s requires a numeric value",
102 : def->defname)));
103 : }
104 : return 0; /* keep compiler quiet */
105 : }
106 :
107 : /*
108 : * Extract a boolean value from a DefElem.
109 : */
110 : bool
111 890 : defGetBoolean(DefElem *def)
112 : {
113 : /*
114 : * If no parameter given, assume "true" is meant.
115 : */
116 890 : if (def->arg == NULL)
117 105 : return true;
118 :
119 : /*
120 : * Allow 0, 1, "true", "false", "on", "off"
121 : */
122 785 : switch (nodeTag(def->arg))
123 : {
124 : case T_Integer:
125 121 : switch (intVal(def->arg))
126 : {
127 : case 0:
128 45 : return false;
129 : case 1:
130 76 : return true;
131 : default:
132 : /* otherwise, error out below */
133 0 : break;
134 : }
135 0 : break;
136 : default:
137 : {
138 664 : char *sval = defGetString(def);
139 :
140 : /*
141 : * The set of strings accepted here should match up with the
142 : * grammar's opt_boolean production.
143 : */
144 664 : if (pg_strcasecmp(sval, "true") == 0)
145 9 : return true;
146 655 : if (pg_strcasecmp(sval, "false") == 0)
147 13 : return false;
148 642 : if (pg_strcasecmp(sval, "on") == 0)
149 4 : return true;
150 638 : if (pg_strcasecmp(sval, "off") == 0)
151 638 : return false;
152 : }
153 0 : break;
154 : }
155 0 : ereport(ERROR,
156 : (errcode(ERRCODE_SYNTAX_ERROR),
157 : errmsg("%s requires a Boolean value",
158 : def->defname)));
159 : return false; /* keep compiler quiet */
160 : }
161 :
162 : /*
163 : * Extract an int32 value from a DefElem.
164 : */
165 : int32
166 3 : defGetInt32(DefElem *def)
167 : {
168 3 : if (def->arg == NULL)
169 0 : ereport(ERROR,
170 : (errcode(ERRCODE_SYNTAX_ERROR),
171 : errmsg("%s requires an integer value",
172 : def->defname)));
173 3 : switch (nodeTag(def->arg))
174 : {
175 : case T_Integer:
176 3 : return (int32) intVal(def->arg);
177 : default:
178 0 : ereport(ERROR,
179 : (errcode(ERRCODE_SYNTAX_ERROR),
180 : errmsg("%s requires an integer value",
181 : def->defname)));
182 : }
183 : return 0; /* keep compiler quiet */
184 : }
185 :
186 : /*
187 : * Extract an int64 value from a DefElem.
188 : */
189 : int64
190 58 : defGetInt64(DefElem *def)
191 : {
192 58 : if (def->arg == NULL)
193 0 : ereport(ERROR,
194 : (errcode(ERRCODE_SYNTAX_ERROR),
195 : errmsg("%s requires a numeric value",
196 : def->defname)));
197 58 : switch (nodeTag(def->arg))
198 : {
199 : case T_Integer:
200 58 : return (int64) intVal(def->arg);
201 : case T_Float:
202 :
203 : /*
204 : * Values too large for int4 will be represented as Float
205 : * constants by the lexer. Accept these if they are valid int8
206 : * strings.
207 : */
208 0 : return DatumGetInt64(DirectFunctionCall1(int8in,
209 : CStringGetDatum(strVal(def->arg))));
210 : default:
211 0 : ereport(ERROR,
212 : (errcode(ERRCODE_SYNTAX_ERROR),
213 : errmsg("%s requires a numeric value",
214 : def->defname)));
215 : }
216 : return 0; /* keep compiler quiet */
217 : }
218 :
219 : /*
220 : * Extract a possibly-qualified name (as a List of Strings) from a DefElem.
221 : */
222 : List *
223 462 : defGetQualifiedName(DefElem *def)
224 : {
225 462 : if (def->arg == NULL)
226 0 : ereport(ERROR,
227 : (errcode(ERRCODE_SYNTAX_ERROR),
228 : errmsg("%s requires a parameter",
229 : def->defname)));
230 462 : switch (nodeTag(def->arg))
231 : {
232 : case T_TypeName:
233 345 : return ((TypeName *) def->arg)->names;
234 : case T_List:
235 102 : return (List *) def->arg;
236 : case T_String:
237 : /* Allow quoted name for backwards compatibility */
238 15 : return list_make1(def->arg);
239 : default:
240 0 : ereport(ERROR,
241 : (errcode(ERRCODE_SYNTAX_ERROR),
242 : errmsg("argument of %s must be a name",
243 : def->defname)));
244 : }
245 : return NIL; /* keep compiler quiet */
246 : }
247 :
248 : /*
249 : * Extract a TypeName from a DefElem.
250 : *
251 : * Note: we do not accept a List arg here, because the parser will only
252 : * return a bare List when the name looks like an operator name.
253 : */
254 : TypeName *
255 368 : defGetTypeName(DefElem *def)
256 : {
257 368 : if (def->arg == NULL)
258 0 : ereport(ERROR,
259 : (errcode(ERRCODE_SYNTAX_ERROR),
260 : errmsg("%s requires a parameter",
261 : def->defname)));
262 368 : switch (nodeTag(def->arg))
263 : {
264 : case T_TypeName:
265 367 : return (TypeName *) def->arg;
266 : case T_String:
267 : /* Allow quoted typename for backwards compatibility */
268 1 : return makeTypeNameFromNameList(list_make1(def->arg));
269 : default:
270 0 : ereport(ERROR,
271 : (errcode(ERRCODE_SYNTAX_ERROR),
272 : errmsg("argument of %s must be a type name",
273 : def->defname)));
274 : }
275 : return NULL; /* keep compiler quiet */
276 : }
277 :
278 : /*
279 : * Extract a type length indicator (either absolute bytes, or
280 : * -1 for "variable") from a DefElem.
281 : */
282 : int
283 6 : defGetTypeLength(DefElem *def)
284 : {
285 6 : if (def->arg == NULL)
286 0 : ereport(ERROR,
287 : (errcode(ERRCODE_SYNTAX_ERROR),
288 : errmsg("%s requires a parameter",
289 : def->defname)));
290 6 : switch (nodeTag(def->arg))
291 : {
292 : case T_Integer:
293 4 : return intVal(def->arg);
294 : case T_Float:
295 0 : ereport(ERROR,
296 : (errcode(ERRCODE_SYNTAX_ERROR),
297 : errmsg("%s requires an integer value",
298 : def->defname)));
299 : break;
300 : case T_String:
301 0 : if (pg_strcasecmp(strVal(def->arg), "variable") == 0)
302 0 : return -1; /* variable length */
303 0 : break;
304 : case T_TypeName:
305 : /* cope if grammar chooses to believe "variable" is a typename */
306 2 : if (pg_strcasecmp(TypeNameToString((TypeName *) def->arg),
307 : "variable") == 0)
308 2 : return -1; /* variable length */
309 0 : break;
310 : case T_List:
311 : /* must be an operator name */
312 0 : break;
313 : default:
314 0 : elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
315 : }
316 0 : ereport(ERROR,
317 : (errcode(ERRCODE_SYNTAX_ERROR),
318 : errmsg("invalid argument for %s: \"%s\"",
319 : def->defname, defGetString(def))));
320 : return 0; /* keep compiler quiet */
321 : }
322 :
323 : /*
324 : * Extract a list of string values (otherwise uninterpreted) from a DefElem.
325 : */
326 : List *
327 0 : defGetStringList(DefElem *def)
328 : {
329 : ListCell *cell;
330 :
331 0 : if (def->arg == NULL)
332 0 : ereport(ERROR,
333 : (errcode(ERRCODE_SYNTAX_ERROR),
334 : errmsg("%s requires a parameter",
335 : def->defname)));
336 0 : if (nodeTag(def->arg) != T_List)
337 0 : elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
338 :
339 0 : foreach(cell, (List *) def->arg)
340 : {
341 0 : Node *str = (Node *) lfirst(cell);
342 :
343 0 : if (!IsA(str, String))
344 0 : elog(ERROR, "unexpected node type in name list: %d",
345 : (int) nodeTag(str));
346 : }
347 :
348 0 : return (List *) def->arg;
349 : }
|