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