PostgreSQL Source Code git master
Loading...
Searching...
No Matches
define.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * define.c
4 * Support routines for various kinds of object creation.
5 *
6 *
7 * Portions Copyright (c) 1996-2026, 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 * Support routines for dealing with DefElem nodes.
16 *
17 *
18 *-------------------------------------------------------------------------
19 */
20#include "postgres.h"
21
22#include <ctype.h>
23
24#include "catalog/namespace.h"
25#include "commands/defrem.h"
26#include "nodes/makefuncs.h"
27#include "parser/parse_type.h"
28#include "utils/fmgrprotos.h"
29
30/*
31 * Extract a string value (otherwise uninterpreted) from a DefElem.
32 */
33char *
35{
36 if (def->arg == NULL)
39 errmsg("%s requires a parameter",
40 def->defname)));
41 switch (nodeTag(def->arg))
42 {
43 case T_Integer:
44 return psprintf("%d", intVal(def->arg));
45 case T_Float:
46 return castNode(Float, def->arg)->fval;
47 case T_Boolean:
48 return boolVal(def->arg) ? "true" : "false";
49 case T_String:
50 return strVal(def->arg);
51 case T_TypeName:
52 return TypeNameToString((TypeName *) def->arg);
53 case T_List:
54 return NameListToString((List *) def->arg);
55 case T_A_Star:
56 return pstrdup("*");
57 default:
58 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
59 }
60 return NULL; /* keep compiler quiet */
61}
62
63/*
64 * Extract a numeric value (actually double) from a DefElem.
65 */
66double
68{
69 if (def->arg == NULL)
72 errmsg("%s requires a numeric value",
73 def->defname)));
74 switch (nodeTag(def->arg))
75 {
76 case T_Integer:
77 return (double) intVal(def->arg);
78 case T_Float:
79 return floatVal(def->arg);
80 default:
83 errmsg("%s requires a numeric value",
84 def->defname)));
85 }
86 return 0; /* keep compiler quiet */
87}
88
89/*
90 * Extract a boolean value from a DefElem.
91 */
92bool
94{
95 /*
96 * If no parameter value given, assume "true" is meant.
97 */
98 if (def->arg == NULL)
99 return true;
100
101 /*
102 * Allow 0, 1, "true", "false", "on", "off"
103 */
104 switch (nodeTag(def->arg))
105 {
106 case T_Integer:
107 switch (intVal(def->arg))
108 {
109 case 0:
110 return false;
111 case 1:
112 return true;
113 default:
114 /* otherwise, error out below */
115 break;
116 }
117 break;
118 default:
119 {
120 char *sval = defGetString(def);
121
122 /*
123 * The set of strings accepted here should match up with the
124 * grammar's opt_boolean_or_string production.
125 */
126 if (pg_strcasecmp(sval, "true") == 0)
127 return true;
128 if (pg_strcasecmp(sval, "false") == 0)
129 return false;
130 if (pg_strcasecmp(sval, "on") == 0)
131 return true;
132 if (pg_strcasecmp(sval, "off") == 0)
133 return false;
134 }
135 break;
136 }
139 errmsg("%s requires a Boolean value",
140 def->defname)));
141 return false; /* keep compiler quiet */
142}
143
144/*
145 * Extract an int32 value from a DefElem.
146 */
147int32
149{
150 if (def->arg == NULL)
153 errmsg("%s requires an integer value",
154 def->defname)));
155 switch (nodeTag(def->arg))
156 {
157 case T_Integer:
158 return (int32) intVal(def->arg);
159 default:
162 errmsg("%s requires an integer value",
163 def->defname)));
164 }
165 return 0; /* keep compiler quiet */
166}
167
168/*
169 * Extract an int64 value from a DefElem.
170 */
171int64
173{
174 if (def->arg == NULL)
177 errmsg("%s requires a numeric value",
178 def->defname)));
179 switch (nodeTag(def->arg))
180 {
181 case T_Integer:
182 return (int64) intVal(def->arg);
183 case T_Float:
184
185 /*
186 * Values too large for int4 will be represented as Float
187 * constants by the lexer. Accept these if they are valid int8
188 * strings.
189 */
191 CStringGetDatum(castNode(Float, def->arg)->fval)));
192 default:
195 errmsg("%s requires a numeric value",
196 def->defname)));
197 }
198 return 0; /* keep compiler quiet */
199}
200
201/*
202 * Extract an OID value from a DefElem.
203 */
204Oid
206{
207 if (def->arg == NULL)
210 errmsg("%s requires a numeric value",
211 def->defname)));
212 switch (nodeTag(def->arg))
213 {
214 case T_Integer:
215 return (Oid) intVal(def->arg);
216 case T_Float:
217
218 /*
219 * Values too large for int4 will be represented as Float
220 * constants by the lexer. Accept these if they are valid OID
221 * strings.
222 */
224 CStringGetDatum(castNode(Float, def->arg)->fval)));
225 default:
228 errmsg("%s requires a numeric value",
229 def->defname)));
230 }
231 return 0; /* keep compiler quiet */
232}
233
234/*
235 * Extract a possibly-qualified name (as a List of Strings) from a DefElem.
236 */
237List *
239{
240 if (def->arg == NULL)
243 errmsg("%s requires a parameter",
244 def->defname)));
245 switch (nodeTag(def->arg))
246 {
247 case T_TypeName:
248 return ((TypeName *) def->arg)->names;
249 case T_List:
250 return (List *) def->arg;
251 case T_String:
252 /* Allow quoted name for backwards compatibility */
253 return list_make1(def->arg);
254 default:
257 errmsg("argument of %s must be a name",
258 def->defname)));
259 }
260 return NIL; /* keep compiler quiet */
261}
262
263/*
264 * Extract a TypeName from a DefElem.
265 *
266 * Note: we do not accept a List arg here, because the parser will only
267 * return a bare List when the name looks like an operator name.
268 */
269TypeName *
271{
272 if (def->arg == NULL)
275 errmsg("%s requires a parameter",
276 def->defname)));
277 switch (nodeTag(def->arg))
278 {
279 case T_TypeName:
280 return (TypeName *) def->arg;
281 case T_String:
282 /* Allow quoted typename for backwards compatibility */
284 default:
287 errmsg("argument of %s must be a type name",
288 def->defname)));
289 }
290 return NULL; /* keep compiler quiet */
291}
292
293/*
294 * Extract a type length indicator (either absolute bytes, or
295 * -1 for "variable") from a DefElem.
296 */
297int
299{
300 if (def->arg == NULL)
303 errmsg("%s requires a parameter",
304 def->defname)));
305 switch (nodeTag(def->arg))
306 {
307 case T_Integer:
308 return intVal(def->arg);
309 case T_Float:
312 errmsg("%s requires an integer value",
313 def->defname)));
314 break;
315 case T_String:
316 if (pg_strcasecmp(strVal(def->arg), "variable") == 0)
317 return -1; /* variable length */
318 break;
319 case T_TypeName:
320 /* cope if grammar chooses to believe "variable" is a typename */
322 "variable") == 0)
323 return -1; /* variable length */
324 break;
325 case T_List:
326 /* must be an operator name */
327 break;
328 default:
329 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
330 }
333 errmsg("invalid argument for %s: \"%s\"",
334 def->defname, defGetString(def))));
335 return 0; /* keep compiler quiet */
336}
337
338/*
339 * Extract a list of string values (otherwise uninterpreted) from a DefElem.
340 */
341List *
343{
344 ListCell *cell;
345
346 if (def->arg == NULL)
349 errmsg("%s requires a parameter",
350 def->defname)));
351 if (!IsA(def->arg, List))
352 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
353
354 foreach(cell, (List *) def->arg)
355 {
356 Node *str = (Node *) lfirst(cell);
357
358 if (!IsA(str, String))
359 elog(ERROR, "unexpected node type in name list: %d",
360 (int) nodeTag(str));
361 }
362
363 return (List *) def->arg;
364}
365
366/*
367 * Raise an error about a conflicting DefElem.
368 */
369void
371{
374 errmsg("conflicting or redundant options"),
375 parser_errposition(pstate, defel->location));
376}
int64_t int64
Definition c.h:543
int32_t int32
Definition c.h:542
TypeName * defGetTypeName(DefElem *def)
Definition define.c:270
int32 defGetInt32(DefElem *def)
Definition define.c:148
int defGetTypeLength(DefElem *def)
Definition define.c:298
char * defGetString(DefElem *def)
Definition define.c:34
bool defGetBoolean(DefElem *def)
Definition define.c:93
List * defGetQualifiedName(DefElem *def)
Definition define.c:238
int64 defGetInt64(DefElem *def)
Definition define.c:172
void errorConflictingDefElem(DefElem *defel, ParseState *pstate)
Definition define.c:370
Oid defGetObjectId(DefElem *def)
Definition define.c:205
double defGetNumeric(DefElem *def)
Definition define.c:67
List * defGetStringList(DefElem *def)
Definition define.c:342
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define ereport(elevel,...)
Definition elog.h:150
#define DirectFunctionCall1(func, arg1)
Definition fmgr.h:684
const char * str
Datum int8in(PG_FUNCTION_ARGS)
Definition int8.c:50
TypeName * makeTypeNameFromNameList(List *names)
Definition makefuncs.c:531
char * pstrdup(const char *in)
Definition mcxt.c:1781
char * NameListToString(const List *names)
Definition namespace.c:3664
#define IsA(nodeptr, _type_)
Definition nodes.h:164
#define nodeTag(nodeptr)
Definition nodes.h:139
#define castNode(_type_, nodeptr)
Definition nodes.h:182
Datum oidin(PG_FUNCTION_ARGS)
Definition oid.c:37
int parser_errposition(ParseState *pstate, int location)
Definition parse_node.c:106
char * TypeNameToString(const TypeName *typeName)
Definition parse_type.c:478
#define lfirst(lc)
Definition pg_list.h:172
#define NIL
Definition pg_list.h:68
#define list_make1(x1)
Definition pg_list.h:212
int pg_strcasecmp(const char *s1, const char *s2)
static int64 DatumGetInt64(Datum X)
Definition postgres.h:413
static Oid DatumGetObjectId(Datum X)
Definition postgres.h:252
static Datum CStringGetDatum(const char *X)
Definition postgres.h:380
unsigned int Oid
static int fb(int x)
char * psprintf(const char *fmt,...)
Definition psprintf.c:43
char * defname
Definition parsenodes.h:844
Node * arg
Definition parsenodes.h:845
Definition value.h:48
Definition pg_list.h:54
Definition nodes.h:135
Definition value.h:64
#define boolVal(v)
Definition value.h:81
#define intVal(v)
Definition value.h:79
#define strVal(v)
Definition value.h:82
#define floatVal(v)
Definition value.h:80