]> granicus.if.org Git - postgresql/blob - src/backend/nodes/makefuncs.c
ALTER TABLE: skip FK validation when it's safe to do so
[postgresql] / 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-2012, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  *
11  * IDENTIFICATION
12  *        src/backend/nodes/makefuncs.c
13  *
14  *-------------------------------------------------------------------------
15  */
16 #include "postgres.h"
17
18 #include "catalog/pg_class.h"
19 #include "catalog/pg_type.h"
20 #include "nodes/makefuncs.h"
21 #include "nodes/nodeFuncs.h"
22 #include "utils/lsyscache.h"
23
24
25 /*
26  * makeA_Expr -
27  *              makes an A_Expr node
28  */
29 A_Expr *
30 makeA_Expr(A_Expr_Kind kind, List *name,
31                    Node *lexpr, Node *rexpr, int location)
32 {
33         A_Expr     *a = makeNode(A_Expr);
34
35         a->kind = kind;
36         a->name = name;
37         a->lexpr = lexpr;
38         a->rexpr = rexpr;
39         a->location = location;
40         return a;
41 }
42
43 /*
44  * makeSimpleA_Expr -
45  *              As above, given a simple (unqualified) operator name
46  */
47 A_Expr *
48 makeSimpleA_Expr(A_Expr_Kind kind, char *name,
49                                  Node *lexpr, Node *rexpr, int location)
50 {
51         A_Expr     *a = makeNode(A_Expr);
52
53         a->kind = kind;
54         a->name = list_make1(makeString((char *) name));
55         a->lexpr = lexpr;
56         a->rexpr = rexpr;
57         a->location = location;
58         return a;
59 }
60
61 /*
62  * makeVar -
63  *        creates a Var node
64  */
65 Var *
66 makeVar(Index varno,
67                 AttrNumber varattno,
68                 Oid vartype,
69                 int32 vartypmod,
70                 Oid varcollid,
71                 Index varlevelsup)
72 {
73         Var                *var = makeNode(Var);
74
75         var->varno = varno;
76         var->varattno = varattno;
77         var->vartype = vartype;
78         var->vartypmod = vartypmod;
79         var->varcollid = varcollid;
80         var->varlevelsup = varlevelsup;
81
82         /*
83          * Since few if any routines ever create Var nodes with varnoold/varoattno
84          * different from varno/varattno, we don't provide separate arguments for
85          * them, but just initialize them to the given varno/varattno. This
86          * reduces code clutter and chance of error for most callers.
87          */
88         var->varnoold = varno;
89         var->varoattno = varattno;
90
91         /* Likewise, we just set location to "unknown" here */
92         var->location = -1;
93
94         return var;
95 }
96
97 /*
98  * makeVarFromTargetEntry -
99  *              convenience function to create a same-level Var node from a
100  *              TargetEntry
101  */
102 Var *
103 makeVarFromTargetEntry(Index varno,
104                                            TargetEntry *tle)
105 {
106         return makeVar(varno,
107                                    tle->resno,
108                                    exprType((Node *) tle->expr),
109                                    exprTypmod((Node *) tle->expr),
110                                    exprCollation((Node *) tle->expr),
111                                    0);
112 }
113
114 /*
115  * makeWholeRowVar -
116  *        creates a Var node representing a whole row of the specified RTE
117  *
118  * A whole-row reference is a Var with varno set to the correct range
119  * table entry, and varattno == 0 to signal that it references the whole
120  * tuple.  (Use of zero here is unclean, since it could easily be confused
121  * with error cases, but it's not worth changing now.)  The vartype indicates
122  * a rowtype; either a named composite type, or RECORD.  This function
123  * encapsulates the logic for determining the correct rowtype OID to use.
124  *
125  * If allowScalar is true, then for the case where the RTE is a function
126  * returning a non-composite result type, we produce a normal Var referencing
127  * the function's result directly, instead of the single-column composite
128  * value that the whole-row notation might otherwise suggest.
129  */
130 Var *
131 makeWholeRowVar(RangeTblEntry *rte,
132                                 Index varno,
133                                 Index varlevelsup,
134                                 bool allowScalar)
135 {
136         Var                *result;
137         Oid                     toid;
138
139         switch (rte->rtekind)
140         {
141                 case RTE_RELATION:
142                         /* relation: the rowtype is a named composite type */
143                         toid = get_rel_type_id(rte->relid);
144                         if (!OidIsValid(toid))
145                                 elog(ERROR, "could not find type OID for relation %u",
146                                          rte->relid);
147                         result = makeVar(varno,
148                                                          InvalidAttrNumber,
149                                                          toid,
150                                                          -1,
151                                                          InvalidOid,
152                                                          varlevelsup);
153                         break;
154                 case RTE_FUNCTION:
155                         toid = exprType(rte->funcexpr);
156                         if (type_is_rowtype(toid))
157                         {
158                                 /* func returns composite; same as relation case */
159                                 result = makeVar(varno,
160                                                                  InvalidAttrNumber,
161                                                                  toid,
162                                                                  -1,
163                                                                  InvalidOid,
164                                                                  varlevelsup);
165                         }
166                         else if (allowScalar)
167                         {
168                                 /* func returns scalar; just return its output as-is */
169                                 result = makeVar(varno,
170                                                                  1,
171                                                                  toid,
172                                                                  -1,
173                                                                  exprCollation(rte->funcexpr),
174                                                                  varlevelsup);
175                         }
176                         else
177                         {
178                                 /* func returns scalar, but we want a composite result */
179                                 result = makeVar(varno,
180                                                                  InvalidAttrNumber,
181                                                                  RECORDOID,
182                                                                  -1,
183                                                                  InvalidOid,
184                                                                  varlevelsup);
185                         }
186                         break;
187                 default:
188
189                         /*
190                          * RTE is a join, subselect, or VALUES.  We represent this as a
191                          * whole-row Var of RECORD type. (Note that in most cases the Var
192                          * will be expanded to a RowExpr during planning, but that is not
193                          * our concern here.)
194                          */
195                         result = makeVar(varno,
196                                                          InvalidAttrNumber,
197                                                          RECORDOID,
198                                                          -1,
199                                                          InvalidOid,
200                                                          varlevelsup);
201                         break;
202         }
203
204         return result;
205 }
206
207 /*
208  * makeTargetEntry -
209  *        creates a TargetEntry node
210  */
211 TargetEntry *
212 makeTargetEntry(Expr *expr,
213                                 AttrNumber resno,
214                                 char *resname,
215                                 bool resjunk)
216 {
217         TargetEntry *tle = makeNode(TargetEntry);
218
219         tle->expr = expr;
220         tle->resno = resno;
221         tle->resname = resname;
222
223         /*
224          * We always set these fields to 0. If the caller wants to change them he
225          * must do so explicitly.  Few callers do that, so omitting these
226          * arguments reduces the chance of error.
227          */
228         tle->ressortgroupref = 0;
229         tle->resorigtbl = InvalidOid;
230         tle->resorigcol = 0;
231
232         tle->resjunk = resjunk;
233
234         return tle;
235 }
236
237 /*
238  * flatCopyTargetEntry -
239  *        duplicate a TargetEntry, but don't copy substructure
240  *
241  * This is commonly used when we just want to modify the resno or substitute
242  * a new expression.
243  */
244 TargetEntry *
245 flatCopyTargetEntry(TargetEntry *src_tle)
246 {
247         TargetEntry *tle = makeNode(TargetEntry);
248
249         Assert(IsA(src_tle, TargetEntry));
250         memcpy(tle, src_tle, sizeof(TargetEntry));
251         return tle;
252 }
253
254 /*
255  * makeFromExpr -
256  *        creates a FromExpr node
257  */
258 FromExpr *
259 makeFromExpr(List *fromlist, Node *quals)
260 {
261         FromExpr   *f = makeNode(FromExpr);
262
263         f->fromlist = fromlist;
264         f->quals = quals;
265         return f;
266 }
267
268 /*
269  * makeConst -
270  *        creates a Const node
271  */
272 Const *
273 makeConst(Oid consttype,
274                   int32 consttypmod,
275                   Oid constcollid,
276                   int constlen,
277                   Datum constvalue,
278                   bool constisnull,
279                   bool constbyval)
280 {
281         Const      *cnst = makeNode(Const);
282
283         cnst->consttype = consttype;
284         cnst->consttypmod = consttypmod;
285         cnst->constcollid = constcollid;
286         cnst->constlen = constlen;
287         cnst->constvalue = constvalue;
288         cnst->constisnull = constisnull;
289         cnst->constbyval = constbyval;
290         cnst->location = -1;            /* "unknown" */
291
292         return cnst;
293 }
294
295 /*
296  * makeNullConst -
297  *        creates a Const node representing a NULL of the specified type/typmod
298  *
299  * This is a convenience routine that just saves a lookup of the type's
300  * storage properties.
301  */
302 Const *
303 makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
304 {
305         int16           typLen;
306         bool            typByVal;
307
308         get_typlenbyval(consttype, &typLen, &typByVal);
309         return makeConst(consttype,
310                                          consttypmod,
311                                          constcollid,
312                                          (int) typLen,
313                                          (Datum) 0,
314                                          true,
315                                          typByVal);
316 }
317
318 /*
319  * makeBoolConst -
320  *        creates a Const node representing a boolean value (can be NULL too)
321  */
322 Node *
323 makeBoolConst(bool value, bool isnull)
324 {
325         /* note that pg_type.h hardwires size of bool as 1 ... duplicate it */
326         return (Node *) makeConst(BOOLOID, -1, InvalidOid, 1,
327                                                           BoolGetDatum(value), isnull, true);
328 }
329
330 /*
331  * makeBoolExpr -
332  *        creates a BoolExpr node
333  */
334 Expr *
335 makeBoolExpr(BoolExprType boolop, List *args, int location)
336 {
337         BoolExpr   *b = makeNode(BoolExpr);
338
339         b->boolop = boolop;
340         b->args = args;
341         b->location = location;
342
343         return (Expr *) b;
344 }
345
346 /*
347  * makeAlias -
348  *        creates an Alias node
349  *
350  * NOTE: the given name is copied, but the colnames list (if any) isn't.
351  */
352 Alias *
353 makeAlias(const char *aliasname, List *colnames)
354 {
355         Alias      *a = makeNode(Alias);
356
357         a->aliasname = pstrdup(aliasname);
358         a->colnames = colnames;
359
360         return a;
361 }
362
363 /*
364  * makeRelabelType -
365  *        creates a RelabelType node
366  */
367 RelabelType *
368 makeRelabelType(Expr *arg, Oid rtype, int32 rtypmod, Oid rcollid,
369                                 CoercionForm rformat)
370 {
371         RelabelType *r = makeNode(RelabelType);
372
373         r->arg = arg;
374         r->resulttype = rtype;
375         r->resulttypmod = rtypmod;
376         r->resultcollid = rcollid;
377         r->relabelformat = rformat;
378         r->location = -1;
379
380         return r;
381 }
382
383 /*
384  * makeRangeVar -
385  *        creates a RangeVar node (rather oversimplified case)
386  */
387 RangeVar *
388 makeRangeVar(char *schemaname, char *relname, int location)
389 {
390         RangeVar   *r = makeNode(RangeVar);
391
392         r->catalogname = NULL;
393         r->schemaname = schemaname;
394         r->relname = relname;
395         r->inhOpt = INH_DEFAULT;
396         r->relpersistence = RELPERSISTENCE_PERMANENT;
397         r->alias = NULL;
398         r->location = location;
399
400         return r;
401 }
402
403 /*
404  * makeTypeName -
405  *      build a TypeName node for an unqualified name.
406  *
407  * typmod is defaulted, but can be changed later by caller.
408  */
409 TypeName *
410 makeTypeName(char *typnam)
411 {
412         return makeTypeNameFromNameList(list_make1(makeString(typnam)));
413 }
414
415 /*
416  * makeTypeNameFromNameList -
417  *      build a TypeName node for a String list representing a qualified name.
418  *
419  * typmod is defaulted, but can be changed later by caller.
420  */
421 TypeName *
422 makeTypeNameFromNameList(List *names)
423 {
424         TypeName   *n = makeNode(TypeName);
425
426         n->names = names;
427         n->typmods = NIL;
428         n->typemod = -1;
429         n->location = -1;
430         return n;
431 }
432
433 /*
434  * makeTypeNameFromOid -
435  *      build a TypeName node to represent a type already known by OID/typmod.
436  */
437 TypeName *
438 makeTypeNameFromOid(Oid typeOid, int32 typmod)
439 {
440         TypeName   *n = makeNode(TypeName);
441
442         n->typeOid = typeOid;
443         n->typemod = typmod;
444         n->location = -1;
445         return n;
446 }
447
448 /*
449  * makeFuncExpr -
450  *      build an expression tree representing a function call.
451  *
452  * The argument expressions must have been transformed already.
453  */
454 FuncExpr *
455 makeFuncExpr(Oid funcid, Oid rettype, List *args,
456                          Oid funccollid, Oid inputcollid, CoercionForm fformat)
457 {
458         FuncExpr   *funcexpr;
459
460         funcexpr = makeNode(FuncExpr);
461         funcexpr->funcid = funcid;
462         funcexpr->funcresulttype = rettype;
463         funcexpr->funcretset = false;           /* only allowed case here */
464         funcexpr->funcformat = fformat;
465         funcexpr->funccollid = funccollid;
466         funcexpr->inputcollid = inputcollid;
467         funcexpr->args = args;
468         funcexpr->location = -1;
469
470         return funcexpr;
471 }
472
473 /*
474  * makeDefElem -
475  *      build a DefElem node
476  *
477  * This is sufficient for the "typical" case with an unqualified option name
478  * and no special action.
479  */
480 DefElem *
481 makeDefElem(char *name, Node *arg)
482 {
483         DefElem    *res = makeNode(DefElem);
484
485         res->defnamespace = NULL;
486         res->defname = name;
487         res->arg = arg;
488         res->defaction = DEFELEM_UNSPEC;
489
490         return res;
491 }
492
493 /*
494  * makeDefElemExtended -
495  *      build a DefElem node with all fields available to be specified
496  */
497 DefElem *
498 makeDefElemExtended(char *nameSpace, char *name, Node *arg,
499                                         DefElemAction defaction)
500 {
501         DefElem    *res = makeNode(DefElem);
502
503         res->defnamespace = nameSpace;
504         res->defname = name;
505         res->arg = arg;
506         res->defaction = defaction;
507
508         return res;
509 }