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-2021, 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)->val;
62  case T_String:
63  return strVal(def->arg);
64  case T_TypeName:
65  return TypeNameToString((TypeName *) def->arg);
66  case T_List:
67  return NameListToString((List *) def->arg);
68  case T_A_Star:
69  return pstrdup("*");
70  default:
71  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
72  }
73  return NULL; /* keep compiler quiet */
74 }
75 
76 /*
77  * Extract a numeric value (actually double) from a DefElem.
78  */
79 double
81 {
82  if (def->arg == NULL)
83  ereport(ERROR,
84  (errcode(ERRCODE_SYNTAX_ERROR),
85  errmsg("%s requires a numeric value",
86  def->defname)));
87  switch (nodeTag(def->arg))
88  {
89  case T_Integer:
90  return (double) intVal(def->arg);
91  case T_Float:
92  return floatVal(def->arg);
93  default:
94  ereport(ERROR,
95  (errcode(ERRCODE_SYNTAX_ERROR),
96  errmsg("%s requires a numeric value",
97  def->defname)));
98  }
99  return 0; /* keep compiler quiet */
100 }
101 
102 /*
103  * Extract a boolean value from a DefElem.
104  */
105 bool
107 {
108  /*
109  * If no parameter given, assume "true" is meant.
110  */
111  if (def->arg == NULL)
112  return true;
113 
114  /*
115  * Allow 0, 1, "true", "false", "on", "off"
116  */
117  switch (nodeTag(def->arg))
118  {
119  case T_Integer:
120  switch (intVal(def->arg))
121  {
122  case 0:
123  return false;
124  case 1:
125  return true;
126  default:
127  /* otherwise, error out below */
128  break;
129  }
130  break;
131  default:
132  {
133  char *sval = defGetString(def);
134 
135  /*
136  * The set of strings accepted here should match up with the
137  * grammar's opt_boolean_or_string production.
138  */
139  if (pg_strcasecmp(sval, "true") == 0)
140  return true;
141  if (pg_strcasecmp(sval, "false") == 0)
142  return false;
143  if (pg_strcasecmp(sval, "on") == 0)
144  return true;
145  if (pg_strcasecmp(sval, "off") == 0)
146  return false;
147  }
148  break;
149  }
150  ereport(ERROR,
151  (errcode(ERRCODE_SYNTAX_ERROR),
152  errmsg("%s requires a Boolean value",
153  def->defname)));
154  return false; /* keep compiler quiet */
155 }
156 
157 /*
158  * Extract an int32 value from a DefElem.
159  */
160 int32
162 {
163  if (def->arg == NULL)
164  ereport(ERROR,
165  (errcode(ERRCODE_SYNTAX_ERROR),
166  errmsg("%s requires an integer value",
167  def->defname)));
168  switch (nodeTag(def->arg))
169  {
170  case T_Integer:
171  return (int32) intVal(def->arg);
172  default:
173  ereport(ERROR,
174  (errcode(ERRCODE_SYNTAX_ERROR),
175  errmsg("%s requires an integer value",
176  def->defname)));
177  }
178  return 0; /* keep compiler quiet */
179 }
180 
181 /*
182  * Extract an int64 value from a DefElem.
183  */
184 int64
186 {
187  if (def->arg == NULL)
188  ereport(ERROR,
189  (errcode(ERRCODE_SYNTAX_ERROR),
190  errmsg("%s requires a numeric value",
191  def->defname)));
192  switch (nodeTag(def->arg))
193  {
194  case T_Integer:
195  return (int64) intVal(def->arg);
196  case T_Float:
197 
198  /*
199  * Values too large for int4 will be represented as Float
200  * constants by the lexer. Accept these if they are valid int8
201  * strings.
202  */
204  CStringGetDatum(castNode(Float, def->arg)->val)));
205  default:
206  ereport(ERROR,
207  (errcode(ERRCODE_SYNTAX_ERROR),
208  errmsg("%s requires a numeric value",
209  def->defname)));
210  }
211  return 0; /* keep compiler quiet */
212 }
213 
214 /*
215  * Extract a possibly-qualified name (as a List of Strings) from a DefElem.
216  */
217 List *
219 {
220  if (def->arg == NULL)
221  ereport(ERROR,
222  (errcode(ERRCODE_SYNTAX_ERROR),
223  errmsg("%s requires a parameter",
224  def->defname)));
225  switch (nodeTag(def->arg))
226  {
227  case T_TypeName:
228  return ((TypeName *) def->arg)->names;
229  case T_List:
230  return (List *) def->arg;
231  case T_String:
232  /* Allow quoted name for backwards compatibility */
233  return list_make1(def->arg);
234  default:
235  ereport(ERROR,
236  (errcode(ERRCODE_SYNTAX_ERROR),
237  errmsg("argument of %s must be a name",
238  def->defname)));
239  }
240  return NIL; /* keep compiler quiet */
241 }
242 
243 /*
244  * Extract a TypeName from a DefElem.
245  *
246  * Note: we do not accept a List arg here, because the parser will only
247  * return a bare List when the name looks like an operator name.
248  */
249 TypeName *
251 {
252  if (def->arg == NULL)
253  ereport(ERROR,
254  (errcode(ERRCODE_SYNTAX_ERROR),
255  errmsg("%s requires a parameter",
256  def->defname)));
257  switch (nodeTag(def->arg))
258  {
259  case T_TypeName:
260  return (TypeName *) def->arg;
261  case T_String:
262  /* Allow quoted typename for backwards compatibility */
264  default:
265  ereport(ERROR,
266  (errcode(ERRCODE_SYNTAX_ERROR),
267  errmsg("argument of %s must be a type name",
268  def->defname)));
269  }
270  return NULL; /* keep compiler quiet */
271 }
272 
273 /*
274  * Extract a type length indicator (either absolute bytes, or
275  * -1 for "variable") from a DefElem.
276  */
277 int
279 {
280  if (def->arg == NULL)
281  ereport(ERROR,
282  (errcode(ERRCODE_SYNTAX_ERROR),
283  errmsg("%s requires a parameter",
284  def->defname)));
285  switch (nodeTag(def->arg))
286  {
287  case T_Integer:
288  return intVal(def->arg);
289  case T_Float:
290  ereport(ERROR,
291  (errcode(ERRCODE_SYNTAX_ERROR),
292  errmsg("%s requires an integer value",
293  def->defname)));
294  break;
295  case T_String:
296  if (pg_strcasecmp(strVal(def->arg), "variable") == 0)
297  return -1; /* variable length */
298  break;
299  case T_TypeName:
300  /* cope if grammar chooses to believe "variable" is a typename */
302  "variable") == 0)
303  return -1; /* variable length */
304  break;
305  case T_List:
306  /* must be an operator name */
307  break;
308  default:
309  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
310  }
311  ereport(ERROR,
312  (errcode(ERRCODE_SYNTAX_ERROR),
313  errmsg("invalid argument for %s: \"%s\"",
314  def->defname, defGetString(def))));
315  return 0; /* keep compiler quiet */
316 }
317 
318 /*
319  * Extract a list of string values (otherwise uninterpreted) from a DefElem.
320  */
321 List *
323 {
324  ListCell *cell;
325 
326  if (def->arg == NULL)
327  ereport(ERROR,
328  (errcode(ERRCODE_SYNTAX_ERROR),
329  errmsg("%s requires a parameter",
330  def->defname)));
331  if (nodeTag(def->arg) != T_List)
332  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
333 
334  foreach(cell, (List *) def->arg)
335  {
336  Node *str = (Node *) lfirst(cell);
337 
338  if (!IsA(str, String))
339  elog(ERROR, "unexpected node type in name list: %d",
340  (int) nodeTag(str));
341  }
342 
343  return (List *) def->arg;
344 }
345 
346 /*
347  * Raise an error about a conflicting DefElem.
348  */
349 void
351 {
352  ereport(ERROR,
353  errcode(ERRCODE_SYNTAX_ERROR),
354  errmsg("conflicting or redundant options"),
355  parser_errposition(pstate, defel->location));
356 }
#define NIL
Definition: pg_list.h:65
#define IsA(nodeptr, _type_)
Definition: nodes.h:587
#define castNode(_type_, nodeptr)
Definition: nodes.h:605
char * TypeNameToString(const TypeName *typeName)
Definition: parse_type.c:480
char * pstrdup(const char *in)
Definition: mcxt.c:1299
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
double defGetNumeric(DefElem *def)
Definition: define.c:80
Definition: nodes.h:536
#define strVal(v)
Definition: value.h:65
int32 defGetInt32(DefElem *def)
Definition: define.c:161
int errcode(int sqlerrcode)
Definition: elog.c:698
Definition: value.h:51
int64 defGetInt64(DefElem *def)
Definition: define.c:185
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:626
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
List * defGetStringList(DefElem *def)
Definition: define.c:322
signed int int32
Definition: c.h:429
int defGetTypeLength(DefElem *def)
Definition: define.c:278
#define list_make1(x1)
Definition: pg_list.h:206
bool defGetBoolean(DefElem *def)
Definition: define.c:106
TypeName * defGetTypeName(DefElem *def)
Definition: define.c:250
#define ERROR
Definition: elog.h:46
char * defGetString(DefElem *def)
Definition: define.c:49
#define DatumGetInt64(X)
Definition: postgres.h:651
int location
Definition: parsenodes.h:761
#define CStringGetDatum(X)
Definition: postgres.h:622
#define floatVal(v)
Definition: value.h:64
Definition: nodes.h:301
Node * arg
Definition: parsenodes.h:759
Definition: value.h:45
char * NameListToString(List *names)
Definition: namespace.c:3147
#define ereport(elevel,...)
Definition: elog.h:157
void errorConflictingDefElem(DefElem *defel, ParseState *pstate)
Definition: define.c:350
#define lfirst(lc)
Definition: pg_list.h:169
List * defGetQualifiedName(DefElem *def)
Definition: define.c:218
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
Datum int8in(PG_FUNCTION_ARGS)
Definition: int8.c:134
#define nodeTag(nodeptr)
Definition: nodes.h:541
Definition: nodes.h:294
#define intVal(v)
Definition: value.h:63
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
TypeName * makeTypeNameFromNameList(List *names)
Definition: makefuncs.c:456
char * defname
Definition: parsenodes.h:758
Definition: pg_list.h:50