PostgreSQL Source Code  git master
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-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 *
49 {
50  if (def->arg == NULL)
51  ereport(ERROR,
52  (errcode(ERRCODE_SYNTAX_ERROR),
53  errmsg("%s requires a parameter",
54  def->defname)));
55  switch (nodeTag(def->arg))
56  {
57  case T_Integer:
58  return psprintf("%ld", (long) intVal(def->arg));
59  case T_Float:
60  return castNode(Float, def->arg)->fval;
61  case T_Boolean:
62  return boolVal(def->arg) ? "true" : "false";
63  case T_String:
64  return strVal(def->arg);
65  case T_TypeName:
66  return TypeNameToString((TypeName *) def->arg);
67  case T_List:
68  return NameListToString((List *) def->arg);
69  case T_A_Star:
70  return pstrdup("*");
71  default:
72  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
82 {
83  if (def->arg == NULL)
84  ereport(ERROR,
85  (errcode(ERRCODE_SYNTAX_ERROR),
86  errmsg("%s requires a numeric value",
87  def->defname)));
88  switch (nodeTag(def->arg))
89  {
90  case T_Integer:
91  return (double) intVal(def->arg);
92  case T_Float:
93  return floatVal(def->arg);
94  default:
95  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
108 {
109  /*
110  * If no parameter value given, assume "true" is meant.
111  */
112  if (def->arg == NULL)
113  return true;
114 
115  /*
116  * Allow 0, 1, "true", "false", "on", "off"
117  */
118  switch (nodeTag(def->arg))
119  {
120  case T_Integer:
121  switch (intVal(def->arg))
122  {
123  case 0:
124  return false;
125  case 1:
126  return true;
127  default:
128  /* otherwise, error out below */
129  break;
130  }
131  break;
132  default:
133  {
134  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  if (pg_strcasecmp(sval, "true") == 0)
141  return true;
142  if (pg_strcasecmp(sval, "false") == 0)
143  return false;
144  if (pg_strcasecmp(sval, "on") == 0)
145  return true;
146  if (pg_strcasecmp(sval, "off") == 0)
147  return false;
148  }
149  break;
150  }
151  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
163 {
164  if (def->arg == NULL)
165  ereport(ERROR,
166  (errcode(ERRCODE_SYNTAX_ERROR),
167  errmsg("%s requires an integer value",
168  def->defname)));
169  switch (nodeTag(def->arg))
170  {
171  case T_Integer:
172  return (int32) intVal(def->arg);
173  default:
174  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
187 {
188  if (def->arg == NULL)
189  ereport(ERROR,
190  (errcode(ERRCODE_SYNTAX_ERROR),
191  errmsg("%s requires a numeric value",
192  def->defname)));
193  switch (nodeTag(def->arg))
194  {
195  case T_Integer:
196  return (int64) intVal(def->arg);
197  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  */
205  CStringGetDatum(castNode(Float, def->arg)->fval)));
206  default:
207  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
220 {
221  if (def->arg == NULL)
222  ereport(ERROR,
223  (errcode(ERRCODE_SYNTAX_ERROR),
224  errmsg("%s requires a numeric value",
225  def->defname)));
226  switch (nodeTag(def->arg))
227  {
228  case T_Integer:
229  return (Oid) intVal(def->arg);
230  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  */
238  CStringGetDatum(castNode(Float, def->arg)->fval)));
239  default:
240  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 *
253 {
254  if (def->arg == NULL)
255  ereport(ERROR,
256  (errcode(ERRCODE_SYNTAX_ERROR),
257  errmsg("%s requires a parameter",
258  def->defname)));
259  switch (nodeTag(def->arg))
260  {
261  case T_TypeName:
262  return ((TypeName *) def->arg)->names;
263  case T_List:
264  return (List *) def->arg;
265  case T_String:
266  /* Allow quoted name for backwards compatibility */
267  return list_make1(def->arg);
268  default:
269  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 *
285 {
286  if (def->arg == NULL)
287  ereport(ERROR,
288  (errcode(ERRCODE_SYNTAX_ERROR),
289  errmsg("%s requires a parameter",
290  def->defname)));
291  switch (nodeTag(def->arg))
292  {
293  case T_TypeName:
294  return (TypeName *) def->arg;
295  case T_String:
296  /* Allow quoted typename for backwards compatibility */
298  default:
299  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
313 {
314  if (def->arg == NULL)
315  ereport(ERROR,
316  (errcode(ERRCODE_SYNTAX_ERROR),
317  errmsg("%s requires a parameter",
318  def->defname)));
319  switch (nodeTag(def->arg))
320  {
321  case T_Integer:
322  return intVal(def->arg);
323  case T_Float:
324  ereport(ERROR,
325  (errcode(ERRCODE_SYNTAX_ERROR),
326  errmsg("%s requires an integer value",
327  def->defname)));
328  break;
329  case T_String:
330  if (pg_strcasecmp(strVal(def->arg), "variable") == 0)
331  return -1; /* variable length */
332  break;
333  case T_TypeName:
334  /* cope if grammar chooses to believe "variable" is a typename */
336  "variable") == 0)
337  return -1; /* variable length */
338  break;
339  case T_List:
340  /* must be an operator name */
341  break;
342  default:
343  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
344  }
345  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 *
357 {
358  ListCell *cell;
359 
360  if (def->arg == NULL)
361  ereport(ERROR,
362  (errcode(ERRCODE_SYNTAX_ERROR),
363  errmsg("%s requires a parameter",
364  def->defname)));
365  if (nodeTag(def->arg) != T_List)
366  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
367 
368  foreach(cell, (List *) def->arg)
369  {
370  Node *str = (Node *) lfirst(cell);
371 
372  if (!IsA(str, String))
373  elog(ERROR, "unexpected node type in name list: %d",
374  (int) nodeTag(str));
375  }
376 
377  return (List *) def->arg;
378 }
379 
380 /*
381  * Raise an error about a conflicting DefElem.
382  */
383 void
385 {
386  ereport(ERROR,
387  errcode(ERRCODE_SYNTAX_ERROR),
388  errmsg("conflicting or redundant options"),
389  parser_errposition(pstate, defel->location));
390 }
signed int int32
Definition: c.h:494
int32 defGetInt32(DefElem *def)
Definition: define.c:162
int defGetTypeLength(DefElem *def)
Definition: define.c:312
bool defGetBoolean(DefElem *def)
Definition: define.c:107
List * defGetQualifiedName(DefElem *def)
Definition: define.c:252
char * defGetString(DefElem *def)
Definition: define.c:48
int64 defGetInt64(DefElem *def)
Definition: define.c:186
void errorConflictingDefElem(DefElem *defel, ParseState *pstate)
Definition: define.c:384
Oid defGetObjectId(DefElem *def)
Definition: define.c:219
double defGetNumeric(DefElem *def)
Definition: define.c:81
TypeName * defGetTypeName(DefElem *def)
Definition: define.c:284
List * defGetStringList(DefElem *def)
Definition: define.c:356
int errcode(int sqlerrcode)
Definition: elog.c:857
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
#define ereport(elevel,...)
Definition: elog.h:149
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:642
const char * str
Datum int8in(PG_FUNCTION_ARGS)
Definition: int8.c:50
TypeName * makeTypeNameFromNameList(List *names)
Definition: makefuncs.c:458
char * pstrdup(const char *in)
Definition: mcxt.c:1695
char * NameListToString(const List *names)
Definition: namespace.c:3579
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
#define nodeTag(nodeptr)
Definition: nodes.h:133
#define castNode(_type_, nodeptr)
Definition: nodes.h:176
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)
Definition: pgstrcasecmp.c:36
static int64 DatumGetInt64(Datum X)
Definition: postgres.h:385
static Oid DatumGetObjectId(Datum X)
Definition: postgres.h:242
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350
unsigned int Oid
Definition: postgres_ext.h:31
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
char * defname
Definition: parsenodes.h:815
ParseLoc location
Definition: parsenodes.h:819
Node * arg
Definition: parsenodes.h:816
Definition: value.h:48
Definition: pg_list.h:54
Definition: nodes.h:129
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