OSDN Git Service

5550f706b18c23a8a1d50472018b7b0220e21968
[pg-rex/syncrep.git] / src / backend / nodes / makefuncs.c
1 /*-------------------------------------------------------------------------
2  *
3  * makefuncs.c
4  *        creator functions for primitive nodes. The functions here are for
5  *        the most frequently created nodes.
6  *
7  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  *
11  * IDENTIFICATION
12  *        $PostgreSQL: pgsql/src/backend/nodes/makefuncs.c,v 1.66 2010/01/02 16:57:46 momjian Exp $
13  *
14  *-------------------------------------------------------------------------
15  */
16 #include "postgres.h"
17
18 #include "catalog/pg_type.h"
19 #include "nodes/makefuncs.h"
20 #include "utils/lsyscache.h"
21
22
23 /*
24  * makeA_Expr -
25  *              makes an A_Expr node
26  */
27 A_Expr *
28 makeA_Expr(A_Expr_Kind kind, List *name,
29                    Node *lexpr, Node *rexpr, int location)
30 {
31         A_Expr     *a = makeNode(A_Expr);
32
33         a->kind = kind;
34         a->name = name;
35         a->lexpr = lexpr;
36         a->rexpr = rexpr;
37         a->location = location;
38         return a;
39 }
40
41 /*
42  * makeSimpleA_Expr -
43  *              As above, given a simple (unqualified) operator name
44  */
45 A_Expr *
46 makeSimpleA_Expr(A_Expr_Kind kind, const char *name,
47                                  Node *lexpr, Node *rexpr, int location)
48 {
49         A_Expr     *a = makeNode(A_Expr);
50
51         a->kind = kind;
52         a->name = list_make1(makeString((char *) name));
53         a->lexpr = lexpr;
54         a->rexpr = rexpr;
55         a->location = location;
56         return a;
57 }
58
59 /*
60  * makeVar -
61  *        creates a Var node
62  */
63 Var *
64 makeVar(Index varno,
65                 AttrNumber varattno,
66                 Oid vartype,
67                 int32 vartypmod,
68                 Index varlevelsup)
69 {
70         Var                *var = makeNode(Var);
71
72         var->varno = varno;
73         var->varattno = varattno;
74         var->vartype = vartype;
75         var->vartypmod = vartypmod;
76         var->varlevelsup = varlevelsup;
77
78         /*
79          * Since few if any routines ever create Var nodes with varnoold/varoattno
80          * different from varno/varattno, we don't provide separate arguments for
81          * them, but just initialize them to the given varno/varattno. This
82          * reduces code clutter and chance of error for most callers.
83          */
84         var->varnoold = varno;
85         var->varoattno = varattno;
86
87         /* Likewise, we just set location to "unknown" here */
88         var->location = -1;
89
90         return var;
91 }
92
93 /*
94  * makeTargetEntry -
95  *        creates a TargetEntry node
96  */
97 TargetEntry *
98 makeTargetEntry(Expr *expr,
99                                 AttrNumber resno,
100                                 char *resname,
101                                 bool resjunk)
102 {
103         TargetEntry *tle = makeNode(TargetEntry);
104
105         tle->expr = expr;
106         tle->resno = resno;
107         tle->resname = resname;
108
109         /*
110          * We always set these fields to 0. If the caller wants to change them he
111          * must do so explicitly.  Few callers do that, so omitting these
112          * arguments reduces the chance of error.
113          */
114         tle->ressortgroupref = 0;
115         tle->resorigtbl = InvalidOid;
116         tle->resorigcol = 0;
117
118         tle->resjunk = resjunk;
119
120         return tle;
121 }
122
123 /*
124  * flatCopyTargetEntry -
125  *        duplicate a TargetEntry, but don't copy substructure
126  *
127  * This is commonly used when we just want to modify the resno or substitute
128  * a new expression.
129  */
130 TargetEntry *
131 flatCopyTargetEntry(TargetEntry *src_tle)
132 {
133         TargetEntry *tle = makeNode(TargetEntry);
134
135         Assert(IsA(src_tle, TargetEntry));
136         memcpy(tle, src_tle, sizeof(TargetEntry));
137         return tle;
138 }
139
140 /*
141  * makeFromExpr -
142  *        creates a FromExpr node
143  */
144 FromExpr *
145 makeFromExpr(List *fromlist, Node *quals)
146 {
147         FromExpr   *f = makeNode(FromExpr);
148
149         f->fromlist = fromlist;
150         f->quals = quals;
151         return f;
152 }
153
154 /*
155  * makeConst -
156  *        creates a Const node
157  */
158 Const *
159 makeConst(Oid consttype,
160                   int32 consttypmod,
161                   int constlen,
162                   Datum constvalue,
163                   bool constisnull,
164                   bool constbyval)
165 {
166         Const      *cnst = makeNode(Const);
167
168         cnst->consttype = consttype;
169         cnst->consttypmod = consttypmod;
170         cnst->constlen = constlen;
171         cnst->constvalue = constvalue;
172         cnst->constisnull = constisnull;
173         cnst->constbyval = constbyval;
174         cnst->location = -1;            /* "unknown" */
175
176         return cnst;
177 }
178
179 /*
180  * makeNullConst -
181  *        creates a Const node representing a NULL of the specified type/typmod
182  *
183  * This is a convenience routine that just saves a lookup of the type's
184  * storage properties.
185  */
186 Const *
187 makeNullConst(Oid consttype, int32 consttypmod)
188 {
189         int16           typLen;
190         bool            typByVal;
191
192         get_typlenbyval(consttype, &typLen, &typByVal);
193         return makeConst(consttype,
194                                          consttypmod,
195                                          (int) typLen,
196                                          (Datum) 0,
197                                          true,
198                                          typByVal);
199 }
200
201 /*
202  * makeBoolConst -
203  *        creates a Const node representing a boolean value (can be NULL too)
204  */
205 Node *
206 makeBoolConst(bool value, bool isnull)
207 {
208         /* note that pg_type.h hardwires size of bool as 1 ... duplicate it */
209         return (Node *) makeConst(BOOLOID, -1, 1,
210                                                           BoolGetDatum(value), isnull, true);
211 }
212
213 /*
214  * makeBoolExpr -
215  *        creates a BoolExpr node
216  */
217 Expr *
218 makeBoolExpr(BoolExprType boolop, List *args, int location)
219 {
220         BoolExpr   *b = makeNode(BoolExpr);
221
222         b->boolop = boolop;
223         b->args = args;
224         b->location = location;
225
226         return (Expr *) b;
227 }
228
229 /*
230  * makeAlias -
231  *        creates an Alias node
232  *
233  * NOTE: the given name is copied, but the colnames list (if any) isn't.
234  */
235 Alias *
236 makeAlias(const char *aliasname, List *colnames)
237 {
238         Alias      *a = makeNode(Alias);
239
240         a->aliasname = pstrdup(aliasname);
241         a->colnames = colnames;
242
243         return a;
244 }
245
246 /*
247  * makeRelabelType -
248  *        creates a RelabelType node
249  */
250 RelabelType *
251 makeRelabelType(Expr *arg, Oid rtype, int32 rtypmod, CoercionForm rformat)
252 {
253         RelabelType *r = makeNode(RelabelType);
254
255         r->arg = arg;
256         r->resulttype = rtype;
257         r->resulttypmod = rtypmod;
258         r->relabelformat = rformat;
259         r->location = -1;
260
261         return r;
262 }
263
264 /*
265  * makeRangeVar -
266  *        creates a RangeVar node (rather oversimplified case)
267  */
268 RangeVar *
269 makeRangeVar(char *schemaname, char *relname, int location)
270 {
271         RangeVar   *r = makeNode(RangeVar);
272
273         r->catalogname = NULL;
274         r->schemaname = schemaname;
275         r->relname = relname;
276         r->inhOpt = INH_DEFAULT;
277         r->istemp = false;
278         r->alias = NULL;
279         r->location = location;
280
281         return r;
282 }
283
284 /*
285  * makeTypeName -
286  *      build a TypeName node for an unqualified name.
287  *
288  * typmod is defaulted, but can be changed later by caller.
289  */
290 TypeName *
291 makeTypeName(char *typnam)
292 {
293         return makeTypeNameFromNameList(list_make1(makeString(typnam)));
294 }
295
296 /*
297  * makeTypeNameFromNameList -
298  *      build a TypeName node for a String list representing a qualified name.
299  *
300  * typmod is defaulted, but can be changed later by caller.
301  */
302 TypeName *
303 makeTypeNameFromNameList(List *names)
304 {
305         TypeName   *n = makeNode(TypeName);
306
307         n->names = names;
308         n->typmods = NIL;
309         n->typemod = -1;
310         n->location = -1;
311         return n;
312 }
313
314 /*
315  * makeTypeNameFromOid -
316  *      build a TypeName node to represent a type already known by OID/typmod.
317  */
318 TypeName *
319 makeTypeNameFromOid(Oid typeOid, int32 typmod)
320 {
321         TypeName   *n = makeNode(TypeName);
322
323         n->typeOid = typeOid;
324         n->typemod = typmod;
325         n->location = -1;
326         return n;
327 }
328
329 /*
330  * makeFuncExpr -
331  *      build an expression tree representing a function call.
332  *
333  * The argument expressions must have been transformed already.
334  */
335 FuncExpr *
336 makeFuncExpr(Oid funcid, Oid rettype, List *args, CoercionForm fformat)
337 {
338         FuncExpr   *funcexpr;
339
340         funcexpr = makeNode(FuncExpr);
341         funcexpr->funcid = funcid;
342         funcexpr->funcresulttype = rettype;
343         funcexpr->funcretset = false;           /* only allowed case here */
344         funcexpr->funcformat = fformat;
345         funcexpr->args = args;
346         funcexpr->location = -1;
347
348         return funcexpr;
349 }
350
351 /*
352  * makeDefElem -
353  *      build a DefElem node
354  *
355  * This is sufficient for the "typical" case with an unqualified option name
356  * and no special action.
357  */
358 DefElem *
359 makeDefElem(char *name, Node *arg)
360 {
361         DefElem    *res = makeNode(DefElem);
362
363         res->defnamespace = NULL;
364         res->defname = name;
365         res->arg = arg;
366         res->defaction = DEFELEM_UNSPEC;
367
368         return res;
369 }
370
371 /*
372  * makeDefElemExtended -
373  *      build a DefElem node with all fields available to be specified
374  */
375 DefElem *
376 makeDefElemExtended(char *nameSpace, char *name, Node *arg,
377                                         DefElemAction defaction)
378 {
379         DefElem    *res = makeNode(DefElem);
380
381         res->defnamespace = nameSpace;
382         res->defname = name;
383         res->arg = arg;
384         res->defaction = defaction;
385
386         return res;
387 }