Age Owner TLA 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 *
5118 tgl 49 CBC 36022 : defGetString(DefElem *def)
50 : {
51 36022 : if (def->arg == NULL)
7203 tgl 52 UBC 0 : ereport(ERROR,
53 : (errcode(ERRCODE_SYNTAX_ERROR),
54 : errmsg("%s requires a parameter",
55 : def->defname)));
5118 tgl 56 CBC 36022 : switch (nodeTag(def->arg))
57 : {
8219 58 480 : case T_Integer:
3380 peter_e 59 480 : return psprintf("%ld", (long) intVal(def->arg));
8219 tgl 60 53 : case T_Float:
450 peter 61 53 : return castNode(Float, def->arg)->fval;
62 184 : case T_Boolean:
63 184 : return boolVal(def->arg) ? "true" : "false";
8219 tgl 64 21676 : case T_String:
5118 65 21676 : return strVal(def->arg);
8219 66 13629 : case T_TypeName:
5118 67 13629 : return TypeNameToString((TypeName *) def->arg);
7547 tgl 68 UBC 0 : case T_List:
5118 69 0 : return NameListToString((List *) def->arg);
4948 70 0 : case T_A_Star:
71 0 : return pstrdup("*");
8219 72 0 : default:
5118 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
8590 tgl 82 CBC 15173 : defGetNumeric(DefElem *def)
83 : {
84 15173 : if (def->arg == NULL)
7203 tgl 85 UBC 0 : ereport(ERROR,
86 : (errcode(ERRCODE_SYNTAX_ERROR),
87 : errmsg("%s requires a numeric value",
88 : def->defname)));
8590 tgl 89 CBC 15173 : switch (nodeTag(def->arg))
90 : {
91 15163 : case T_Integer:
92 15163 : return (double) intVal(def->arg);
93 10 : case T_Float:
94 10 : return floatVal(def->arg);
8590 tgl 95 UBC 0 : default:
7203 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
5118 tgl 108 CBC 13884 : defGetBoolean(DefElem *def)
109 : {
110 : /*
111 : * If no parameter value given, assume "true" is meant.
112 : */
113 13884 : if (def->arg == NULL)
6904 114 5910 : return true;
115 :
116 : /*
117 : * Allow 0, 1, "true", "false", "on", "off"
118 : */
5118 119 7974 : switch (nodeTag(def->arg))
120 : {
6125 bruce 121 198 : case T_Integer:
5118 tgl 122 198 : switch (intVal(def->arg))
123 : {
6124 124 166 : case 0:
125 166 : return false;
126 29 : case 1:
127 29 : return true;
128 3 : default:
129 : /* otherwise, error out below */
130 3 : break;
131 : }
6125 bruce 132 3 : break;
133 7776 : default:
134 : {
5118 tgl 135 7776 : 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 : */
6124 141 7776 : if (pg_strcasecmp(sval, "true") == 0)
142 967 : return true;
143 6809 : if (pg_strcasecmp(sval, "false") == 0)
144 850 : return false;
5005 145 5959 : if (pg_strcasecmp(sval, "on") == 0)
146 59 : return true;
147 5900 : if (pg_strcasecmp(sval, "off") == 0)
148 5891 : return false;
149 : }
6125 bruce 150 9 : break;
151 : }
6904 tgl 152 12 : 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
3431 163 775 : defGetInt32(DefElem *def)
164 : {
165 775 : if (def->arg == NULL)
3431 tgl 166 UBC 0 : ereport(ERROR,
167 : (errcode(ERRCODE_SYNTAX_ERROR),
168 : errmsg("%s requires an integer value",
169 : def->defname)));
3431 tgl 170 CBC 775 : switch (nodeTag(def->arg))
171 : {
172 775 : case T_Integer:
173 775 : return (int32) intVal(def->arg);
3431 tgl 174 UBC 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
7627 tgl 187 CBC 327 : defGetInt64(DefElem *def)
188 : {
189 327 : if (def->arg == NULL)
7203 tgl 190 UBC 0 : ereport(ERROR,
191 : (errcode(ERRCODE_SYNTAX_ERROR),
192 : errmsg("%s requires a numeric value",
193 : def->defname)));
7627 tgl 194 CBC 327 : switch (nodeTag(def->arg))
195 : {
196 311 : case T_Integer:
197 311 : return (int64) intVal(def->arg);
198 16 : 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 16 : return DatumGetInt64(DirectFunctionCall1(int8in,
206 : CStringGetDatum(castNode(Float, def->arg)->fval)));
7627 tgl 207 UBC 0 : default:
7203 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
156 tgl 220 CBC 615 : defGetObjectId(DefElem *def)
221 : {
222 615 : if (def->arg == NULL)
156 tgl 223 UBC 0 : ereport(ERROR,
224 : (errcode(ERRCODE_SYNTAX_ERROR),
225 : errmsg("%s requires a numeric value",
226 : def->defname)));
156 tgl 227 CBC 615 : switch (nodeTag(def->arg))
228 : {
229 615 : case T_Integer:
230 615 : return (Oid) intVal(def->arg);
156 tgl 231 UBC 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 *
7670 tgl 253 CBC 22369 : defGetQualifiedName(DefElem *def)
254 : {
255 22369 : if (def->arg == NULL)
7203 tgl 256 UBC 0 : ereport(ERROR,
257 : (errcode(ERRCODE_SYNTAX_ERROR),
258 : errmsg("%s requires a parameter",
259 : def->defname)));
7670 tgl 260 CBC 22369 : switch (nodeTag(def->arg))
261 : {
262 12522 : case T_TypeName:
263 22369 : return ((TypeName *) def->arg)->names;
7547 264 1131 : case T_List:
265 1131 : return (List *) def->arg;
7670 266 8716 : case T_String:
267 : /* Allow quoted name for backwards compatibility */
6892 neilc 268 8716 : return list_make1(def->arg);
7670 tgl 269 UBC 0 : default:
7203 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 *
7681 tgl 285 CBC 2762 : defGetTypeName(DefElem *def)
286 : {
287 2762 : if (def->arg == NULL)
7203 tgl 288 UBC 0 : ereport(ERROR,
289 : (errcode(ERRCODE_SYNTAX_ERROR),
290 : errmsg("%s requires a parameter",
291 : def->defname)));
7681 tgl 292 CBC 2762 : switch (nodeTag(def->arg))
293 : {
294 2759 : case T_TypeName:
295 2762 : return (TypeName *) def->arg;
296 3 : case T_String:
297 : /* Allow quoted typename for backwards compatibility */
6235 298 3 : return makeTypeNameFromNameList(list_make1(def->arg));
7681 tgl 299 UBC 0 : default:
7203 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
9344 bruce 313 CBC 64 : defGetTypeLength(DefElem *def)
314 : {
8219 tgl 315 64 : if (def->arg == NULL)
7203 tgl 316 UBC 0 : ereport(ERROR,
317 : (errcode(ERRCODE_SYNTAX_ERROR),
318 : errmsg("%s requires a parameter",
319 : def->defname)));
8219 tgl 320 CBC 64 : switch (nodeTag(def->arg))
321 : {
322 49 : case T_Integer:
323 49 : return intVal(def->arg);
8219 tgl 324 UBC 0 : case T_Float:
7203 325 0 : ereport(ERROR,
326 : (errcode(ERRCODE_SYNTAX_ERROR),
327 : errmsg("%s requires an integer value",
328 : def->defname)));
329 : break;
8219 330 0 : case T_String:
6911 331 0 : if (pg_strcasecmp(strVal(def->arg), "variable") == 0)
8219 332 0 : return -1; /* variable length */
333 0 : break;
8219 tgl 334 CBC 15 : case T_TypeName:
335 : /* cope if grammar chooses to believe "variable" is a typename */
6911 336 15 : if (pg_strcasecmp(TypeNameToString((TypeName *) def->arg),
337 : "variable") == 0)
8219 338 15 : return -1; /* variable length */
8219 tgl 339 UBC 0 : break;
7547 340 0 : case T_List:
341 : /* must be an operator name */
342 0 : break;
8219 343 0 : default:
7203 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 *
2271 peter_e 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 :
2153 bruce 369 0 : foreach(cell, (List *) def->arg)
370 : {
2271 peter_e 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
633 dean.a.rasheed 385 CBC 63 : errorConflictingDefElem(DefElem *defel, ParseState *pstate)
386 : {
387 63 : ereport(ERROR,
388 : errcode(ERRCODE_SYNTAX_ERROR),
389 : errmsg("conflicting or redundant options"),
390 : parser_errposition(pstate, defel->location));
391 : }
|