1/*-------------------------------------------------------------------------
2 *
3 * define.c
4 * Support routines for various kinds of object creation.
5 *
6 *
7 * Portions Copyright (c) 1996-2019, 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 */
48char *
49defGetString(DefElem *def)
50{
51 if (def->arg == NULL)
52 ereport(ERROR,
53 (errcode(ERRCODE_SYNTAX_ERROR),
54 errmsg("%s requires a parameter",
55 def->defname)));
56 switch (nodeTag(def->arg))
57 {
58 case T_Integer:
59 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 return strVal(def->arg);
67 case T_String:
68 return strVal(def->arg);
69 case T_TypeName:
70 return TypeNameToString((TypeName *) def->arg);
71 case T_List:
72 return NameListToString((List *) def->arg);
73 case T_A_Star:
74 return pstrdup("*");
75 default:
76 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 */
84double
85defGetNumeric(DefElem *def)
86{
87 if (def->arg == NULL)
88 ereport(ERROR,
89 (errcode(ERRCODE_SYNTAX_ERROR),
90 errmsg("%s requires a numeric value",
91 def->defname)));
92 switch (nodeTag(def->arg))
93 {
94 case T_Integer:
95 return (double) intVal(def->arg);
96 case T_Float:
97 return floatVal(def->arg);
98 default:
99 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 */
110bool
111defGetBoolean(DefElem *def)
112{
113 /*
114 * If no parameter given, assume "true" is meant.
115 */
116 if (def->arg == NULL)
117 return true;
118
119 /*
120 * Allow 0, 1, "true", "false", "on", "off"
121 */
122 switch (nodeTag(def->arg))
123 {
124 case T_Integer:
125 switch (intVal(def->arg))
126 {
127 case 0:
128 return false;
129 case 1:
130 return true;
131 default:
132 /* otherwise, error out below */
133 break;
134 }
135 break;
136 default:
137 {
138 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 if (pg_strcasecmp(sval, "true") == 0)
145 return true;
146 if (pg_strcasecmp(sval, "false") == 0)
147 return false;
148 if (pg_strcasecmp(sval, "on") == 0)
149 return true;
150 if (pg_strcasecmp(sval, "off") == 0)
151 return false;
152 }
153 break;
154 }
155 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 */
165int32
166defGetInt32(DefElem *def)
167{
168 if (def->arg == NULL)
169 ereport(ERROR,
170 (errcode(ERRCODE_SYNTAX_ERROR),
171 errmsg("%s requires an integer value",
172 def->defname)));
173 switch (nodeTag(def->arg))
174 {
175 case T_Integer:
176 return (int32) intVal(def->arg);
177 default:
178 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 */
189int64
190defGetInt64(DefElem *def)
191{
192 if (def->arg == NULL)
193 ereport(ERROR,
194 (errcode(ERRCODE_SYNTAX_ERROR),
195 errmsg("%s requires a numeric value",
196 def->defname)));
197 switch (nodeTag(def->arg))
198 {
199 case T_Integer:
200 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 return DatumGetInt64(DirectFunctionCall1(int8in,
209 CStringGetDatum(strVal(def->arg))));
210 default:
211 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 */
222List *
223defGetQualifiedName(DefElem *def)
224{
225 if (def->arg == NULL)
226 ereport(ERROR,
227 (errcode(ERRCODE_SYNTAX_ERROR),
228 errmsg("%s requires a parameter",
229 def->defname)));
230 switch (nodeTag(def->arg))
231 {
232 case T_TypeName:
233 return ((TypeName *) def->arg)->names;
234 case T_List:
235 return (List *) def->arg;
236 case T_String:
237 /* Allow quoted name for backwards compatibility */
238 return list_make1(def->arg);
239 default:
240 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 */
254TypeName *
255defGetTypeName(DefElem *def)
256{
257 if (def->arg == NULL)
258 ereport(ERROR,
259 (errcode(ERRCODE_SYNTAX_ERROR),
260 errmsg("%s requires a parameter",
261 def->defname)));
262 switch (nodeTag(def->arg))
263 {
264 case T_TypeName:
265 return (TypeName *) def->arg;
266 case T_String:
267 /* Allow quoted typename for backwards compatibility */
268 return makeTypeNameFromNameList(list_make1(def->arg));
269 default:
270 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 */
282int
283defGetTypeLength(DefElem *def)
284{
285 if (def->arg == NULL)
286 ereport(ERROR,
287 (errcode(ERRCODE_SYNTAX_ERROR),
288 errmsg("%s requires a parameter",
289 def->defname)));
290 switch (nodeTag(def->arg))
291 {
292 case T_Integer:
293 return intVal(def->arg);
294 case T_Float:
295 ereport(ERROR,
296 (errcode(ERRCODE_SYNTAX_ERROR),
297 errmsg("%s requires an integer value",
298 def->defname)));
299 break;
300 case T_String:
301 if (pg_strcasecmp(strVal(def->arg), "variable") == 0)
302 return -1; /* variable length */
303 break;
304 case T_TypeName:
305 /* cope if grammar chooses to believe "variable" is a typename */
306 if (pg_strcasecmp(TypeNameToString((TypeName *) def->arg),
307 "variable") == 0)
308 return -1; /* variable length */
309 break;
310 case T_List:
311 /* must be an operator name */
312 break;
313 default:
314 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
315 }
316 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 */
326List *
327defGetStringList(DefElem *def)
328{
329 ListCell *cell;
330
331 if (def->arg == NULL)
332 ereport(ERROR,
333 (errcode(ERRCODE_SYNTAX_ERROR),
334 errmsg("%s requires a parameter",
335 def->defname)));
336 if (nodeTag(def->arg) != T_List)
337 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
338
339 foreach(cell, (List *) def->arg)
340 {
341 Node *str = (Node *) lfirst(cell);
342
343 if (!IsA(str, String))
344 elog(ERROR, "unexpected node type in name list: %d",
345 (int) nodeTag(str));
346 }
347
348 return (List *) def->arg;
349}
350