YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/postgres/src/backend/commands/define.c
Line
Count
Source (jump to first uncovered line)
1
/*-------------------------------------------------------------------------
2
 *
3
 * define.c
4
 *    Support routines for various kinds of object creation.
5
 *
6
 *
7
 * Portions Copyright (c) 1996-2018, 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 *
49
defGetString(DefElem *def)
50
6.10k
{
51
6.10k
  if (def->arg == NULL)
52
6.10k
    ereport(ERROR,
53
6.10k
        (errcode(ERRCODE_SYNTAX_ERROR),
54
6.10k
         errmsg("%s requires a parameter",
55
6.10k
            def->defname)));
56
6.10k
  switch (nodeTag(def->arg))
57
6.10k
  {
58
14
    case T_Integer:
59
14
      return psprintf("%ld", (long) intVal(def->arg));
60
0
    case T_Float:
61
62
      /*
63
       * T_Float values are kept in string form, so this type cheat
64
       * works (and doesn't risk losing precision)
65
       */
66
0
      return strVal(def->arg);
67
6.07k
    case T_String:
68
6.07k
      return strVal(def->arg);
69
16
    case T_TypeName:
70
16
      return TypeNameToString((TypeName *) def->arg);
71
0
    case T_List:
72
0
      return NameListToString((List *) def->arg);
73
0
    case T_A_Star:
74
0
      return pstrdup("*");
75
0
    default:
76
0
      elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
77
6.10k
  }
78
0
  return NULL;       /* keep compiler quiet */
79
6.10k
}
80
81
/*
82
 * Extract a numeric value (actually double) from a DefElem.
83
 */
84
double
85
defGetNumeric(DefElem *def)
86
1
{
87
1
  if (def->arg == NULL)
88
1
    ereport(ERROR,
89
1
        (errcode(ERRCODE_SYNTAX_ERROR),
90
1
         errmsg("%s requires a numeric value",
91
1
            def->defname)));
92
1
  switch (nodeTag(def->arg))
93
1
  {
94
0
    case T_Integer:
95
0
      return (double) intVal(def->arg);
96
1
    case T_Float:
97
1
      return floatVal(def->arg);
98
0
    default:
99
0
      ereport(ERROR,
100
1
          (errcode(ERRCODE_SYNTAX_ERROR),
101
1
           errmsg("%s requires a numeric value",
102
1
              def->defname)));
103
1
  }
104
0
  return 0;         /* keep compiler quiet */
105
1
}
106
107
/*
108
 * Extract a boolean value from a DefElem.
109
 */
110
bool
111
defGetBoolean(DefElem *def)
112
880
{
113
  /*
114
   * If no parameter given, assume "true" is meant.
115
   */
116
880
  if (def->arg == NULL)
117
195
    return true;
118
119
  /*
120
   * Allow 0, 1, "true", "false", "on", "off"
121
   */
122
685
  switch (nodeTag(def->arg))
123
685
  {
124
3
    case T_Integer:
125
3
      switch (intVal(def->arg))
126
3
      {
127
0
        case 0:
128
0
          return false;
129
3
        case 1:
130
3
          return true;
131
0
        default:
132
          /* otherwise, error out below */
133
0
          break;
134
0
      }
135
0
      break;
136
682
    default:
137
682
      {
138
682
        char     *sval = defGetString(def);
139
140
        /*
141
         * The set of strings accepted here should match up with the
142
         * grammar's opt_boolean production.
143
         */
144
682
        if (pg_strcasecmp(sval, "true") == 0)
145
417
          return true;
146
265
        if (pg_strcasecmp(sval, "false") == 0)
147
24
          return false;
148
241
        if (pg_strcasecmp(sval, "on") == 0)
149
0
          return true;
150
241
        if (pg_strcasecmp(sval, "off") == 0)
151
241
          return false;
152
0
      }
153
0
      break;
154
0
  }
155
0
  ereport(ERROR,
156
0
      (errcode(ERRCODE_SYNTAX_ERROR),
157
0
       errmsg("%s requires a Boolean value",
158
0
          def->defname)));
159
0
  return false;       /* keep compiler quiet */
160
0
}
161
162
/*
163
 * Extract an int32 value from a DefElem.
164
 */
165
int32
166
defGetInt32(DefElem *def)
167
32
{
168
32
  if (def->arg == NULL)
169
32
    ereport(ERROR,
170
32
        (errcode(ERRCODE_SYNTAX_ERROR),
171
32
         errmsg("%s requires an integer value",
172
32
            def->defname)));
173
32
  switch (nodeTag(def->arg))
174
32
  {
175
32
    case T_Integer:
176
32
      return (int32) intVal(def->arg);
177
0
    default:
178
0
      ereport(ERROR,
179
32
          (errcode(ERRCODE_SYNTAX_ERROR),
180
32
           errmsg("%s requires an integer value",
181
32
              def->defname)));
182
32
  }
183
0
  return 0;         /* keep compiler quiet */
184
32
}
185
186
/*
187
 * Extract an int64 value from a DefElem.
188
 */
189
int64
190
defGetInt64(DefElem *def)
191
4
{
192
4
  if (def->arg == NULL)
193
4
    ereport(ERROR,
194
4
        (errcode(ERRCODE_SYNTAX_ERROR),
195
4
         errmsg("%s requires a numeric value",
196
4
            def->defname)));
197
4
  switch (nodeTag(def->arg))
198
4
  {
199
4
    case T_Integer:
200
4
      return (int64) intVal(def->arg);
201
0
    case T_Float:
202
203
      /*
204
       * Values too large for int4 will be represented as Float
205
       * constants by the lexer.  Accept these if they are valid int8
206
       * strings.
207
       */
208
0
      return DatumGetInt64(DirectFunctionCall1(int8in,
209
0
                           CStringGetDatum(strVal(def->arg))));
210
0
    default:
211
0
      ereport(ERROR,
212
4
          (errcode(ERRCODE_SYNTAX_ERROR),
213
4
           errmsg("%s requires a numeric value",
214
4
              def->defname)));
215
4
  }
216
0
  return 0;         /* keep compiler quiet */
217
4
}
218
219
/*
220
 * Extract a possibly-qualified name (as a List of Strings) from a DefElem.
221
 */
222
List *
223
defGetQualifiedName(DefElem *def)
224
1.45k
{
225
1.45k
  if (def->arg == NULL)
226
1.45k
    ereport(ERROR,
227
1.45k
        (errcode(ERRCODE_SYNTAX_ERROR),
228
1.45k
         errmsg("%s requires a parameter",
229
1.45k
            def->defname)));
230
1.45k
  switch (nodeTag(def->arg))
231
1.45k
  {
232
981
    case T_TypeName:
233
981
      return ((TypeName *) def->arg)->names;
234
395
    case T_List:
235
395
      return (List *) def->arg;
236
81
    case T_String:
237
      /* Allow quoted name for backwards compatibility */
238
81
      return list_make1(def->arg);
239
0
    default:
240
0
      ereport(ERROR,
241
1.45k
          (errcode(ERRCODE_SYNTAX_ERROR),
242
1.45k
           errmsg("argument of %s must be a name",
243
1.45k
              def->defname)));
244
1.45k
  }
245
0
  return NIL;         /* keep compiler quiet */
246
1.45k
}
247
248
/*
249
 * Extract a TypeName from a DefElem.
250
 *
251
 * Note: we do not accept a List arg here, because the parser will only
252
 * return a bare List when the name looks like an operator name.
253
 */
254
TypeName *
255
defGetTypeName(DefElem *def)
256
632
{
257
632
  if (def->arg == NULL)
258
632
    ereport(ERROR,
259
632
        (errcode(ERRCODE_SYNTAX_ERROR),
260
632
         errmsg("%s requires a parameter",
261
632
            def->defname)));
262
632
  switch (nodeTag(def->arg))
263
632
  {
264
631
    case T_TypeName:
265
631
      return (TypeName *) def->arg;
266
1
    case T_String:
267
      /* Allow quoted typename for backwards compatibility */
268
1
      return makeTypeNameFromNameList(list_make1(def->arg));
269
0
    default:
270
0
      ereport(ERROR,
271
632
          (errcode(ERRCODE_SYNTAX_ERROR),
272
632
           errmsg("argument of %s must be a type name",
273
632
              def->defname)));
274
632
  }
275
0
  return NULL;       /* keep compiler quiet */
276
632
}
277
278
/*
279
 * Extract a type length indicator (either absolute bytes, or
280
 * -1 for "variable") from a DefElem.
281
 */
282
int
283
defGetTypeLength(DefElem *def)
284
18
{
285
18
  if (def->arg == NULL)
286
18
    ereport(ERROR,
287
18
        (errcode(ERRCODE_SYNTAX_ERROR),
288
18
         errmsg("%s requires a parameter",
289
18
            def->defname)));
290
18
  switch (nodeTag(def->arg))
291
18
  {
292
13
    case T_Integer:
293
13
      return intVal(def->arg);
294
0
    case T_Float:
295
0
      ereport(ERROR,
296
0
          (errcode(ERRCODE_SYNTAX_ERROR),
297
0
           errmsg("%s requires an integer value",
298
0
              def->defname)));
299
0
      break;
300
0
    case T_String:
301
0
      if (pg_strcasecmp(strVal(def->arg), "variable") == 0)
302
0
        return -1;   /* variable length */
303
0
      break;
304
5
    case T_TypeName:
305
      /* cope if grammar chooses to believe "variable" is a typename */
306
5
      if (pg_strcasecmp(TypeNameToString((TypeName *) def->arg),
307
5
                "variable") == 0)
308
5
        return -1;   /* variable length */
309
0
      break;
310
0
    case T_List:
311
      /* must be an operator name */
312
0
      break;
313
0
    default:
314
0
      elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
315
18
  }
316
0
  ereport(ERROR,
317
0
      (errcode(ERRCODE_SYNTAX_ERROR),
318
0
       errmsg("invalid argument for %s: \"%s\"",
319
0
          def->defname, defGetString(def))));
320
0
  return 0;         /* keep compiler quiet */
321
0
}
322
323
/*
324
 * Extract a list of string values (otherwise uninterpreted) from a DefElem.
325
 */
326
List *
327
defGetStringList(DefElem *def)
328
0
{
329
0
  ListCell   *cell;
330
331
0
  if (def->arg == NULL)
332
0
    ereport(ERROR,
333
0
        (errcode(ERRCODE_SYNTAX_ERROR),
334
0
         errmsg("%s requires a parameter",
335
0
            def->defname)));
336
0
  if (nodeTag(def->arg) != T_List)
337
0
    elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
338
339
0
  foreach(cell, (List *) def->arg)
340
0
  {
341
0
    Node     *str = (Node *) lfirst(cell);
342
343
0
    if (!IsA(str, String))
344
0
      elog(ERROR, "unexpected node type in name list: %d",
345
0
         (int) nodeTag(str));
346
0
  }
347
348
0
  return (List *) def->arg;
349
0
}