~vcs-imports/mammoth-replicator/trunk

« back to all changes in this revision

Viewing changes to src/backend/commands/define.c

  • Committer: alvherre
  • Date: 2005-12-16 21:24:52 UTC
  • Revision ID: svn-v4:db760fc0-0f08-0410-9d63-cc6633f64896:trunk:1
Initial import of the REL8_0_3 sources from the Pgsql CVS repository.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-------------------------------------------------------------------------
 
2
 *
 
3
 * define.c
 
4
 *        Support routines for various kinds of object creation.
 
5
 *
 
6
 *
 
7
 * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
 
8
 * Portions Copyright (c) 1994, Regents of the University of California
 
9
 *
 
10
 *
 
11
 * IDENTIFICATION
 
12
 *        $PostgreSQL: pgsql/src/backend/commands/define.c,v 1.92 2004-12-31 21:59:41 pgsql Exp $
 
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 "parser/parse_type.h"
 
41
#include "parser/scansup.h"
 
42
#include "utils/int8.h"
 
43
 
 
44
 
 
45
/*
 
46
 * Translate the input language name to lower case, and truncate if needed.
 
47
 *
 
48
 * Returns a palloc'd string
 
49
 */
 
50
char *
 
51
case_translate_language_name(const char *input)
 
52
{
 
53
        return downcase_truncate_identifier(input, strlen(input), false);
 
54
}
 
55
 
 
56
 
 
57
/*
 
58
 * Extract a string value (otherwise uninterpreted) from a DefElem.
 
59
 */
 
60
char *
 
61
defGetString(DefElem *def)
 
62
{
 
63
        if (def->arg == NULL)
 
64
                ereport(ERROR,
 
65
                                (errcode(ERRCODE_SYNTAX_ERROR),
 
66
                                 errmsg("%s requires a parameter",
 
67
                                                def->defname)));
 
68
        switch (nodeTag(def->arg))
 
69
        {
 
70
                case T_Integer:
 
71
                        {
 
72
                                char       *str = palloc(32);
 
73
 
 
74
                                snprintf(str, 32, "%ld", (long) intVal(def->arg));
 
75
                                return str;
 
76
                        }
 
77
                case T_Float:
 
78
 
 
79
                        /*
 
80
                         * T_Float values are kept in string form, so this type cheat
 
81
                         * works (and doesn't risk losing precision)
 
82
                         */
 
83
                        return strVal(def->arg);
 
84
                case T_String:
 
85
                        return strVal(def->arg);
 
86
                case T_TypeName:
 
87
                        return TypeNameToString((TypeName *) def->arg);
 
88
                case T_List:
 
89
                        return NameListToString((List *) def->arg);
 
90
                default:
 
91
                        elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
 
92
        }
 
93
        return NULL;                            /* keep compiler quiet */
 
94
}
 
95
 
 
96
/*
 
97
 * Extract a numeric value (actually double) from a DefElem.
 
98
 */
 
99
double
 
100
defGetNumeric(DefElem *def)
 
101
{
 
102
        if (def->arg == NULL)
 
103
                ereport(ERROR,
 
104
                                (errcode(ERRCODE_SYNTAX_ERROR),
 
105
                                 errmsg("%s requires a numeric value",
 
106
                                                def->defname)));
 
107
        switch (nodeTag(def->arg))
 
108
        {
 
109
                case T_Integer:
 
110
                        return (double) intVal(def->arg);
 
111
                case T_Float:
 
112
                        return floatVal(def->arg);
 
113
                default:
 
114
                        ereport(ERROR,
 
115
                                        (errcode(ERRCODE_SYNTAX_ERROR),
 
116
                                         errmsg("%s requires a numeric value",
 
117
                                                        def->defname)));
 
118
        }
 
119
        return 0;                                       /* keep compiler quiet */
 
120
}
 
121
 
 
122
/*
 
123
 * Extract a boolean value from a DefElem.
 
124
 */
 
125
bool
 
126
defGetBoolean(DefElem *def)
 
127
{
 
128
        /*
 
129
         * Presently, boolean flags must simply be present or absent. Later we
 
130
         * could allow 'flag = t', 'flag = f', etc.
 
131
         */
 
132
        if (def->arg == NULL)
 
133
                return true;
 
134
        ereport(ERROR,
 
135
                        (errcode(ERRCODE_SYNTAX_ERROR),
 
136
                         errmsg("%s does not take a parameter",
 
137
                                        def->defname)));
 
138
        return false;                           /* keep compiler quiet */
 
139
}
 
140
 
 
141
/*
 
142
 * Extract an int64 value from a DefElem.
 
143
 */
 
144
int64
 
145
defGetInt64(DefElem *def)
 
146
{
 
147
        if (def->arg == NULL)
 
148
                ereport(ERROR,
 
149
                                (errcode(ERRCODE_SYNTAX_ERROR),
 
150
                                 errmsg("%s requires a numeric value",
 
151
                                                def->defname)));
 
152
        switch (nodeTag(def->arg))
 
153
        {
 
154
                case T_Integer:
 
155
                        return (int64) intVal(def->arg);
 
156
                case T_Float:
 
157
 
 
158
                        /*
 
159
                         * Values too large for int4 will be represented as Float
 
160
                         * constants by the lexer.      Accept these if they are valid
 
161
                         * int8 strings.
 
162
                         */
 
163
                        return DatumGetInt64(DirectFunctionCall1(int8in,
 
164
                                                                         CStringGetDatum(strVal(def->arg))));
 
165
                default:
 
166
                        ereport(ERROR,
 
167
                                        (errcode(ERRCODE_SYNTAX_ERROR),
 
168
                                         errmsg("%s requires a numeric value",
 
169
                                                        def->defname)));
 
170
        }
 
171
        return 0;                                       /* keep compiler quiet */
 
172
}
 
173
 
 
174
/*
 
175
 * Extract a possibly-qualified name (as a List of Strings) from a DefElem.
 
176
 */
 
177
List *
 
178
defGetQualifiedName(DefElem *def)
 
179
{
 
180
        if (def->arg == NULL)
 
181
                ereport(ERROR,
 
182
                                (errcode(ERRCODE_SYNTAX_ERROR),
 
183
                                 errmsg("%s requires a parameter",
 
184
                                                def->defname)));
 
185
        switch (nodeTag(def->arg))
 
186
        {
 
187
                case T_TypeName:
 
188
                        return ((TypeName *) def->arg)->names;
 
189
                case T_List:
 
190
                        return (List *) def->arg;
 
191
                case T_String:
 
192
                        /* Allow quoted name for backwards compatibility */
 
193
                        return list_make1(def->arg);
 
194
                default:
 
195
                        ereport(ERROR,
 
196
                                        (errcode(ERRCODE_SYNTAX_ERROR),
 
197
                                         errmsg("argument of %s must be a name",
 
198
                                                        def->defname)));
 
199
        }
 
200
        return NIL;                                     /* keep compiler quiet */
 
201
}
 
202
 
 
203
/*
 
204
 * Extract a TypeName from a DefElem.
 
205
 *
 
206
 * Note: we do not accept a List arg here, because the parser will only
 
207
 * return a bare List when the name looks like an operator name.
 
208
 */
 
209
TypeName *
 
210
defGetTypeName(DefElem *def)
 
211
{
 
212
        if (def->arg == NULL)
 
213
                ereport(ERROR,
 
214
                                (errcode(ERRCODE_SYNTAX_ERROR),
 
215
                                 errmsg("%s requires a parameter",
 
216
                                                def->defname)));
 
217
        switch (nodeTag(def->arg))
 
218
        {
 
219
                case T_TypeName:
 
220
                        return (TypeName *) def->arg;
 
221
                case T_String:
 
222
                        {
 
223
                                /* Allow quoted typename for backwards compatibility */
 
224
                                TypeName   *n = makeNode(TypeName);
 
225
 
 
226
                                n->names = list_make1(def->arg);
 
227
                                n->typmod = -1;
 
228
                                return n;
 
229
                        }
 
230
                default:
 
231
                        ereport(ERROR,
 
232
                                        (errcode(ERRCODE_SYNTAX_ERROR),
 
233
                                         errmsg("argument of %s must be a type name",
 
234
                                                        def->defname)));
 
235
        }
 
236
        return NULL;                            /* keep compiler quiet */
 
237
}
 
238
 
 
239
/*
 
240
 * Extract a type length indicator (either absolute bytes, or
 
241
 * -1 for "variable") from a DefElem.
 
242
 */
 
243
int
 
244
defGetTypeLength(DefElem *def)
 
245
{
 
246
        if (def->arg == NULL)
 
247
                ereport(ERROR,
 
248
                                (errcode(ERRCODE_SYNTAX_ERROR),
 
249
                                 errmsg("%s requires a parameter",
 
250
                                                def->defname)));
 
251
        switch (nodeTag(def->arg))
 
252
        {
 
253
                case T_Integer:
 
254
                        return intVal(def->arg);
 
255
                case T_Float:
 
256
                        ereport(ERROR,
 
257
                                        (errcode(ERRCODE_SYNTAX_ERROR),
 
258
                                         errmsg("%s requires an integer value",
 
259
                                                        def->defname)));
 
260
                        break;
 
261
                case T_String:
 
262
                        if (pg_strcasecmp(strVal(def->arg), "variable") == 0)
 
263
                                return -1;              /* variable length */
 
264
                        break;
 
265
                case T_TypeName:
 
266
                        /* cope if grammar chooses to believe "variable" is a typename */
 
267
                        if (pg_strcasecmp(TypeNameToString((TypeName *) def->arg),
 
268
                                                          "variable") == 0)
 
269
                                return -1;              /* variable length */
 
270
                        break;
 
271
                case T_List:
 
272
                        /* must be an operator name */
 
273
                        break;
 
274
                default:
 
275
                        elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
 
276
        }
 
277
        ereport(ERROR,
 
278
                        (errcode(ERRCODE_SYNTAX_ERROR),
 
279
                         errmsg("invalid argument for %s: \"%s\"",
 
280
                                        def->defname, defGetString(def))));
 
281
        return 0;                                       /* keep compiler quiet */
 
282
}