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