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