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 | */ |
48 | char * |
49 | defGetString(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 | */ |
84 | double |
85 | defGetNumeric(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 | */ |
110 | bool |
111 | defGetBoolean(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 | */ |
165 | int32 |
166 | defGetInt32(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 | */ |
189 | int64 |
190 | defGetInt64(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 | */ |
222 | List * |
223 | defGetQualifiedName(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 | */ |
254 | TypeName * |
255 | defGetTypeName(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 | */ |
282 | int |
283 | defGetTypeLength(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 | */ |
326 | List * |
327 | defGetStringList(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 | |