]> granicus.if.org Git - postgresql/blob - src/backend/parser/analyze.c
Second phase of committing Rod Taylor's pg_depend/pg_constraint patch.
[postgresql] / src / backend / parser / analyze.c
1 /*-------------------------------------------------------------------------
2  *
3  * analyze.c
4  *        transform the parse tree into a query tree
5  *
6  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *      $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.238 2002/07/12 18:43:17 tgl Exp $
10  *
11  *-------------------------------------------------------------------------
12  */
13
14 #include "postgres.h"
15
16 #include "access/heapam.h"
17 #include "catalog/catname.h"
18 #include "catalog/heap.h"
19 #include "catalog/index.h"
20 #include "catalog/namespace.h"
21 #include "catalog/pg_index.h"
22 #include "catalog/pg_type.h"
23 #include "nodes/makefuncs.h"
24 #include "parser/analyze.h"
25 #include "parser/gramparse.h"
26 #include "parser/parsetree.h"
27 #include "parser/parse_agg.h"
28 #include "parser/parse_clause.h"
29 #include "parser/parse_coerce.h"
30 #include "parser/parse_expr.h"
31 #include "parser/parse_oper.h"
32 #include "parser/parse_relation.h"
33 #include "parser/parse_target.h"
34 #include "parser/parse_type.h"
35 #include "parser/parse_expr.h"
36 #include "rewrite/rewriteManip.h"
37 #include "utils/builtins.h"
38 #include "utils/fmgroids.h"
39 #include "utils/lsyscache.h"
40 #include "utils/relcache.h"
41 #include "utils/syscache.h"
42 #ifdef MULTIBYTE
43 #include "mb/pg_wchar.h"
44 #endif
45
46
47 /* State shared by transformCreateSchemaStmt and its subroutines */
48 typedef struct
49 {
50         const char *stmtType;           /* "CREATE SCHEMA" or "ALTER SCHEMA" */
51         char       *schemaname;         /* name of schema */
52         char       *authid;                     /* owner of schema */
53         List       *tables;                     /* CREATE TABLE items */
54         List       *views;                      /* CREATE VIEW items */
55         List       *grants;                     /* GRANT items */
56         List       *fwconstraints;      /* Forward referencing FOREIGN KEY constraints */
57         List       *alters;                     /* Generated ALTER items (from the above) */
58         List       *ixconstraints;      /* index-creating constraints */
59         List       *blist;                      /* "before list" of things to do before
60                                                                  * creating the schema */
61         List       *alist;                      /* "after list" of things to do after
62                                                                  * creating the schema */
63 } CreateSchemaStmtContext;
64
65 /* State shared by transformCreateStmt and its subroutines */
66 typedef struct
67 {
68         const char *stmtType;           /* "CREATE TABLE" or "ALTER TABLE" */
69         RangeVar   *relation;           /* relation to create */
70         List       *inhRelations;       /* relations to inherit from */
71         bool            hasoids;                /* does relation have an OID column? */
72         Oid                     relOid;                 /* OID of table, if ALTER TABLE case */
73         List       *columns;            /* ColumnDef items */
74         List       *ckconstraints;      /* CHECK constraints */
75         List       *fkconstraints;      /* FOREIGN KEY constraints */
76         List       *ixconstraints;      /* index-creating constraints */
77         List       *blist;                      /* "before list" of things to do before
78                                                                  * creating the table */
79         List       *alist;                      /* "after list" of things to do after
80                                                                  * creating the table */
81         IndexStmt  *pkey;                       /* PRIMARY KEY index, if any */
82 } CreateStmtContext;
83
84
85 static Query *transformStmt(ParseState *pstate, Node *stmt,
86                                                 List **extras_before, List **extras_after);
87 static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt);
88 static Query *transformInsertStmt(ParseState *pstate, InsertStmt *stmt,
89                                                 List **extras_before, List **extras_after);
90 static Query *transformIndexStmt(ParseState *pstate, IndexStmt *stmt);
91 static Query *transformRuleStmt(ParseState *query, RuleStmt *stmt,
92                                                 List **extras_before, List **extras_after);
93 static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt);
94 static Query *transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt);
95 static Node *transformSetOperationTree(ParseState *pstate, SelectStmt *stmt);
96 static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt);
97 static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt,
98                                                 List **extras_before, List **extras_after);
99 static Query *transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt,
100                                                 List **extras_before, List **extras_after);
101 static void transformColumnDefinition(ParseState *pstate,
102                                                   CreateStmtContext *cxt,
103                                                   ColumnDef *column);
104 static void transformTableConstraint(ParseState *pstate,
105                                                  CreateStmtContext *cxt,
106                                                  Constraint *constraint);
107 static void transformIndexConstraints(ParseState *pstate,
108                                                   CreateStmtContext *cxt);
109 static void transformFKConstraints(ParseState *pstate,
110                                            CreateStmtContext *cxt);
111 static void applyColumnNames(List *dst, List *src);
112 static List *getSetColTypes(ParseState *pstate, Node *node);
113 static void transformForUpdate(Query *qry, List *forUpdate);
114 static void transformConstraintAttrs(List *constraintList);
115 static void transformColumnType(ParseState *pstate, ColumnDef *column);
116 static void transformFkeyCheckAttrs(FkConstraint *fkconstraint, Oid *pktypoid);
117 static void transformFkeyGetPrimaryKey(FkConstraint *fkconstraint, Oid *pktypoid);
118 static bool relationHasPrimaryKey(Oid relationOid);
119 static Oid      transformFkeyGetColType(CreateStmtContext *cxt, char *colname);
120 static void release_pstate_resources(ParseState *pstate);
121 static FromExpr *makeFromExpr(List *fromlist, Node *quals);
122
123
124
125 /*
126  * parse_analyze -
127  *        analyze a raw parse tree and transform it to Query form.
128  *
129  * The result is a List of Query nodes (we need a list since some commands
130  * produce multiple Queries).  Optimizable statements require considerable
131  * transformation, while many utility-type statements are simply hung off
132  * a dummy CMD_UTILITY Query node.
133  */
134 List *
135 parse_analyze(Node *parseTree, ParseState *parentParseState)
136 {
137         List       *result = NIL;
138         ParseState *pstate = make_parsestate(parentParseState);
139         /* Lists to return extra commands from transformation */
140         List       *extras_before = NIL;
141         List       *extras_after = NIL;
142         Query      *query;
143         List       *listscan;
144
145         query = transformStmt(pstate, parseTree, &extras_before, &extras_after);
146         release_pstate_resources(pstate);
147
148         while (extras_before != NIL)
149         {
150                 result = nconc(result, parse_analyze(lfirst(extras_before), pstate));
151                 extras_before = lnext(extras_before);
152         }
153
154         result = lappend(result, query);
155
156         while (extras_after != NIL)
157         {
158                 result = nconc(result, parse_analyze(lfirst(extras_after), pstate));
159                 extras_after = lnext(extras_after);
160         }
161
162         /*
163          * Make sure that only the original query is marked original.
164          * We have to do this explicitly since recursive calls of parse_analyze
165          * will have set originalQuery in some of the added-on queries.
166          */
167         foreach(listscan, result)
168         {
169                 Query  *q = lfirst(listscan);
170
171                 q->originalQuery = (q == query);
172         }
173
174         pfree(pstate);
175
176         return result;
177 }
178
179 static void
180 release_pstate_resources(ParseState *pstate)
181 {
182         if (pstate->p_target_relation != NULL)
183                 heap_close(pstate->p_target_relation, NoLock);
184         pstate->p_target_relation = NULL;
185         pstate->p_target_rangetblentry = NULL;
186 }
187
188 /*
189  * transformStmt -
190  *        transform a Parse tree into a Query tree.
191  */
192 static Query *
193 transformStmt(ParseState *pstate, Node *parseTree,
194                           List **extras_before, List **extras_after)
195 {
196         Query      *result = NULL;
197
198         switch (nodeTag(parseTree))
199         {
200                         /*
201                          * Non-optimizable statements
202                          */
203                 case T_CreateStmt:
204                         result = transformCreateStmt(pstate, (CreateStmt *) parseTree,
205                                                                         extras_before, extras_after);
206                         break;
207
208                 case T_IndexStmt:
209                         result = transformIndexStmt(pstate, (IndexStmt *) parseTree);
210                         break;
211
212                 case T_RuleStmt:
213                         result = transformRuleStmt(pstate, (RuleStmt *) parseTree,
214                                                                         extras_before, extras_after);
215                         break;
216
217                 case T_ViewStmt:
218                         {
219                                 ViewStmt   *n = (ViewStmt *) parseTree;
220
221                                 n->query = transformStmt(pstate, (Node *) n->query,
222                                                                         extras_before, extras_after);
223
224                                 /*
225                                  * If a list of column names was given, run through and
226                                  * insert these into the actual query tree. - thomas
227                                  * 2000-03-08
228                                  *
229                                  * Outer loop is over targetlist to make it easier to skip
230                                  * junk targetlist entries.
231                                  */
232                                 if (n->aliases != NIL)
233                                 {
234                                         List       *aliaslist = n->aliases;
235                                         List       *targetList;
236
237                                         foreach(targetList, n->query->targetList)
238                                         {
239                                                 TargetEntry *te = (TargetEntry *) lfirst(targetList);
240                                                 Resdom     *rd;
241                                                 Ident      *id;
242
243                                                 Assert(IsA(te, TargetEntry));
244                                                 rd = te->resdom;
245                                                 Assert(IsA(rd, Resdom));
246                                                 if (rd->resjunk)                /* junk columns don't get
247                                                                                                  * aliases */
248                                                         continue;
249                                                 id = (Ident *) lfirst(aliaslist);
250                                                 Assert(IsA(id, Ident));
251                                                 rd->resname = pstrdup(id->name);
252                                                 aliaslist = lnext(aliaslist);
253                                                 if (aliaslist == NIL)
254                                                         break;          /* done assigning aliases */
255                                         }
256
257                                         if (aliaslist != NIL)
258                                                 elog(ERROR, "CREATE VIEW specifies more column names than columns");
259                                 }
260                                 result = makeNode(Query);
261                                 result->commandType = CMD_UTILITY;
262                                 result->utilityStmt = (Node *) n;
263                         }
264                         break;
265
266                 case T_ExplainStmt:
267                         {
268                                 ExplainStmt *n = (ExplainStmt *) parseTree;
269
270                                 result = makeNode(Query);
271                                 result->commandType = CMD_UTILITY;
272                                 n->query = transformStmt(pstate, (Node *) n->query,
273                                                                 extras_before, extras_after);
274                                 result->utilityStmt = (Node *) parseTree;
275                         }
276                         break;
277
278                 case T_AlterTableStmt:
279                         result = transformAlterTableStmt(pstate, (AlterTableStmt *) parseTree,
280                                                                                 extras_before, extras_after);
281                         break;
282
283                         /*
284                          * Optimizable statements
285                          */
286                 case T_InsertStmt:
287                         result = transformInsertStmt(pstate, (InsertStmt *) parseTree,
288                                                                                 extras_before, extras_after);
289                         break;
290
291                 case T_DeleteStmt:
292                         result = transformDeleteStmt(pstate, (DeleteStmt *) parseTree);
293                         break;
294
295                 case T_UpdateStmt:
296                         result = transformUpdateStmt(pstate, (UpdateStmt *) parseTree);
297                         break;
298
299                 case T_SelectStmt:
300                         if (((SelectStmt *) parseTree)->op == SETOP_NONE)
301                                 result = transformSelectStmt(pstate,
302                                                                                          (SelectStmt *) parseTree);
303                         else
304                                 result = transformSetOperationStmt(pstate,
305                                                                                            (SelectStmt *) parseTree);
306                         break;
307
308                 default:
309
310                         /*
311                          * other statements don't require any transformation-- just
312                          * return the original parsetree, yea!
313                          */
314                         result = makeNode(Query);
315                         result->commandType = CMD_UTILITY;
316                         result->utilityStmt = (Node *) parseTree;
317                         break;
318         }
319         return result;
320 }
321
322 /*
323  * transformDeleteStmt -
324  *        transforms a Delete Statement
325  */
326 static Query *
327 transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
328 {
329         Query      *qry = makeNode(Query);
330         Node       *qual;
331
332         qry->commandType = CMD_DELETE;
333
334         /* set up range table with just the result rel */
335         qry->resultRelation = setTargetTable(pstate, stmt->relation,
336                                                                                  interpretInhOption(stmt->relation->inhOpt),
337                                                                                  true);
338
339         qry->distinctClause = NIL;
340
341         /* fix where clause */
342         qual = transformWhereClause(pstate, stmt->whereClause);
343
344         /* done building the range table and jointree */
345         qry->rtable = pstate->p_rtable;
346         qry->jointree = makeFromExpr(pstate->p_joinlist, qual);
347
348         qry->hasSubLinks = pstate->p_hasSubLinks;
349         qry->hasAggs = pstate->p_hasAggs;
350         if (pstate->p_hasAggs)
351                 parseCheckAggregates(pstate, qry, qual);
352
353         return qry;
354 }
355
356 /*
357  * transformInsertStmt -
358  *        transform an Insert Statement
359  */
360 static Query *
361 transformInsertStmt(ParseState *pstate, InsertStmt *stmt,
362                                         List **extras_before, List **extras_after)
363 {
364         Query      *qry = makeNode(Query);
365         List       *sub_rtable;
366         List       *sub_namespace;
367         List       *icolumns;
368         List       *attrnos;
369         List       *attnos;
370         List       *tl;
371
372         qry->commandType = CMD_INSERT;
373         pstate->p_is_insert = true;
374
375         /*
376          * If a non-nil rangetable/namespace was passed in, and we are doing
377          * INSERT/SELECT, arrange to pass the rangetable/namespace down to the
378          * SELECT.      This can only happen if we are inside a CREATE RULE, and
379          * in that case we want the rule's OLD and NEW rtable entries to
380          * appear as part of the SELECT's rtable, not as outer references for
381          * it.  (Kluge!)  The SELECT's joinlist is not affected however. We
382          * must do this before adding the target table to the INSERT's rtable.
383          */
384         if (stmt->selectStmt)
385         {
386                 sub_rtable = pstate->p_rtable;
387                 pstate->p_rtable = NIL;
388                 sub_namespace = pstate->p_namespace;
389                 pstate->p_namespace = NIL;
390         }
391         else
392         {
393                 sub_rtable = NIL;               /* not used, but keep compiler quiet */
394                 sub_namespace = NIL;
395         }
396
397         /*
398          * Must get write lock on INSERT target table before scanning SELECT,
399          * else we will grab the wrong kind of initial lock if the target
400          * table is also mentioned in the SELECT part.  Note that the target
401          * table is not added to the joinlist or namespace.
402          */
403         qry->resultRelation = setTargetTable(pstate, stmt->relation,
404                                                                                  false, false);
405
406         /*
407          * Is it INSERT ... SELECT or INSERT ... VALUES?
408          */
409         if (stmt->selectStmt)
410         {
411                 ParseState *sub_pstate = make_parsestate(pstate->parentParseState);
412                 Query      *selectQuery;
413                 RangeTblEntry *rte;
414                 RangeTblRef *rtr;
415
416                 /*
417                  * Process the source SELECT.
418                  *
419                  * It is important that this be handled just like a standalone
420                  * SELECT; otherwise the behavior of SELECT within INSERT might be
421                  * different from a stand-alone SELECT. (Indeed, Postgres up
422                  * through 6.5 had bugs of just that nature...)
423                  */
424                 sub_pstate->p_rtable = sub_rtable;
425                 sub_pstate->p_namespace = sub_namespace;
426
427                 /*
428                  * Note: we are not expecting that extras_before and extras_after
429                  * are going to be used by the transformation of the SELECT statement.
430                  */
431                 selectQuery = transformStmt(sub_pstate, stmt->selectStmt,
432                                                                 extras_before, extras_after);
433
434                 release_pstate_resources(sub_pstate);
435                 pfree(sub_pstate);
436
437                 Assert(IsA(selectQuery, Query));
438                 Assert(selectQuery->commandType == CMD_SELECT);
439                 if (selectQuery->into || selectQuery->isPortal)
440                         elog(ERROR, "INSERT ... SELECT may not specify INTO");
441
442                 /*
443                  * Make the source be a subquery in the INSERT's rangetable, and
444                  * add it to the INSERT's joinlist.
445                  */
446                 rte = addRangeTableEntryForSubquery(pstate,
447                                                                                         selectQuery,
448                                                                                         makeAlias("*SELECT*", NIL),
449                                                                                         true);
450                 rtr = makeNode(RangeTblRef);
451                 /* assume new rte is at end */
452                 rtr->rtindex = length(pstate->p_rtable);
453                 Assert(rte == rt_fetch(rtr->rtindex, pstate->p_rtable));
454                 pstate->p_joinlist = lappend(pstate->p_joinlist, rtr);
455
456                 /*
457                  * Generate a targetlist for the INSERT that selects all the
458                  * non-resjunk columns from the subquery.  (We need this to be
459                  * separate from the subquery's tlist because we may add columns,
460                  * insert datatype coercions, etc.)
461                  *
462                  * HACK: constants in the INSERT's targetlist are copied up as-is
463                  * rather than being referenced as subquery outputs.  This is
464                  * mainly to ensure that when we try to coerce them to the target
465                  * column's datatype, the right things happen for UNKNOWN
466                  * constants. Otherwise this fails: INSERT INTO foo SELECT 'bar',
467                  * ... FROM baz
468                  */
469                 qry->targetList = NIL;
470                 foreach(tl, selectQuery->targetList)
471                 {
472                         TargetEntry *tle = (TargetEntry *) lfirst(tl);
473                         Resdom     *resnode = tle->resdom;
474                         Node       *expr;
475
476                         if (resnode->resjunk)
477                                 continue;
478                         if (tle->expr && IsA(tle->expr, Const))
479                                 expr = tle->expr;
480                         else
481                                 expr = (Node *) makeVar(rtr->rtindex,
482                                                                                 resnode->resno,
483                                                                                 resnode->restype,
484                                                                                 resnode->restypmod,
485                                                                                 0);
486                         resnode = copyObject(resnode);
487                         resnode->resno = (AttrNumber) pstate->p_last_resno++;
488                         qry->targetList = lappend(qry->targetList,
489                                                                           makeTargetEntry(resnode, expr));
490                 }
491         }
492         else
493         {
494                 /*
495                  * For INSERT ... VALUES, transform the given list of values to
496                  * form a targetlist for the INSERT.
497                  */
498                 qry->targetList = transformTargetList(pstate, stmt->targetList);
499         }
500
501         /*
502          * Now we are done with SELECT-like processing, and can get on with
503          * transforming the target list to match the INSERT target columns.
504          */
505
506         /* Prepare to assign non-conflicting resnos to resjunk attributes */
507         if (pstate->p_last_resno <= pstate->p_target_relation->rd_rel->relnatts)
508                 pstate->p_last_resno = pstate->p_target_relation->rd_rel->relnatts + 1;
509
510         /* Validate stmt->cols list, or build default list if no list given */
511         icolumns = checkInsertTargets(pstate, stmt->cols, &attrnos);
512
513         /*
514          * Prepare columns for assignment to target table.
515          */
516         attnos = attrnos;
517         foreach(tl, qry->targetList)
518         {
519                 TargetEntry *tle = (TargetEntry *) lfirst(tl);
520                 ResTarget   *col;
521
522                 if (icolumns == NIL || attnos == NIL)
523                         elog(ERROR, "INSERT has more expressions than target columns");
524                 col = (ResTarget *) lfirst(icolumns);
525
526                 /*
527                  * When the value is to be set to the column default we can simply
528                  * drop it now and handle it later on using methods for missing
529                  * columns.
530                  */
531                 if (!IsA(tle, InsertDefault))
532                 {
533                         Assert(IsA(col, ResTarget));
534                         Assert(!tle->resdom->resjunk);
535                         updateTargetListEntry(pstate, tle, col->name, lfirsti(attnos),
536                                                           col->indirection);
537                 }
538                 else
539                 {
540                         icolumns = lremove(icolumns, icolumns);
541                         attnos = lremove(attnos, attnos);
542                         qry->targetList = lremove(tle, qry->targetList);
543                 }
544
545                 icolumns = lnext(icolumns);
546                 attnos = lnext(attnos);
547         }
548
549         /*
550          * Ensure that the targetlist has the same number of  entries
551          * that were present in the columns list.  Don't do the check
552          * for select statements.
553          */
554         if (stmt->cols != NIL && (icolumns != NIL || attnos != NIL))
555                 elog(ERROR, "INSERT has more target columns than expressions");
556
557         /* done building the range table and jointree */
558         qry->rtable = pstate->p_rtable;
559         qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
560
561         qry->hasSubLinks = pstate->p_hasSubLinks;
562         qry->hasAggs = pstate->p_hasAggs;
563         if (pstate->p_hasAggs)
564                 parseCheckAggregates(pstate, qry, NULL);
565
566         return qry;
567 }
568
569 /*
570  *      makeObjectName()
571  *
572  *      Create a name for an implicitly created index, sequence, constraint, etc.
573  *
574  *      The parameters are: the original table name, the original field name, and
575  *      a "type" string (such as "seq" or "pkey").      The field name and/or type
576  *      can be NULL if not relevant.
577  *
578  *      The result is a palloc'd string.
579  *
580  *      The basic result we want is "name1_name2_type", omitting "_name2" or
581  *      "_type" when those parameters are NULL.  However, we must generate
582  *      a name with less than NAMEDATALEN characters!  So, we truncate one or
583  *      both names if necessary to make a short-enough string.  The type part
584  *      is never truncated (so it had better be reasonably short).
585  *
586  *      To reduce the probability of collisions, we might someday add more
587  *      smarts to this routine, like including some "hash" characters computed
588  *      from the truncated characters.  Currently it seems best to keep it simple,
589  *      so that the generated names are easily predictable by a person.
590  */
591 char *
592 makeObjectName(char *name1, char *name2, char *typename)
593 {
594         char       *name;
595         int                     overhead = 0;   /* chars needed for type and underscores */
596         int                     availchars;             /* chars available for name(s) */
597         int                     name1chars;             /* chars allocated to name1 */
598         int                     name2chars;             /* chars allocated to name2 */
599         int                     ndx;
600
601         name1chars = strlen(name1);
602         if (name2)
603         {
604                 name2chars = strlen(name2);
605                 overhead++;                             /* allow for separating underscore */
606         }
607         else
608                 name2chars = 0;
609         if (typename)
610                 overhead += strlen(typename) + 1;
611
612         availchars = NAMEDATALEN - 1 - overhead;
613
614         /*
615          * If we must truncate,  preferentially truncate the longer name. This
616          * logic could be expressed without a loop, but it's simple and
617          * obvious as a loop.
618          */
619         while (name1chars + name2chars > availchars)
620         {
621                 if (name1chars > name2chars)
622                         name1chars--;
623                 else
624                         name2chars--;
625         }
626
627 #ifdef MULTIBYTE
628         if (name1)
629                 name1chars = pg_mbcliplen(name1, name1chars, name1chars);
630         if (name2)
631                 name2chars = pg_mbcliplen(name2, name2chars, name2chars);
632 #endif
633
634         /* Now construct the string using the chosen lengths */
635         name = palloc(name1chars + name2chars + overhead + 1);
636         strncpy(name, name1, name1chars);
637         ndx = name1chars;
638         if (name2)
639         {
640                 name[ndx++] = '_';
641                 strncpy(name + ndx, name2, name2chars);
642                 ndx += name2chars;
643         }
644         if (typename)
645         {
646                 name[ndx++] = '_';
647                 strcpy(name + ndx, typename);
648         }
649         else
650                 name[ndx] = '\0';
651
652         return name;
653 }
654
655 static char *
656 CreateIndexName(char *table_name, char *column_name,
657                                 char *label, List *indices)
658 {
659         int                     pass = 0;
660         char       *iname = NULL;
661         List       *ilist;
662         char            typename[NAMEDATALEN];
663
664         /*
665          * The type name for makeObjectName is label, or labelN if that's
666          * necessary to prevent collisions among multiple indexes for the same
667          * table.  Note there is no check for collisions with already-existing
668          * indexes, only among the indexes we're about to create now; this
669          * ought to be improved someday.
670          */
671         strcpy(typename, label);
672
673         for (;;)
674         {
675                 iname = makeObjectName(table_name, column_name, typename);
676
677                 foreach(ilist, indices)
678                 {
679                         IndexStmt  *index = lfirst(ilist);
680
681                         if (index->idxname != NULL &&
682                                 strcmp(iname, index->idxname) == 0)
683                                 break;
684                 }
685                 /* ran through entire list? then no name conflict found so done */
686                 if (ilist == NIL)
687                         break;
688
689                 /* found a conflict, so try a new name component */
690                 pfree(iname);
691                 sprintf(typename, "%s%d", label, ++pass);
692         }
693
694         return iname;
695 }
696
697 /*
698  * transformCreateStmt -
699  *        transforms the "create table" statement
700  *        SQL92 allows constraints to be scattered all over, so thumb through
701  *         the columns and collect all constraints into one place.
702  *        If there are any implied indices (e.g. UNIQUE or PRIMARY KEY)
703  *         then expand those into multiple IndexStmt blocks.
704  *        - thomas 1997-12-02
705  */
706 static Query *
707 transformCreateStmt(ParseState *pstate, CreateStmt *stmt,
708                                         List **extras_before, List **extras_after)
709 {
710         CreateStmtContext cxt;
711         Query      *q;
712         List       *elements;
713
714         cxt.stmtType = "CREATE TABLE";
715         cxt.relation = stmt->relation;
716         cxt.inhRelations = stmt->inhRelations;
717         cxt.hasoids = stmt->hasoids;
718         cxt.relOid = InvalidOid;
719         cxt.columns = NIL;
720         cxt.ckconstraints = NIL;
721         cxt.fkconstraints = NIL;
722         cxt.ixconstraints = NIL;
723         cxt.blist = NIL;
724         cxt.alist = NIL;
725         cxt.pkey = NULL;
726
727         /*
728          * Run through each primary element in the table creation clause.
729          * Separate column defs from constraints, and do preliminary analysis.
730          */
731         foreach(elements, stmt->tableElts)
732         {
733                 Node       *element = lfirst(elements);
734
735                 switch (nodeTag(element))
736                 {
737                         case T_ColumnDef:
738                                 transformColumnDefinition(pstate, &cxt,
739                                                                                   (ColumnDef *) element);
740                                 break;
741
742                         case T_Constraint:
743                                 transformTableConstraint(pstate, &cxt,
744                                                                                  (Constraint *) element);
745                                 break;
746
747                         case T_FkConstraint:
748                                 /* No pre-transformation needed */
749                                 cxt.fkconstraints = lappend(cxt.fkconstraints, element);
750                                 break;
751
752                         default:
753                                 elog(ERROR, "parser: unrecognized node (internal error)");
754                 }
755         }
756
757         Assert(stmt->constraints == NIL);
758
759         /*
760          * Postprocess constraints that give rise to index definitions.
761          */
762         transformIndexConstraints(pstate, &cxt);
763
764         /*
765          * Postprocess foreign-key constraints.
766          */
767         transformFKConstraints(pstate, &cxt);
768
769         /*
770          * Output results.
771          */
772         q = makeNode(Query);
773         q->commandType = CMD_UTILITY;
774         q->utilityStmt = (Node *) stmt;
775         stmt->tableElts = cxt.columns;
776         stmt->constraints = cxt.ckconstraints;
777         *extras_before = nconc (*extras_before, cxt.blist);
778         *extras_after = nconc (cxt.alist, *extras_after);
779
780         return q;
781 }
782
783 static void
784 transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
785                                                   ColumnDef *column)
786 {
787         bool            is_serial;
788         bool            saw_nullable;
789         Constraint *constraint;
790         List       *clist;
791         Ident      *key;
792
793         cxt->columns = lappend(cxt->columns, column);
794
795         /* Check for SERIAL pseudo-types */
796         is_serial = false;
797         if (length(column->typename->names) == 1)
798         {
799                 char       *typname = strVal(lfirst(column->typename->names));
800
801                 if (strcmp(typname, "serial") == 0 ||
802                         strcmp(typname, "serial4") == 0)
803                 {
804                         is_serial = true;
805                         column->typename->names = NIL;
806                         column->typename->typeid = INT4OID;
807                 }
808                 else if (strcmp(typname, "bigserial") == 0 ||
809                                  strcmp(typname, "serial8") == 0)
810                 {
811                         is_serial = true;
812                         column->typename->names = NIL;
813                         column->typename->typeid = INT8OID;
814                 }
815         }
816
817         /* Do necessary work on the column type declaration */
818         transformColumnType(pstate, column);
819
820         /* Special actions for SERIAL pseudo-types */
821         if (is_serial)
822         {
823                 char       *sname;
824                 char       *snamespace;
825                 char       *qstring;
826                 A_Const    *snamenode;
827                 FuncCall   *funccallnode;
828                 CreateSeqStmt *seqstmt;
829
830                 /*
831                  * Determine name and namespace to use for the sequence.
832                  */
833                 sname = makeObjectName(cxt->relation->relname, column->colname, "seq");
834                 snamespace = get_namespace_name(RangeVarGetCreationNamespace(cxt->relation));
835
836                 elog(NOTICE, "%s will create implicit sequence '%s' for SERIAL column '%s.%s'",
837                          cxt->stmtType, sname, cxt->relation->relname, column->colname);
838
839                 /*
840                  * Build a CREATE SEQUENCE command to create the sequence object,
841                  * and add it to the list of things to be done before this
842                  * CREATE/ALTER TABLE.
843                  */
844                 seqstmt = makeNode(CreateSeqStmt);
845                 seqstmt->sequence = makeRangeVar(snamespace, sname);
846                 seqstmt->options = NIL;
847
848                 cxt->blist = lappend(cxt->blist, seqstmt);
849
850                 /*
851                  * Create appropriate constraints for SERIAL.  We do this in full,
852                  * rather than shortcutting, so that we will detect any
853                  * conflicting constraints the user wrote (like a different
854                  * DEFAULT).
855                  *
856                  * Create an expression tree representing the function call
857                  * nextval('"sequencename"')
858                  */
859                 qstring = quote_qualified_identifier(snamespace, sname);
860                 snamenode = makeNode(A_Const);
861                 snamenode->val.type = T_String;
862                 snamenode->val.val.str = qstring;
863                 funccallnode = makeNode(FuncCall);
864                 funccallnode->funcname = SystemFuncName("nextval");
865                 funccallnode->args = makeList1(snamenode);
866                 funccallnode->agg_star = false;
867                 funccallnode->agg_distinct = false;
868
869                 constraint = makeNode(Constraint);
870                 constraint->contype = CONSTR_DEFAULT;
871                 constraint->name = sname;
872                 constraint->raw_expr = (Node *) funccallnode;
873                 constraint->cooked_expr = NULL;
874                 constraint->keys = NIL;
875                 column->constraints = lappend(column->constraints, constraint);
876
877                 constraint = makeNode(Constraint);
878                 constraint->contype = CONSTR_UNIQUE;
879                 constraint->name = NULL;        /* assign later */
880                 column->constraints = lappend(column->constraints, constraint);
881
882                 constraint = makeNode(Constraint);
883                 constraint->contype = CONSTR_NOTNULL;
884                 column->constraints = lappend(column->constraints, constraint);
885         }
886
887         /* Process column constraints, if any... */
888         transformConstraintAttrs(column->constraints);
889
890         saw_nullable = false;
891
892         foreach(clist, column->constraints)
893         {
894                 constraint = lfirst(clist);
895
896                 /*
897                  * If this column constraint is a FOREIGN KEY constraint, then we
898                  * fill in the current attributes name and throw it into the list
899                  * of FK constraints to be processed later.
900                  */
901                 if (IsA(constraint, FkConstraint))
902                 {
903                         FkConstraint *fkconstraint = (FkConstraint *) constraint;
904                         Ident      *id = makeNode(Ident);
905
906                         id->name = column->colname;
907                         fkconstraint->fk_attrs = makeList1(id);
908
909                         cxt->fkconstraints = lappend(cxt->fkconstraints, fkconstraint);
910                         continue;
911                 }
912
913                 Assert(IsA(constraint, Constraint));
914
915                 switch (constraint->contype)
916                 {
917                         case CONSTR_NULL:
918                                 if (saw_nullable && column->is_not_null)
919                                         elog(ERROR, "%s/(NOT) NULL conflicting declaration for '%s.%s'",
920                                                  cxt->stmtType, (cxt->relation)->relname, column->colname);
921                                 column->is_not_null = FALSE;
922                                 saw_nullable = true;
923                                 break;
924
925                         case CONSTR_NOTNULL:
926                                 if (saw_nullable && !column->is_not_null)
927                                         elog(ERROR, "%s/(NOT) NULL conflicting declaration for '%s.%s'",
928                                                  cxt->stmtType, (cxt->relation)->relname, column->colname);
929                                 column->is_not_null = TRUE;
930                                 saw_nullable = true;
931                                 break;
932
933                         case CONSTR_DEFAULT:
934                                 if (column->raw_default != NULL)
935                                         elog(ERROR, "%s/DEFAULT multiple values specified for '%s.%s'",
936                                                  cxt->stmtType, (cxt->relation)->relname, column->colname);
937                                 column->raw_default = constraint->raw_expr;
938                                 Assert(constraint->cooked_expr == NULL);
939                                 break;
940
941                         case CONSTR_PRIMARY:
942                                 if (constraint->name == NULL)
943                                         constraint->name = makeObjectName((cxt->relation)->relname,
944                                                                                                           NULL,
945                                                                                                           "pkey");
946                                 if (constraint->keys == NIL)
947                                 {
948                                         key = makeNode(Ident);
949                                         key->name = pstrdup(column->colname);
950                                         constraint->keys = makeList1(key);
951                                 }
952                                 cxt->ixconstraints = lappend(cxt->ixconstraints, constraint);
953                                 break;
954
955                         case CONSTR_UNIQUE:
956                                 if (constraint->name == NULL)
957                                         constraint->name = makeObjectName((cxt->relation)->relname,
958                                                                                                           column->colname,
959                                                                                                           "key");
960                                 if (constraint->keys == NIL)
961                                 {
962                                         key = makeNode(Ident);
963                                         key->name = pstrdup(column->colname);
964                                         constraint->keys = makeList1(key);
965                                 }
966                                 cxt->ixconstraints = lappend(cxt->ixconstraints, constraint);
967                                 break;
968
969                         case CONSTR_CHECK:
970                                 if (constraint->name == NULL)
971                                         constraint->name = makeObjectName((cxt->relation)->relname,
972                                                                                                           column->colname,
973                                                                                                           NULL);
974                                 cxt->ckconstraints = lappend(cxt->ckconstraints, constraint);
975                                 break;
976
977                         case CONSTR_ATTR_DEFERRABLE:
978                         case CONSTR_ATTR_NOT_DEFERRABLE:
979                         case CONSTR_ATTR_DEFERRED:
980                         case CONSTR_ATTR_IMMEDIATE:
981                                 /* transformConstraintAttrs took care of these */
982                                 break;
983
984                         default:
985                                 elog(ERROR, "parser: unrecognized constraint (internal error)");
986                                 break;
987                 }
988         }
989 }
990
991 static void
992 transformTableConstraint(ParseState *pstate, CreateStmtContext *cxt,
993                                                  Constraint *constraint)
994 {
995         switch (constraint->contype)
996         {
997                 case CONSTR_PRIMARY:
998                         if (constraint->name == NULL)
999                                 constraint->name = makeObjectName((cxt->relation)->relname,
1000                                                                                                   NULL,
1001                                                                                                   "pkey");
1002                         cxt->ixconstraints = lappend(cxt->ixconstraints, constraint);
1003                         break;
1004
1005                 case CONSTR_UNIQUE:
1006                         cxt->ixconstraints = lappend(cxt->ixconstraints, constraint);
1007                         break;
1008
1009                 case CONSTR_CHECK:
1010                         cxt->ckconstraints = lappend(cxt->ckconstraints, constraint);
1011                         break;
1012
1013                 case CONSTR_NULL:
1014                 case CONSTR_NOTNULL:
1015                 case CONSTR_DEFAULT:
1016                 case CONSTR_ATTR_DEFERRABLE:
1017                 case CONSTR_ATTR_NOT_DEFERRABLE:
1018                 case CONSTR_ATTR_DEFERRED:
1019                 case CONSTR_ATTR_IMMEDIATE:
1020                         elog(ERROR, "parser: illegal context for constraint (internal error)");
1021                         break;
1022
1023                 default:
1024                         elog(ERROR, "parser: unrecognized constraint (internal error)");
1025                         break;
1026         }
1027 }
1028
1029 static void
1030 transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
1031 {
1032         List       *listptr;
1033         List       *keys;
1034         IndexStmt  *index;
1035         IndexElem  *iparam;
1036         ColumnDef  *column;
1037         List       *columns;
1038         List       *indexlist = NIL;
1039
1040         /*
1041          * Run through the constraints that need to generate an index. For
1042          * PRIMARY KEY, mark each column as NOT NULL and create an index. For
1043          * UNIQUE, create an index as for PRIMARY KEY, but do not insist on
1044          * NOT NULL.
1045          */
1046         foreach(listptr, cxt->ixconstraints)
1047         {
1048                 Constraint *constraint = lfirst(listptr);
1049
1050                 Assert(IsA(constraint, Constraint));
1051                 Assert((constraint->contype == CONSTR_PRIMARY)
1052                            || (constraint->contype == CONSTR_UNIQUE));
1053
1054                 index = makeNode(IndexStmt);
1055
1056                 index->unique = true;
1057                 index->primary = (constraint->contype == CONSTR_PRIMARY);
1058                 if (index->primary)
1059                 {
1060                         /* In ALTER TABLE case, a primary index might already exist */
1061                         if (cxt->pkey != NULL ||
1062                                 (OidIsValid(cxt->relOid) &&
1063                                  relationHasPrimaryKey(cxt->relOid)))
1064                                 elog(ERROR, "%s / PRIMARY KEY multiple primary keys"
1065                                          " for table '%s' are not allowed",
1066                                          cxt->stmtType, (cxt->relation)->relname);
1067                         cxt->pkey = index;
1068                 }
1069                 index->isconstraint = true;
1070
1071                 if (constraint->name != NULL)
1072                         index->idxname = pstrdup(constraint->name);
1073                 else if (constraint->contype == CONSTR_PRIMARY)
1074                         index->idxname = makeObjectName((cxt->relation)->relname, NULL, "pkey");
1075                 else
1076                         index->idxname = NULL;          /* will set it later */
1077
1078                 index->relation = cxt->relation;
1079                 index->accessMethod = DEFAULT_INDEX_TYPE;
1080                 index->indexParams = NIL;
1081                 index->whereClause = NULL;
1082
1083                 /*
1084                  * Make sure referenced keys exist.  If we are making a PRIMARY
1085                  * KEY index, also make sure they are NOT NULL.
1086                  */
1087                 foreach(keys, constraint->keys)
1088                 {
1089                         Ident      *key = (Ident *) lfirst(keys);
1090                         bool            found = false;
1091
1092                         Assert(IsA(key, Ident));
1093                         column = NULL;
1094                         foreach(columns, cxt->columns)
1095                         {
1096                                 column = lfirst(columns);
1097                                 Assert(IsA(column, ColumnDef));
1098                                 if (strcmp(column->colname, key->name) == 0)
1099                                 {
1100                                         found = true;
1101                                         break;
1102                                 }
1103                         }
1104                         if (found)
1105                         {
1106                                 /* found column in the new table; force it to be NOT NULL */
1107                                 if (constraint->contype == CONSTR_PRIMARY)
1108                                         column->is_not_null = TRUE;
1109                         }
1110                         else if (SystemAttributeByName(key->name, cxt->hasoids) != NULL)
1111                         {
1112                                 /*
1113                                  * column will be a system column in the new table, so
1114                                  * accept it.  System columns can't ever be null, so no
1115                                  * need to worry about PRIMARY/NOT NULL constraint.
1116                                  */
1117                                 found = true;
1118                         }
1119                         else if (cxt->inhRelations)
1120                         {
1121                                 /* try inherited tables */
1122                                 List       *inher;
1123
1124                                 foreach(inher, cxt->inhRelations)
1125                                 {
1126                                         RangeVar   *inh = lfirst(inher);
1127                                         Relation        rel;
1128                                         int                     count;
1129
1130                                         Assert(IsA(inh, RangeVar));
1131                                         rel = heap_openrv(inh, AccessShareLock);
1132                                         if (rel->rd_rel->relkind != RELKIND_RELATION)
1133                                                 elog(ERROR, "inherited table \"%s\" is not a relation",
1134                                                          inh->relname);
1135                                         for (count = 0; count < rel->rd_att->natts; count++)
1136                                         {
1137                                                 Form_pg_attribute inhattr = rel->rd_att->attrs[count];
1138                                                 char       *inhname = NameStr(inhattr->attname);
1139
1140                                                 if (strcmp(key->name, inhname) == 0)
1141                                                 {
1142                                                         found = true;
1143
1144                                                         /*
1145                                                          * If the column is inherited, we currently
1146                                                          * have no easy way to force it to be NOT
1147                                                          * NULL. Only way I can see to fix this would
1148                                                          * be to convert the inherited-column info to
1149                                                          * ColumnDef nodes before we reach this point,
1150                                                          * and then create the table from those nodes
1151                                                          * rather than referencing the parent tables
1152                                                          * later.  That would likely be cleaner, but
1153                                                          * too much work to contemplate right now.
1154                                                          * Instead, raise an error if the inherited
1155                                                          * column won't be NOT NULL. (Would a WARNING
1156                                                          * be more reasonable?)
1157                                                          */
1158                                                         if (constraint->contype == CONSTR_PRIMARY &&
1159                                                                 !inhattr->attnotnull)
1160                                                                 elog(ERROR, "inherited attribute \"%s\" cannot be a PRIMARY KEY because it is not marked NOT NULL",
1161                                                                          inhname);
1162                                                         break;
1163                                                 }
1164                                         }
1165                                         heap_close(rel, NoLock);
1166                                         if (found)
1167                                                 break;
1168                                 }
1169                         }
1170                         else if (OidIsValid(cxt->relOid))
1171                         {
1172                                 /* ALTER TABLE case: does column already exist? */
1173                                 HeapTuple       atttuple;
1174
1175                                 atttuple = SearchSysCache(ATTNAME,
1176                                                                                   ObjectIdGetDatum(cxt->relOid),
1177                                                                                   PointerGetDatum(key->name),
1178                                                                                   0, 0);
1179                                 if (HeapTupleIsValid(atttuple))
1180                                 {
1181                                         found = true;
1182
1183                                         /*
1184                                          * We require pre-existing column to be already marked
1185                                          * NOT NULL.
1186                                          */
1187                                         if (constraint->contype == CONSTR_PRIMARY &&
1188                                                 !((Form_pg_attribute) GETSTRUCT(atttuple))->attnotnull)
1189                                                 elog(ERROR, "Existing attribute \"%s\" cannot be a PRIMARY KEY because it is not marked NOT NULL",
1190                                                          key->name);
1191                                         ReleaseSysCache(atttuple);
1192                                 }
1193                         }
1194
1195                         if (!found)
1196                                 elog(ERROR, "%s: column \"%s\" named in key does not exist",
1197                                          cxt->stmtType, key->name);
1198
1199                         /* Check for PRIMARY KEY(foo, foo) */
1200                         foreach(columns, index->indexParams)
1201                         {
1202                                 iparam = (IndexElem *) lfirst(columns);
1203                                 if (iparam->name && strcmp(key->name, iparam->name) == 0)
1204                                         elog(ERROR, "%s: column \"%s\" appears twice in %s constraint",
1205                                                  cxt->stmtType, key->name,
1206                                                  index->primary ? "PRIMARY KEY" : "UNIQUE");
1207                         }
1208
1209                         /* OK, add it to the index definition */
1210                         iparam = makeNode(IndexElem);
1211                         iparam->name = pstrdup(key->name);
1212                         iparam->funcname = NIL;
1213                         iparam->args = NIL;
1214                         iparam->opclass = NIL;
1215                         index->indexParams = lappend(index->indexParams, iparam);
1216                 }
1217
1218                 indexlist = lappend(indexlist, index);
1219         }
1220
1221         /*
1222          * Scan the index list and remove any redundant index specifications.
1223          * This can happen if, for instance, the user writes SERIAL PRIMARY
1224          * KEY or SERIAL UNIQUE.  A strict reading of SQL92 would suggest
1225          * raising an error instead, but that strikes me as too
1226          * anal-retentive. - tgl 2001-02-14
1227          *
1228          * XXX in ALTER TABLE case, it'd be nice to look for duplicate
1229          * pre-existing indexes, too.
1230          */
1231         cxt->alist = NIL;
1232         if (cxt->pkey != NULL)
1233         {
1234                 /* Make sure we keep the PKEY index in preference to others... */
1235                 cxt->alist = makeList1(cxt->pkey);
1236         }
1237         while (indexlist != NIL)
1238         {
1239                 index = lfirst(indexlist);
1240
1241                 /* if it's pkey, it's already in cxt->alist */
1242                 if (index != cxt->pkey)
1243                 {
1244                         bool            keep = true;
1245                         List       *priorlist;
1246
1247                         foreach(priorlist, cxt->alist)
1248                         {
1249                                 IndexStmt  *priorindex = lfirst(priorlist);
1250
1251                                 if (equal(index->indexParams, priorindex->indexParams))
1252                                 {
1253                                         /*
1254                                          * If the prior index is as yet unnamed, and this one
1255                                          * is named, then transfer the name to the prior
1256                                          * index. This ensures that if we have named and
1257                                          * unnamed constraints, we'll use (at least one of)
1258                                          * the names for the index.
1259                                          */
1260                                         if (priorindex->idxname == NULL)
1261                                                 priorindex->idxname = index->idxname;
1262                                         keep = false;
1263                                         break;
1264                                 }
1265                         }
1266
1267                         if (keep)
1268                                 cxt->alist = lappend(cxt->alist, index);
1269                 }
1270
1271                 indexlist = lnext(indexlist);
1272         }
1273
1274         /*
1275          * Finally, select unique names for all not-previously-named indices,
1276          * and display WARNING messages.
1277          *
1278          * XXX in ALTER TABLE case, we fail to consider name collisions against
1279          * pre-existing indexes.
1280          */
1281         foreach(indexlist, cxt->alist)
1282         {
1283                 index = lfirst(indexlist);
1284
1285                 if (index->idxname == NULL && index->indexParams != NIL)
1286                 {
1287                         iparam = lfirst(index->indexParams);
1288                         index->idxname = CreateIndexName(cxt->relation->relname,
1289                                                                                          iparam->name ? iparam->name :
1290                                                                                          strVal(llast(iparam->funcname)),
1291                                                                                          "key", cxt->alist);
1292                 }
1293                 if (index->idxname == NULL)             /* should not happen */
1294                         elog(ERROR, "%s: failed to make implicit index name",
1295                                  cxt->stmtType);
1296
1297                 elog(NOTICE, "%s / %s%s will create implicit index '%s' for table '%s'",
1298                          cxt->stmtType,
1299                          (strcmp(cxt->stmtType, "ALTER TABLE") == 0) ? "ADD " : "",
1300                          (index->primary ? "PRIMARY KEY" : "UNIQUE"),
1301                          index->idxname, cxt->relation->relname);
1302         }
1303 }
1304
1305 static void
1306 transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt)
1307 {
1308         List       *fkactions = NIL;
1309         List       *fkclist;
1310
1311         if (cxt->fkconstraints == NIL)
1312                 return;
1313
1314         elog(NOTICE, "%s will create implicit trigger(s) for FOREIGN KEY check(s)",
1315                  cxt->stmtType);
1316
1317         foreach(fkclist, cxt->fkconstraints)
1318         {
1319                 FkConstraint *fkconstraint = (FkConstraint *) lfirst(fkclist);
1320                 Oid                     pktypoid[INDEX_MAX_KEYS];
1321                 Oid                     fktypoid[INDEX_MAX_KEYS];
1322                 int                     i;
1323                 int                     attnum;
1324                 List       *fkattrs;
1325
1326                 for (attnum = 0; attnum < INDEX_MAX_KEYS; attnum++)
1327                         pktypoid[attnum] = fktypoid[attnum] = InvalidOid;
1328
1329                 /*
1330                  * Look up the referencing attributes to make sure they exist (or
1331                  * will exist) in this table, and remember their type OIDs.
1332                  */
1333                 attnum = 0;
1334                 foreach(fkattrs, fkconstraint->fk_attrs)
1335                 {
1336                         Ident      *fkattr = lfirst(fkattrs);
1337
1338                         if (attnum >= INDEX_MAX_KEYS)
1339                                 elog(ERROR, "Can only have %d keys in a foreign key",
1340                                          INDEX_MAX_KEYS);
1341                         fktypoid[attnum++] = transformFkeyGetColType(cxt,
1342                                                                                                                  fkattr->name);
1343                 }
1344
1345                 /*
1346                  * If the attribute list for the referenced table was omitted,
1347                  * lookup the definition of the primary key.
1348                  */
1349                 if (fkconstraint->pk_attrs == NIL)
1350                 {
1351                         if (strcmp(fkconstraint->pktable->relname, (cxt->relation)->relname) != 0)
1352                                 transformFkeyGetPrimaryKey(fkconstraint, pktypoid);
1353                         else if (cxt->pkey != NULL)
1354                         {
1355                                 /* Use the to-be-created primary key */
1356                                 List       *attr;
1357
1358                                 attnum = 0;
1359                                 foreach(attr, cxt->pkey->indexParams)
1360                                 {
1361                                         IndexElem  *ielem = lfirst(attr);
1362                                         Ident      *pkattr = (Ident *) makeNode(Ident);
1363
1364                                         Assert(ielem->name); /* no func index here */
1365                                         pkattr->name = pstrdup(ielem->name);
1366                                         fkconstraint->pk_attrs = lappend(fkconstraint->pk_attrs,
1367                                                                                                          pkattr);
1368                                         if (attnum >= INDEX_MAX_KEYS)
1369                                                 elog(ERROR, "Can only have %d keys in a foreign key",
1370                                                          INDEX_MAX_KEYS);
1371                                         pktypoid[attnum++] = transformFkeyGetColType(cxt,
1372                                                                                                                         ielem->name);
1373                                 }
1374                         }
1375                         else
1376                         {
1377                                 /* In ALTER TABLE case, primary key may already exist */
1378                                 if (OidIsValid(cxt->relOid))
1379                                         transformFkeyGetPrimaryKey(fkconstraint, pktypoid);
1380                                 else
1381                                         elog(ERROR, "PRIMARY KEY for referenced table \"%s\" not found",
1382                                                  fkconstraint->pktable->relname);
1383                         }
1384                 }
1385                 else
1386                 {
1387                         /* Validate the specified referenced key list */
1388                         if (strcmp(fkconstraint->pktable->relname, (cxt->relation)->relname) != 0)
1389                                 transformFkeyCheckAttrs(fkconstraint, pktypoid);
1390                         else
1391                         {
1392                                 /* Look for a matching new unique/primary constraint */
1393                                 List       *index;
1394                                 bool            found = false;
1395
1396                                 foreach(index, cxt->alist)
1397                                 {
1398                                         IndexStmt  *ind = lfirst(index);
1399                                         List       *pkattrs;
1400
1401                                         if (!ind->unique)
1402                                                 continue;
1403                                         if (length(ind->indexParams) !=
1404                                                 length(fkconstraint->pk_attrs))
1405                                                 continue;
1406                                         attnum = 0;
1407                                         foreach(pkattrs, fkconstraint->pk_attrs)
1408                                         {
1409                                                 Ident      *pkattr = lfirst(pkattrs);
1410                                                 List       *indparms;
1411
1412                                                 found = false;
1413                                                 foreach(indparms, ind->indexParams)
1414                                                 {
1415                                                         IndexElem  *indparm = lfirst(indparms);
1416
1417                                                         if (indparm->name &&
1418                                                                 strcmp(indparm->name, pkattr->name) == 0)
1419                                                         {
1420                                                                 found = true;
1421                                                                 break;
1422                                                         }
1423                                                 }
1424                                                 if (!found)
1425                                                         break;
1426                                                 if (attnum >= INDEX_MAX_KEYS)
1427                                                         elog(ERROR, "Can only have %d keys in a foreign key",
1428                                                                  INDEX_MAX_KEYS);
1429                                                 pktypoid[attnum++] = transformFkeyGetColType(cxt,
1430                                                                                                                    pkattr->name);
1431                                         }
1432                                         if (found)
1433                                                 break;
1434                                 }
1435                                 if (!found)
1436                                 {
1437                                         /*
1438                                          * In ALTER TABLE case, such an index may already
1439                                          * exist
1440                                          */
1441                                         if (OidIsValid(cxt->relOid))
1442                                                 transformFkeyCheckAttrs(fkconstraint, pktypoid);
1443                                         else
1444                                                 elog(ERROR, "UNIQUE constraint matching given keys for referenced table \"%s\" not found",
1445                                                          fkconstraint->pktable->relname);
1446                                 }
1447                         }
1448                 }
1449
1450                 /* Be sure referencing and referenced column types are comparable */
1451                 for (i = 0; i < INDEX_MAX_KEYS && fktypoid[i] != 0; i++)
1452                 {
1453                         /*
1454                          * fktypoid[i] is the foreign key table's i'th element's type
1455                          * pktypoid[i] is the primary key table's i'th element's type
1456                          *
1457                          * We let oper() do our work for us, including elog(ERROR) if
1458                          * the types don't compare with =
1459                          */
1460                         Operator        o = oper(makeList1(makeString("=")),
1461                                                                  fktypoid[i], pktypoid[i], false);
1462
1463                         ReleaseSysCache(o);
1464                 }
1465
1466                 /*
1467                  * For ALTER TABLE ADD CONSTRAINT, we're done.  For CREATE TABLE,
1468                  * gin up an ALTER TABLE ADD CONSTRAINT command to execute after
1469                  * the basic CREATE TABLE is complete.
1470                  */
1471                 if (strcmp(cxt->stmtType, "CREATE TABLE") == 0)
1472                 {
1473                         AlterTableStmt *alterstmt = makeNode(AlterTableStmt);
1474
1475                         alterstmt->subtype = 'c'; /* preprocessed add constraint */
1476                         alterstmt->relation = cxt->relation;
1477                         alterstmt->name = NULL;
1478                         alterstmt->def = (Node *) makeList1(fkconstraint);
1479
1480                         /* Don't need to scan the table contents in this case */
1481                         fkconstraint->skip_validation = true;
1482
1483                         fkactions = lappend(fkactions, (Node *) alterstmt);
1484                 }
1485         }
1486
1487         /*
1488          * Attach completed list of extra actions to cxt->alist.  We cannot do
1489          * this earlier, because we assume above that cxt->alist still holds
1490          * only IndexStmts.
1491          */
1492         cxt->alist = nconc(cxt->alist, fkactions);
1493 }
1494
1495 /*
1496  * transformIndexStmt -
1497  *        transforms the qualification of the index statement
1498  */
1499 static Query *
1500 transformIndexStmt(ParseState *pstate, IndexStmt *stmt)
1501 {
1502         Query      *qry;
1503         RangeTblEntry *rte;
1504
1505         qry = makeNode(Query);
1506         qry->commandType = CMD_UTILITY;
1507
1508         /* take care of the where clause */
1509         if (stmt->whereClause)
1510         {
1511                 /*
1512                  * Put the parent table into the rtable so that the WHERE clause
1513                  * can refer to its fields without qualification.  Note that this
1514                  * only works if the parent table already exists --- so we can't
1515                  * easily support predicates on indexes created implicitly by
1516                  * CREATE TABLE. Fortunately, that's not necessary.
1517                  */
1518                 rte = addRangeTableEntry(pstate, stmt->relation, NULL, false, true);
1519
1520                 /* no to join list, yes to namespace */
1521                 addRTEtoQuery(pstate, rte, false, true);
1522
1523                 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
1524         }
1525
1526         qry->hasSubLinks = pstate->p_hasSubLinks;
1527         stmt->rangetable = pstate->p_rtable;
1528
1529         qry->utilityStmt = (Node *) stmt;
1530
1531         return qry;
1532 }
1533
1534 /*
1535  * transformRuleStmt -
1536  *        transform a Create Rule Statement. The actions is a list of parse
1537  *        trees which is transformed into a list of query trees.
1538  */
1539 static Query *
1540 transformRuleStmt(ParseState *pstate, RuleStmt *stmt,
1541                                 List **extras_before, List **extras_after)
1542 {
1543         Query      *qry;
1544         RangeTblEntry *oldrte;
1545         RangeTblEntry *newrte;
1546
1547         qry = makeNode(Query);
1548         qry->commandType = CMD_UTILITY;
1549         qry->utilityStmt = (Node *) stmt;
1550
1551         /*
1552          * To avoid deadlock, make sure the first thing we do is grab
1553          * AccessExclusiveLock on the target relation.  This will be needed by
1554          * DefineQueryRewrite(), and we don't want to grab a lesser lock
1555          * beforehand.  We don't need to hold a refcount on the relcache
1556          * entry, however.
1557          */
1558         heap_close(heap_openrv(stmt->relation, AccessExclusiveLock),
1559                            NoLock);
1560
1561         /*
1562          * NOTE: 'OLD' must always have a varno equal to 1 and 'NEW' equal to
1563          * 2.  Set up their RTEs in the main pstate for use in parsing the
1564          * rule qualification.
1565          */
1566         Assert(pstate->p_rtable == NIL);
1567         oldrte = addRangeTableEntry(pstate, stmt->relation,
1568                                                                 makeAlias("*OLD*", NIL),
1569                                                                 false, true);
1570         newrte = addRangeTableEntry(pstate, stmt->relation,
1571                                                                 makeAlias("*NEW*", NIL),
1572                                                                 false, true);
1573         /* Must override addRangeTableEntry's default access-check flags */
1574         oldrte->checkForRead = false;
1575         newrte->checkForRead = false;
1576
1577         /*
1578          * They must be in the namespace too for lookup purposes, but only add
1579          * the one(s) that are relevant for the current kind of rule.  In an
1580          * UPDATE rule, quals must refer to OLD.field or NEW.field to be
1581          * unambiguous, but there's no need to be so picky for INSERT &
1582          * DELETE. (Note we marked the RTEs "inFromCl = true" above to allow
1583          * unqualified references to their fields.)  We do not add them to the
1584          * joinlist.
1585          */
1586         switch (stmt->event)
1587         {
1588                 case CMD_SELECT:
1589                         addRTEtoQuery(pstate, oldrte, false, true);
1590                         break;
1591                 case CMD_UPDATE:
1592                         addRTEtoQuery(pstate, oldrte, false, true);
1593                         addRTEtoQuery(pstate, newrte, false, true);
1594                         break;
1595                 case CMD_INSERT:
1596                         addRTEtoQuery(pstate, newrte, false, true);
1597                         break;
1598                 case CMD_DELETE:
1599                         addRTEtoQuery(pstate, oldrte, false, true);
1600                         break;
1601                 default:
1602                         elog(ERROR, "transformRuleStmt: unexpected event type %d",
1603                                  (int) stmt->event);
1604                         break;
1605         }
1606
1607         /* take care of the where clause */
1608         stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
1609
1610         if (length(pstate->p_rtable) != 2)      /* naughty, naughty... */
1611                 elog(ERROR, "Rule WHERE condition may not contain references to other relations");
1612
1613         /* save info about sublinks in where clause */
1614         qry->hasSubLinks = pstate->p_hasSubLinks;
1615
1616         /*
1617          * 'instead nothing' rules with a qualification need a query
1618          * rangetable so the rewrite handler can add the negated rule
1619          * qualification to the original query. We create a query with the new
1620          * command type CMD_NOTHING here that is treated specially by the
1621          * rewrite system.
1622          */
1623         if (stmt->actions == NIL)
1624         {
1625                 Query      *nothing_qry = makeNode(Query);
1626
1627                 nothing_qry->commandType = CMD_NOTHING;
1628                 nothing_qry->rtable = pstate->p_rtable;
1629                 nothing_qry->jointree = makeFromExpr(NIL, NULL);                /* no join wanted */
1630
1631                 stmt->actions = makeList1(nothing_qry);
1632         }
1633         else
1634         {
1635                 List       *oldactions;
1636                 List       *newactions = NIL;
1637
1638                 /*
1639                  * transform each statement, like parse_analyze()
1640                  */
1641                 foreach(oldactions, stmt->actions)
1642                 {
1643                         Node       *action = (Node *) lfirst(oldactions);
1644                         ParseState *sub_pstate = make_parsestate(pstate->parentParseState);
1645                         Query      *sub_qry,
1646                                            *top_subqry;
1647                         bool            has_old,
1648                                                 has_new;
1649
1650                         /*
1651                          * Set up OLD/NEW in the rtable for this statement.  The
1652                          * entries are marked not inFromCl because we don't want them
1653                          * to be referred to by unqualified field names nor "*" in the
1654                          * rule actions.  We must add them to the namespace, however,
1655                          * or they won't be accessible at all.  We decide later
1656                          * whether to put them in the joinlist.
1657                          */
1658                         oldrte = addRangeTableEntry(sub_pstate, stmt->relation,
1659                                                                                 makeAlias("*OLD*", NIL),
1660                                                                                 false, false);
1661                         newrte = addRangeTableEntry(sub_pstate, stmt->relation,
1662                                                                                 makeAlias("*NEW*", NIL),
1663                                                                                 false, false);
1664                         oldrte->checkForRead = false;
1665                         newrte->checkForRead = false;
1666                         addRTEtoQuery(sub_pstate, oldrte, false, true);
1667                         addRTEtoQuery(sub_pstate, newrte, false, true);
1668
1669                         /* Transform the rule action statement */
1670                         top_subqry = transformStmt(sub_pstate, action,
1671                                                                 extras_before, extras_after);
1672
1673                         /*
1674                          * We cannot support utility-statement actions (eg NOTIFY)
1675                          * with nonempty rule WHERE conditions, because there's no way
1676                          * to make the utility action execute conditionally.
1677                          */
1678                         if (top_subqry->commandType == CMD_UTILITY &&
1679                                 stmt->whereClause != NULL)
1680                                 elog(ERROR, "Rules with WHERE conditions may only have SELECT, INSERT, UPDATE, or DELETE actions");
1681
1682                         /*
1683                          * If the action is INSERT...SELECT, OLD/NEW have been pushed
1684                          * down into the SELECT, and that's what we need to look at.
1685                          * (Ugly kluge ... try to fix this when we redesign
1686                          * querytrees.)
1687                          */
1688                         sub_qry = getInsertSelectQuery(top_subqry, NULL);
1689
1690                         /*
1691                          * Validate action's use of OLD/NEW, qual too
1692                          */
1693                         has_old =
1694                                 rangeTableEntry_used((Node *) sub_qry, PRS2_OLD_VARNO, 0) ||
1695                                 rangeTableEntry_used(stmt->whereClause, PRS2_OLD_VARNO, 0);
1696                         has_new =
1697                                 rangeTableEntry_used((Node *) sub_qry, PRS2_NEW_VARNO, 0) ||
1698                                 rangeTableEntry_used(stmt->whereClause, PRS2_NEW_VARNO, 0);
1699
1700                         switch (stmt->event)
1701                         {
1702                                 case CMD_SELECT:
1703                                         if (has_old)
1704                                                 elog(ERROR, "ON SELECT rule may not use OLD");
1705                                         if (has_new)
1706                                                 elog(ERROR, "ON SELECT rule may not use NEW");
1707                                         break;
1708                                 case CMD_UPDATE:
1709                                         /* both are OK */
1710                                         break;
1711                                 case CMD_INSERT:
1712                                         if (has_old)
1713                                                 elog(ERROR, "ON INSERT rule may not use OLD");
1714                                         break;
1715                                 case CMD_DELETE:
1716                                         if (has_new)
1717                                                 elog(ERROR, "ON DELETE rule may not use NEW");
1718                                         break;
1719                                 default:
1720                                         elog(ERROR, "transformRuleStmt: unexpected event type %d",
1721                                                  (int) stmt->event);
1722                                         break;
1723                         }
1724
1725                         /*
1726                          * For efficiency's sake, add OLD to the rule action's
1727                          * jointree only if it was actually referenced in the
1728                          * statement or qual.
1729                          *
1730                          * For INSERT, NEW is not really a relation (only a reference to
1731                          * the to-be-inserted tuple) and should never be added to the
1732                          * jointree.
1733                          *
1734                          * For UPDATE, we treat NEW as being another kind of reference to
1735                          * OLD, because it represents references to *transformed*
1736                          * tuples of the existing relation.  It would be wrong to
1737                          * enter NEW separately in the jointree, since that would
1738                          * cause a double join of the updated relation.  It's also
1739                          * wrong to fail to make a jointree entry if only NEW and not
1740                          * OLD is mentioned.
1741                          */
1742                         if (has_old || (has_new && stmt->event == CMD_UPDATE))
1743                         {
1744                                 /* hack so we can use addRTEtoQuery() */
1745                                 sub_pstate->p_rtable = sub_qry->rtable;
1746                                 sub_pstate->p_joinlist = sub_qry->jointree->fromlist;
1747                                 addRTEtoQuery(sub_pstate, oldrte, true, false);
1748                                 sub_qry->jointree->fromlist = sub_pstate->p_joinlist;
1749                         }
1750
1751                         newactions = lappend(newactions, top_subqry);
1752
1753                         release_pstate_resources(sub_pstate);
1754                         pfree(sub_pstate);
1755                 }
1756
1757                 stmt->actions = newactions;
1758         }
1759
1760         return qry;
1761 }
1762
1763
1764 /*
1765  * transformSelectStmt -
1766  *        transforms a Select Statement
1767  *
1768  * Note: this is also used for DECLARE CURSOR statements.
1769  */
1770 static Query *
1771 transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
1772 {
1773         Query      *qry = makeNode(Query);
1774         Node       *qual;
1775
1776         qry->commandType = CMD_SELECT;
1777
1778         if (stmt->portalname)
1779         {
1780                 /* DECLARE CURSOR */
1781                 if (stmt->into)
1782                         elog(ERROR, "DECLARE CURSOR must not specify INTO");
1783                 if (stmt->forUpdate)
1784                         elog(ERROR, "DECLARE/UPDATE is not supported"
1785                                  "\n\tCursors must be READ ONLY");
1786
1787                 /*
1788                  * 15 august 1991 -- since 3.0 postgres does locking right, we
1789                  * discovered that portals were violating locking protocol. portal
1790                  * locks cannot span xacts. as a short-term fix, we installed the
1791                  * check here. -- mao
1792                  */
1793                 if (!IsTransactionBlock())
1794                         elog(ERROR, "DECLARE CURSOR may only be used in begin/end transaction blocks");
1795
1796                 qry->into = makeNode(RangeVar);
1797                 qry->into->relname = stmt->portalname;
1798                 qry->isPortal = TRUE;
1799                 qry->isBinary = stmt->binary;   /* internal portal */
1800         }
1801         else
1802         {
1803                 /* SELECT */
1804                 qry->into = stmt->into;
1805                 qry->isPortal = FALSE;
1806                 qry->isBinary = FALSE;
1807         }
1808
1809         /* make FOR UPDATE clause available to addRangeTableEntry */
1810         pstate->p_forUpdate = stmt->forUpdate;
1811
1812         /* process the FROM clause */
1813         transformFromClause(pstate, stmt->fromClause);
1814
1815         /* transform targetlist */
1816         qry->targetList = transformTargetList(pstate, stmt->targetList);
1817
1818         if (stmt->intoColNames)
1819                 applyColumnNames(qry->targetList, stmt->intoColNames);
1820
1821         /* transform WHERE */
1822         qual = transformWhereClause(pstate, stmt->whereClause);
1823
1824         /*
1825          * Initial processing of HAVING clause is just like WHERE clause.
1826          * Additional work will be done in optimizer/plan/planner.c.
1827          */
1828         qry->havingQual = transformWhereClause(pstate, stmt->havingClause);
1829
1830         qry->groupClause = transformGroupClause(pstate,
1831                                                                                         stmt->groupClause,
1832                                                                                         qry->targetList);
1833
1834         qry->sortClause = transformSortClause(pstate,
1835                                                                                   stmt->sortClause,
1836                                                                                   qry->targetList);
1837
1838         qry->distinctClause = transformDistinctClause(pstate,
1839                                                                                                   stmt->distinctClause,
1840                                                                                                   qry->targetList,
1841                                                                                                   &qry->sortClause);
1842
1843         qry->limitOffset = stmt->limitOffset;
1844         qry->limitCount = stmt->limitCount;
1845
1846         qry->hasSubLinks = pstate->p_hasSubLinks;
1847         qry->hasAggs = pstate->p_hasAggs;
1848         if (pstate->p_hasAggs || qry->groupClause || qry->havingQual)
1849                 parseCheckAggregates(pstate, qry, qual);
1850
1851         qry->rtable = pstate->p_rtable;
1852         qry->jointree = makeFromExpr(pstate->p_joinlist, qual);
1853
1854         if (stmt->forUpdate != NIL)
1855                 transformForUpdate(qry, stmt->forUpdate);
1856
1857         return qry;
1858 }
1859
1860 /*
1861  * transformSetOperationsStmt -
1862  *        transforms a set-operations tree
1863  *
1864  * A set-operation tree is just a SELECT, but with UNION/INTERSECT/EXCEPT
1865  * structure to it.  We must transform each leaf SELECT and build up a top-
1866  * level Query that contains the leaf SELECTs as subqueries in its rangetable.
1867  * The tree of set operations is converted into the setOperations field of
1868  * the top-level Query.
1869  */
1870 static Query *
1871 transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
1872 {
1873         Query      *qry = makeNode(Query);
1874         SelectStmt *leftmostSelect;
1875         int                     leftmostRTI;
1876         Query      *leftmostQuery;
1877         SetOperationStmt *sostmt;
1878         RangeVar   *into;
1879         List       *intoColNames;
1880         char       *portalname;
1881         bool            binary;
1882         List       *sortClause;
1883         Node       *limitOffset;
1884         Node       *limitCount;
1885         List       *forUpdate;
1886         Node       *node;
1887         List       *lefttl,
1888                            *dtlist,
1889                            *targetvars,
1890                            *targetnames,
1891                            *sv_namespace,
1892                            *sv_rtable;
1893         RangeTblEntry *jrte;
1894         RangeTblRef *jrtr;
1895         int                     tllen;
1896
1897         qry->commandType = CMD_SELECT;
1898
1899         /*
1900          * Find leftmost leaf SelectStmt; extract the one-time-only items from
1901          * it and from the top-level node.
1902          */
1903         leftmostSelect = stmt->larg;
1904         while (leftmostSelect && leftmostSelect->op != SETOP_NONE)
1905                 leftmostSelect = leftmostSelect->larg;
1906         Assert(leftmostSelect && IsA(leftmostSelect, SelectStmt) &&
1907                    leftmostSelect->larg == NULL);
1908         into = leftmostSelect->into;
1909         intoColNames = leftmostSelect->intoColNames;
1910         portalname = stmt->portalname;
1911         binary = stmt->binary;
1912
1913         /* clear them to prevent complaints in transformSetOperationTree() */
1914         leftmostSelect->into = NULL;
1915         leftmostSelect->intoColNames = NIL;
1916         stmt->portalname = NULL;
1917         stmt->binary = false;
1918
1919         /*
1920          * These are not one-time, exactly, but we want to process them here
1921          * and not let transformSetOperationTree() see them --- else it'll
1922          * just recurse right back here!
1923          */
1924         sortClause = stmt->sortClause;
1925         limitOffset = stmt->limitOffset;
1926         limitCount = stmt->limitCount;
1927         forUpdate = stmt->forUpdate;
1928
1929         stmt->sortClause = NIL;
1930         stmt->limitOffset = NULL;
1931         stmt->limitCount = NULL;
1932         stmt->forUpdate = NIL;
1933
1934         /* We don't support forUpdate with set ops at the moment. */
1935         if (forUpdate)
1936                 elog(ERROR, "SELECT FOR UPDATE is not allowed with UNION/INTERSECT/EXCEPT");
1937
1938         /*
1939          * Recursively transform the components of the tree.
1940          */
1941         sostmt = (SetOperationStmt *) transformSetOperationTree(pstate, stmt);
1942         Assert(sostmt && IsA(sostmt, SetOperationStmt));
1943         qry->setOperations = (Node *) sostmt;
1944
1945         /*
1946          * Re-find leftmost SELECT (now it's a sub-query in rangetable)
1947          */
1948         node = sostmt->larg;
1949         while (node && IsA(node, SetOperationStmt))
1950                 node = ((SetOperationStmt *) node)->larg;
1951         Assert(node && IsA(node, RangeTblRef));
1952         leftmostRTI = ((RangeTblRef *) node)->rtindex;
1953         leftmostQuery = rt_fetch(leftmostRTI, pstate->p_rtable)->subquery;
1954         Assert(leftmostQuery != NULL);
1955
1956         /*
1957          * Generate dummy targetlist for outer query using column names of
1958          * leftmost select and common datatypes of topmost set operation. Also
1959          * make lists of the dummy vars and their names for use in parsing
1960          * ORDER BY.
1961          */
1962         qry->targetList = NIL;
1963         targetvars = NIL;
1964         targetnames = NIL;
1965         lefttl = leftmostQuery->targetList;
1966         foreach(dtlist, sostmt->colTypes)
1967         {
1968                 Oid                     colType = (Oid) lfirsti(dtlist);
1969                 Resdom     *leftResdom = ((TargetEntry *) lfirst(lefttl))->resdom;
1970                 char       *colName = pstrdup(leftResdom->resname);
1971                 Resdom     *resdom;
1972                 Node       *expr;
1973
1974                 resdom = makeResdom((AttrNumber) pstate->p_last_resno++,
1975                                                         colType,
1976                                                         -1,
1977                                                         colName,
1978                                                         false);
1979                 expr = (Node *) makeVar(1,
1980                                                                 leftResdom->resno,
1981                                                                 colType,
1982                                                                 -1,
1983                                                                 0);
1984                 qry->targetList = lappend(qry->targetList,
1985                                                                   makeTargetEntry(resdom, expr));
1986                 targetvars = lappend(targetvars, expr);
1987                 targetnames = lappend(targetnames, makeString(colName));
1988                 lefttl = lnext(lefttl);
1989         }
1990
1991         /*
1992          * Insert one-time items into top-level query
1993          *
1994          * This needs to agree with transformSelectStmt!
1995          */
1996         if (portalname)
1997         {
1998                 /* DECLARE CURSOR */
1999                 if (into)
2000                         elog(ERROR, "DECLARE CURSOR must not specify INTO");
2001                 if (forUpdate)
2002                         elog(ERROR, "DECLARE/UPDATE is not supported"
2003                                  "\n\tCursors must be READ ONLY");
2004
2005                 /*
2006                  * 15 august 1991 -- since 3.0 postgres does locking right, we
2007                  * discovered that portals were violating locking protocol. portal
2008                  * locks cannot span xacts. as a short-term fix, we installed the
2009                  * check here. -- mao
2010                  */
2011                 if (!IsTransactionBlock())
2012                         elog(ERROR, "DECLARE CURSOR may only be used in begin/end transaction blocks");
2013
2014                 qry->into = makeNode(RangeVar);
2015                 qry->into->relname = portalname;
2016                 qry->isPortal = TRUE;
2017                 qry->isBinary = binary; /* internal portal */
2018         }
2019         else
2020         {
2021                 /* SELECT */
2022                 qry->into = into;
2023                 qry->isPortal = FALSE;
2024                 qry->isBinary = FALSE;
2025         }
2026
2027         /*
2028          * Any column names from CREATE TABLE AS need to be attached to both the
2029          * top level and the leftmost subquery.  We do not do this earlier
2030          * because we do *not* want the targetnames list to be affected.
2031          */
2032         if (intoColNames)
2033         {
2034                 applyColumnNames(qry->targetList, intoColNames);
2035                 applyColumnNames(leftmostQuery->targetList, intoColNames);
2036         }
2037
2038         /*
2039          * As a first step towards supporting sort clauses that are
2040          * expressions using the output columns, generate a namespace entry
2041          * that makes the output columns visible.  A Join RTE node is handy
2042          * for this, since we can easily control the Vars generated upon
2043          * matches.
2044          *
2045          * Note: we don't yet do anything useful with such cases, but at least
2046          * "ORDER BY upper(foo)" will draw the right error message rather than
2047          * "foo not found".
2048          */
2049         jrte = addRangeTableEntryForJoin(NULL,
2050                                                                          targetnames,
2051                                                                          JOIN_INNER,
2052                                                                          targetvars,
2053                                                                          NULL,
2054                                                                          true);
2055         jrtr = makeNode(RangeTblRef);
2056         jrtr->rtindex = 1;
2057
2058         sv_rtable = pstate->p_rtable;
2059         pstate->p_rtable = makeList1(jrte);
2060
2061         sv_namespace = pstate->p_namespace;
2062         pstate->p_namespace = makeList1(jrtr);
2063
2064         /*
2065          * For now, we don't support resjunk sort clauses on the output of a
2066          * setOperation tree --- you can only use the SQL92-spec options of
2067          * selecting an output column by name or number.  Enforce by checking
2068          * that transformSortClause doesn't add any items to tlist.
2069          */
2070         tllen = length(qry->targetList);
2071
2072         qry->sortClause = transformSortClause(pstate,
2073                                                                                   sortClause,
2074                                                                                   qry->targetList);
2075
2076         pstate->p_namespace = sv_namespace;
2077         pstate->p_rtable = sv_rtable;
2078
2079         if (tllen != length(qry->targetList))
2080                 elog(ERROR, "ORDER BY on a UNION/INTERSECT/EXCEPT result must be on one of the result columns");
2081
2082         qry->limitOffset = limitOffset;
2083         qry->limitCount = limitCount;
2084
2085         qry->hasSubLinks = pstate->p_hasSubLinks;
2086         qry->hasAggs = pstate->p_hasAggs;
2087         if (pstate->p_hasAggs || qry->groupClause || qry->havingQual)
2088                 parseCheckAggregates(pstate, qry, NULL);
2089
2090         qry->rtable = pstate->p_rtable;
2091         qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
2092
2093         if (forUpdate != NIL)
2094                 transformForUpdate(qry, forUpdate);
2095
2096         return qry;
2097 }
2098
2099 /*
2100  * transformSetOperationTree
2101  *              Recursively transform leaves and internal nodes of a set-op tree
2102  */
2103 static Node *
2104 transformSetOperationTree(ParseState *pstate, SelectStmt *stmt)
2105 {
2106         bool            isLeaf;
2107
2108         Assert(stmt && IsA(stmt, SelectStmt));
2109
2110         /*
2111          * Validity-check both leaf and internal SELECTs for disallowed ops.
2112          */
2113         if (stmt->into)
2114                 elog(ERROR, "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT");
2115         if (stmt->portalname)           /* should not happen */
2116                 elog(ERROR, "Portal may not appear in UNION/INTERSECT/EXCEPT");
2117         /* We don't support forUpdate with set ops at the moment. */
2118         if (stmt->forUpdate)
2119                 elog(ERROR, "SELECT FOR UPDATE is not allowed with UNION/INTERSECT/EXCEPT");
2120
2121         /*
2122          * If an internal node of a set-op tree has ORDER BY, UPDATE, or LIMIT
2123          * clauses attached, we need to treat it like a leaf node to generate
2124          * an independent sub-Query tree.  Otherwise, it can be represented by
2125          * a SetOperationStmt node underneath the parent Query.
2126          */
2127         if (stmt->op == SETOP_NONE)
2128         {
2129                 Assert(stmt->larg == NULL && stmt->rarg == NULL);
2130                 isLeaf = true;
2131         }
2132         else
2133         {
2134                 Assert(stmt->larg != NULL && stmt->rarg != NULL);
2135                 if (stmt->sortClause || stmt->limitOffset || stmt->limitCount ||
2136                         stmt->forUpdate)
2137                         isLeaf = true;
2138                 else
2139                         isLeaf = false;
2140         }
2141
2142         if (isLeaf)
2143         {
2144                 /* Process leaf SELECT */
2145                 List       *selectList;
2146                 Query      *selectQuery;
2147                 char            selectName[32];
2148                 RangeTblEntry *rte;
2149                 RangeTblRef *rtr;
2150
2151                 /*
2152                  * Transform SelectStmt into a Query.
2153                  *
2154                  * Note: previously transformed sub-queries don't affect the parsing
2155                  * of this sub-query, because they are not in the toplevel
2156                  * pstate's namespace list.
2157                  */
2158                 selectList = parse_analyze((Node *) stmt, pstate);
2159
2160                 Assert(length(selectList) == 1);
2161                 selectQuery = (Query *) lfirst(selectList);
2162
2163                 /*
2164                  * Make the leaf query be a subquery in the top-level rangetable.
2165                  */
2166                 sprintf(selectName, "*SELECT* %d", length(pstate->p_rtable) + 1);
2167                 rte = addRangeTableEntryForSubquery(pstate,
2168                                                                                         selectQuery,
2169                                                                                         makeAlias(selectName, NIL),
2170                                                                                         false);
2171
2172                 /*
2173                  * Return a RangeTblRef to replace the SelectStmt in the set-op
2174                  * tree.
2175                  */
2176                 rtr = makeNode(RangeTblRef);
2177                 /* assume new rte is at end */
2178                 rtr->rtindex = length(pstate->p_rtable);
2179                 Assert(rte == rt_fetch(rtr->rtindex, pstate->p_rtable));
2180                 return (Node *) rtr;
2181         }
2182         else
2183         {
2184                 /* Process an internal node (set operation node) */
2185                 SetOperationStmt *op = makeNode(SetOperationStmt);
2186                 List       *lcoltypes;
2187                 List       *rcoltypes;
2188                 const char *context;
2189
2190                 context = (stmt->op == SETOP_UNION ? "UNION" :
2191                                    (stmt->op == SETOP_INTERSECT ? "INTERSECT" :
2192                                         "EXCEPT"));
2193
2194                 op->op = stmt->op;
2195                 op->all = stmt->all;
2196
2197                 /*
2198                  * Recursively transform the child nodes.
2199                  */
2200                 op->larg = transformSetOperationTree(pstate, stmt->larg);
2201                 op->rarg = transformSetOperationTree(pstate, stmt->rarg);
2202
2203                 /*
2204                  * Verify that the two children have the same number of non-junk
2205                  * columns, and determine the types of the merged output columns.
2206                  */
2207                 lcoltypes = getSetColTypes(pstate, op->larg);
2208                 rcoltypes = getSetColTypes(pstate, op->rarg);
2209                 if (length(lcoltypes) != length(rcoltypes))
2210                         elog(ERROR, "Each %s query must have the same number of columns",
2211                                  context);
2212                 op->colTypes = NIL;
2213                 while (lcoltypes != NIL)
2214                 {
2215                         Oid                     lcoltype = (Oid) lfirsti(lcoltypes);
2216                         Oid                     rcoltype = (Oid) lfirsti(rcoltypes);
2217                         Oid                     rescoltype;
2218
2219                         rescoltype = select_common_type(makeListi2(lcoltype, rcoltype),
2220                                                                                         context);
2221                         op->colTypes = lappendi(op->colTypes, rescoltype);
2222                         lcoltypes = lnext(lcoltypes);
2223                         rcoltypes = lnext(rcoltypes);
2224                 }
2225
2226                 return (Node *) op;
2227         }
2228 }
2229
2230 /*
2231  * getSetColTypes
2232  *              Get output column types of an (already transformed) set-op node
2233  */
2234 static List *
2235 getSetColTypes(ParseState *pstate, Node *node)
2236 {
2237         if (IsA(node, RangeTblRef))
2238         {
2239                 RangeTblRef *rtr = (RangeTblRef *) node;
2240                 RangeTblEntry *rte = rt_fetch(rtr->rtindex, pstate->p_rtable);
2241                 Query      *selectQuery = rte->subquery;
2242                 List       *result = NIL;
2243                 List       *tl;
2244
2245                 Assert(selectQuery != NULL);
2246                 /* Get types of non-junk columns */
2247                 foreach(tl, selectQuery->targetList)
2248                 {
2249                         TargetEntry *tle = (TargetEntry *) lfirst(tl);
2250                         Resdom     *resnode = tle->resdom;
2251
2252                         if (resnode->resjunk)
2253                                 continue;
2254                         result = lappendi(result, resnode->restype);
2255                 }
2256                 return result;
2257         }
2258         else if (IsA(node, SetOperationStmt))
2259         {
2260                 SetOperationStmt *op = (SetOperationStmt *) node;
2261
2262                 /* Result already computed during transformation of node */
2263                 Assert(op->colTypes != NIL);
2264                 return op->colTypes;
2265         }
2266         else
2267         {
2268                 elog(ERROR, "getSetColTypes: unexpected node %d",
2269                          (int) nodeTag(node));
2270                 return NIL;                             /* keep compiler quiet */
2271         }
2272 }
2273
2274 /* Attach column names from a ColumnDef list to a TargetEntry list */
2275 static void
2276 applyColumnNames(List *dst, List *src)
2277 {
2278         if (length(src) > length(dst))
2279                 elog(ERROR, "CREATE TABLE AS specifies too many column names");
2280
2281         while (src != NIL && dst != NIL)
2282         {
2283                 TargetEntry *d = (TargetEntry *) lfirst(dst);
2284                 ColumnDef  *s = (ColumnDef *) lfirst(src);
2285
2286                 Assert(d->resdom && !d->resdom->resjunk);
2287
2288                 d->resdom->resname = pstrdup(s->colname);
2289
2290                 dst = lnext(dst);
2291                 src = lnext(src);
2292         }
2293 }
2294
2295
2296 /*
2297  * transformUpdateStmt -
2298  *        transforms an update statement
2299  */
2300 static Query *
2301 transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
2302 {
2303         Query      *qry = makeNode(Query);
2304         Node       *qual;
2305         List       *origTargetList;
2306         List       *tl;
2307
2308         qry->commandType = CMD_UPDATE;
2309         pstate->p_is_update = true;
2310
2311         qry->resultRelation = setTargetTable(pstate, stmt->relation,
2312                                                                                  interpretInhOption(stmt->relation->inhOpt),
2313                                                                                  true);
2314
2315         /*
2316          * the FROM clause is non-standard SQL syntax. We used to be able to
2317          * do this with REPLACE in POSTQUEL so we keep the feature.
2318          */
2319         transformFromClause(pstate, stmt->fromClause);
2320
2321         qry->targetList = transformTargetList(pstate, stmt->targetList);
2322
2323         qual = transformWhereClause(pstate, stmt->whereClause);
2324
2325         qry->rtable = pstate->p_rtable;
2326         qry->jointree = makeFromExpr(pstate->p_joinlist, qual);
2327
2328         qry->hasSubLinks = pstate->p_hasSubLinks;
2329         qry->hasAggs = pstate->p_hasAggs;
2330         if (pstate->p_hasAggs)
2331                 parseCheckAggregates(pstate, qry, qual);
2332
2333         /*
2334          * Now we are done with SELECT-like processing, and can get on with
2335          * transforming the target list to match the UPDATE target columns.
2336          */
2337
2338         /* Prepare to assign non-conflicting resnos to resjunk attributes */
2339         if (pstate->p_last_resno <= pstate->p_target_relation->rd_rel->relnatts)
2340                 pstate->p_last_resno = pstate->p_target_relation->rd_rel->relnatts + 1;
2341
2342         /* Prepare non-junk columns for assignment to target table */
2343         origTargetList = stmt->targetList;
2344         foreach(tl, qry->targetList)
2345         {
2346                 TargetEntry *tle = (TargetEntry *) lfirst(tl);
2347                 Resdom     *resnode = tle->resdom;
2348                 ResTarget  *origTarget;
2349
2350                 if (resnode->resjunk)
2351                 {
2352                         /*
2353                          * Resjunk nodes need no additional processing, but be sure
2354                          * they have names and resnos that do not match any target
2355                          * columns; else rewriter or planner might get confused.
2356                          */
2357                         resnode->resname = "?resjunk?";
2358                         resnode->resno = (AttrNumber) pstate->p_last_resno++;
2359                         continue;
2360                 }
2361                 if (origTargetList == NIL)
2362                         elog(ERROR, "UPDATE target count mismatch --- internal error");
2363                 origTarget = (ResTarget *) lfirst(origTargetList);
2364                 updateTargetListEntry(pstate, tle, origTarget->name,
2365                                                           attnameAttNum(pstate->p_target_relation,
2366                                                                                         origTarget->name),
2367                                                           origTarget->indirection);
2368                 origTargetList = lnext(origTargetList);
2369         }
2370         if (origTargetList != NIL)
2371                 elog(ERROR, "UPDATE target count mismatch --- internal error");
2372
2373         return qry;
2374 }
2375
2376 /*
2377  * tranformAlterTableStmt -
2378  *      transform an Alter Table Statement
2379  */
2380 static Query *
2381 transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt,
2382                                                 List **extras_before, List **extras_after)
2383 {
2384         CreateStmtContext cxt;
2385         Query      *qry;
2386
2387         /*
2388          * The only subtypes that currently require parse transformation
2389          * handling are 'A'dd column and Add 'C'onstraint.      These largely
2390          * re-use code from CREATE TABLE.
2391          */
2392         switch (stmt->subtype)
2393         {
2394                 case 'A':
2395                         cxt.stmtType = "ALTER TABLE";
2396                         cxt.relation = stmt->relation;
2397                         cxt.inhRelations = NIL;
2398                         cxt.relOid = RangeVarGetRelid(stmt->relation, false);
2399                         cxt.hasoids = SearchSysCacheExists(ATTNUM,
2400                                                                                         ObjectIdGetDatum(cxt.relOid),
2401                                                                   Int16GetDatum(ObjectIdAttributeNumber),
2402                                                                                            0, 0);
2403                         cxt.columns = NIL;
2404                         cxt.ckconstraints = NIL;
2405                         cxt.fkconstraints = NIL;
2406                         cxt.ixconstraints = NIL;
2407                         cxt.blist = NIL;
2408                         cxt.alist = NIL;
2409                         cxt.pkey = NULL;
2410
2411                         Assert(IsA(stmt->def, ColumnDef));
2412                         transformColumnDefinition(pstate, &cxt,
2413                                                                           (ColumnDef *) stmt->def);
2414
2415                         transformIndexConstraints(pstate, &cxt);
2416                         transformFKConstraints(pstate, &cxt);
2417
2418                         ((ColumnDef *) stmt->def)->constraints = cxt.ckconstraints;
2419                         *extras_before = nconc(*extras_before, cxt.blist);
2420                         *extras_after = nconc(cxt.alist, *extras_after);
2421                         break;
2422
2423                 case 'C':
2424                         cxt.stmtType = "ALTER TABLE";
2425                         cxt.relation = stmt->relation;
2426                         cxt.inhRelations = NIL;
2427                         cxt.relOid = RangeVarGetRelid(stmt->relation, false);
2428                         cxt.hasoids = SearchSysCacheExists(ATTNUM,
2429                                                                                         ObjectIdGetDatum(cxt.relOid),
2430                                                                   Int16GetDatum(ObjectIdAttributeNumber),
2431                                                                                            0, 0);
2432                         cxt.columns = NIL;
2433                         cxt.ckconstraints = NIL;
2434                         cxt.fkconstraints = NIL;
2435                         cxt.ixconstraints = NIL;
2436                         cxt.blist = NIL;
2437                         cxt.alist = NIL;
2438                         cxt.pkey = NULL;
2439
2440                         if (IsA(stmt->def, Constraint))
2441                                 transformTableConstraint(pstate, &cxt,
2442                                                                                  (Constraint *) stmt->def);
2443                         else if (IsA(stmt->def, FkConstraint))
2444                                 cxt.fkconstraints = lappend(cxt.fkconstraints, stmt->def);
2445                         else
2446                                 elog(ERROR, "Unexpected node type in ALTER TABLE ADD CONSTRAINT");
2447
2448                         transformIndexConstraints(pstate, &cxt);
2449                         transformFKConstraints(pstate, &cxt);
2450
2451                         Assert(cxt.columns == NIL);
2452                         stmt->def = (Node *) nconc(cxt.ckconstraints, cxt.fkconstraints);
2453                         *extras_before = nconc(*extras_before, cxt.blist);
2454                         *extras_after = nconc(cxt.alist, *extras_after);
2455                         break;
2456
2457                 case 'c':
2458                         /*
2459                          * Already-transformed ADD CONSTRAINT, so just make it look
2460                          * like the standard case.
2461                          */
2462                         stmt->subtype = 'C';
2463                         break;
2464
2465                 default:
2466                         break;
2467         }
2468
2469         qry = makeNode(Query);
2470         qry->commandType = CMD_UTILITY;
2471         qry->utilityStmt = (Node *) stmt;
2472
2473         return qry;
2474 }
2475
2476 /* exported so planner can check again after rewriting, query pullup, etc */
2477 void
2478 CheckSelectForUpdate(Query *qry)
2479 {
2480         if (qry->setOperations)
2481                 elog(ERROR, "SELECT FOR UPDATE is not allowed with UNION/INTERSECT/EXCEPT");
2482         if (qry->distinctClause != NIL)
2483                 elog(ERROR, "SELECT FOR UPDATE is not allowed with DISTINCT clause");
2484         if (qry->groupClause != NIL)
2485                 elog(ERROR, "SELECT FOR UPDATE is not allowed with GROUP BY clause");
2486         if (qry->hasAggs)
2487                 elog(ERROR, "SELECT FOR UPDATE is not allowed with AGGREGATE");
2488 }
2489
2490 static void
2491 transformForUpdate(Query *qry, List *forUpdate)
2492 {
2493         List       *rowMarks = qry->rowMarks;
2494         List       *l;
2495         List       *rt;
2496         Index           i;
2497
2498         CheckSelectForUpdate(qry);
2499
2500         if (lfirst(forUpdate) == NULL)
2501         {
2502                 /* all tables used in query */
2503                 i = 0;
2504                 foreach(rt, qry->rtable)
2505                 {
2506                         RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
2507
2508                         ++i;
2509                         if (rte->rtekind == RTE_SUBQUERY)
2510                         {
2511                                 /* FOR UPDATE of subquery is propagated to subquery's rels */
2512                                 transformForUpdate(rte->subquery, makeList1(NULL));
2513                         }
2514                         else
2515                         {
2516                                 if (!intMember(i, rowMarks))    /* avoid duplicates */
2517                                         rowMarks = lappendi(rowMarks, i);
2518                                 rte->checkForWrite = true;
2519                         }
2520                 }
2521         }
2522         else
2523         {
2524                 /* just the named tables */
2525                 foreach(l, forUpdate)
2526                 {
2527                         char       *relname = strVal(lfirst(l));
2528
2529                         i = 0;
2530                         foreach(rt, qry->rtable)
2531                         {
2532                                 RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
2533
2534                                 ++i;
2535                                 if (strcmp(rte->eref->aliasname, relname) == 0)
2536                                 {
2537                                         if (rte->rtekind == RTE_SUBQUERY)
2538                                         {
2539                                                 /* propagate to subquery */
2540                                                 transformForUpdate(rte->subquery, makeList1(NULL));
2541                                         }
2542                                         else
2543                                         {
2544                                                 if (!intMember(i, rowMarks))    /* avoid duplicates */
2545                                                         rowMarks = lappendi(rowMarks, i);
2546                                                 rte->checkForWrite = true;
2547                                         }
2548                                         break;
2549                                 }
2550                         }
2551                         if (rt == NIL)
2552                                 elog(ERROR, "FOR UPDATE: relation \"%s\" not found in FROM clause",
2553                                          relname);
2554                 }
2555         }
2556
2557         qry->rowMarks = rowMarks;
2558 }
2559
2560
2561 /*
2562  * transformFkeyCheckAttrs -
2563  *
2564  *      Make sure that the attributes of a referenced table
2565  *              belong to a unique (or primary key) constraint.
2566  */
2567 static void
2568 transformFkeyCheckAttrs(FkConstraint *fkconstraint, Oid *pktypoid)
2569 {
2570         Relation        pkrel;
2571         List       *indexoidlist,
2572                            *indexoidscan;
2573         int                     i;
2574         bool            found = false;
2575
2576         /*
2577          * Open the referenced table
2578          */
2579         pkrel = heap_openrv(fkconstraint->pktable, AccessShareLock);
2580
2581         if (pkrel->rd_rel->relkind != RELKIND_RELATION)
2582                 elog(ERROR, "Referenced relation \"%s\" is not a table",
2583                          fkconstraint->pktable->relname);
2584
2585         /*
2586          * Get the list of index OIDs for the table from the relcache, and
2587          * look up each one in the pg_index syscache for each unique one, and
2588          * then compare the attributes we were given to those defined.
2589          */
2590         indexoidlist = RelationGetIndexList(pkrel);
2591
2592         foreach(indexoidscan, indexoidlist)
2593         {
2594                 Oid                     indexoid = lfirsti(indexoidscan);
2595                 HeapTuple       indexTuple;
2596                 Form_pg_index indexStruct;
2597
2598                 found = false;
2599                 indexTuple = SearchSysCache(INDEXRELID,
2600                                                                         ObjectIdGetDatum(indexoid),
2601                                                                         0, 0, 0);
2602                 if (!HeapTupleIsValid(indexTuple))
2603                         elog(ERROR, "transformFkeyCheckAttrs: index %u not found",
2604                                  indexoid);
2605                 indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
2606
2607                 if (indexStruct->indisunique)
2608                 {
2609                         for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++)
2610                                 ;
2611                         if (i == length(fkconstraint->pk_attrs))
2612                         {
2613                                 /* go through the fkconstraint->pk_attrs list */
2614                                 List       *attrl;
2615                                 int                     attnum = 0;
2616
2617                                 foreach(attrl, fkconstraint->pk_attrs)
2618                                 {
2619                                         Ident      *attr = lfirst(attrl);
2620
2621                                         found = false;
2622                                         for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++)
2623                                         {
2624                                                 int                     pkattno = indexStruct->indkey[i];
2625
2626                                                 if (namestrcmp(attnumAttName(pkrel, pkattno),
2627                                                                            attr->name) == 0)
2628                                                 {
2629                                                         pktypoid[attnum++] = attnumTypeId(pkrel, pkattno);
2630                                                         found = true;
2631                                                         break;
2632                                                 }
2633                                         }
2634                                         if (!found)
2635                                                 break;
2636                                 }
2637                         }
2638                 }
2639                 ReleaseSysCache(indexTuple);
2640                 if (found)
2641                         break;
2642         }
2643         if (!found)
2644                 elog(ERROR, "UNIQUE constraint matching given keys for referenced table \"%s\" not found",
2645                          fkconstraint->pktable->relname);
2646
2647         freeList(indexoidlist);
2648         heap_close(pkrel, AccessShareLock);
2649 }
2650
2651
2652 /*
2653  * transformFkeyGetPrimaryKey -
2654  *
2655  *      Try to find the primary key attributes of a referenced table if
2656  *      the column list in the REFERENCES specification was omitted.
2657  */
2658 static void
2659 transformFkeyGetPrimaryKey(FkConstraint *fkconstraint, Oid *pktypoid)
2660 {
2661         Relation        pkrel;
2662         List       *indexoidlist,
2663                            *indexoidscan;
2664         HeapTuple       indexTuple = NULL;
2665         Form_pg_index indexStruct = NULL;
2666         int                     i;
2667         int                     attnum = 0;
2668
2669         /*
2670          * Open the referenced table
2671          */
2672         pkrel = heap_openrv(fkconstraint->pktable, AccessShareLock);
2673
2674         if (pkrel->rd_rel->relkind != RELKIND_RELATION)
2675                 elog(ERROR, "Referenced relation \"%s\" is not a table",
2676                          fkconstraint->pktable->relname);
2677
2678         /*
2679          * Get the list of index OIDs for the table from the relcache, and
2680          * look up each one in the pg_index syscache until we find one marked
2681          * primary key (hopefully there isn't more than one such).
2682          */
2683         indexoidlist = RelationGetIndexList(pkrel);
2684
2685         foreach(indexoidscan, indexoidlist)
2686         {
2687                 Oid                     indexoid = lfirsti(indexoidscan);
2688
2689                 indexTuple = SearchSysCache(INDEXRELID,
2690                                                                         ObjectIdGetDatum(indexoid),
2691                                                                         0, 0, 0);
2692                 if (!HeapTupleIsValid(indexTuple))
2693                         elog(ERROR, "transformFkeyGetPrimaryKey: index %u not found",
2694                                  indexoid);
2695                 indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
2696                 if (indexStruct->indisprimary)
2697                         break;
2698                 ReleaseSysCache(indexTuple);
2699                 indexStruct = NULL;
2700         }
2701
2702         freeList(indexoidlist);
2703
2704         /*
2705          * Check that we found it
2706          */
2707         if (indexStruct == NULL)
2708                 elog(ERROR, "PRIMARY KEY for referenced table \"%s\" not found",
2709                          fkconstraint->pktable->relname);
2710
2711         /*
2712          * Now build the list of PK attributes from the indkey definition
2713          * using the attribute names of the PK relation descriptor
2714          */
2715         for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++)
2716         {
2717                 int                     pkattno = indexStruct->indkey[i];
2718                 Ident      *pkattr = makeNode(Ident);
2719
2720                 pkattr->name = pstrdup(NameStr(*attnumAttName(pkrel, pkattno)));
2721                 pktypoid[attnum++] = attnumTypeId(pkrel, pkattno);
2722
2723                 fkconstraint->pk_attrs = lappend(fkconstraint->pk_attrs, pkattr);
2724         }
2725
2726         ReleaseSysCache(indexTuple);
2727
2728         heap_close(pkrel, AccessShareLock);
2729 }
2730
2731 /*
2732  * relationHasPrimaryKey -
2733  *
2734  *      See whether an existing relation has a primary key.
2735  */
2736 static bool
2737 relationHasPrimaryKey(Oid relationOid)
2738 {
2739         bool            result = false;
2740         Relation        rel;
2741         List       *indexoidlist,
2742                            *indexoidscan;
2743
2744         rel = heap_open(relationOid, AccessShareLock);
2745
2746         /*
2747          * Get the list of index OIDs for the table from the relcache, and
2748          * look up each one in the pg_index syscache until we find one marked
2749          * primary key (hopefully there isn't more than one such).
2750          */
2751         indexoidlist = RelationGetIndexList(rel);
2752
2753         foreach(indexoidscan, indexoidlist)
2754         {
2755                 Oid                     indexoid = lfirsti(indexoidscan);
2756                 HeapTuple       indexTuple;
2757
2758                 indexTuple = SearchSysCache(INDEXRELID,
2759                                                                         ObjectIdGetDatum(indexoid),
2760                                                                         0, 0, 0);
2761                 if (!HeapTupleIsValid(indexTuple))
2762                         elog(ERROR, "relationHasPrimaryKey: index %u not found",
2763                                  indexoid);
2764                 result = ((Form_pg_index) GETSTRUCT(indexTuple))->indisprimary;
2765                 ReleaseSysCache(indexTuple);
2766                 if (result)
2767                         break;
2768         }
2769
2770         freeList(indexoidlist);
2771
2772         heap_close(rel, AccessShareLock);
2773
2774         return result;
2775 }
2776
2777 /*
2778  * transformFkeyGetColType -
2779  *
2780  *      Find a referencing column by name, and return its type OID.
2781  *      Error if it can't be found.
2782  */
2783 static Oid
2784 transformFkeyGetColType(CreateStmtContext *cxt, char *colname)
2785 {
2786         List       *cols;
2787         List       *inher;
2788         Oid                     result;
2789         Form_pg_attribute sysatt;
2790
2791         /* First look for column among the newly-created columns */
2792         foreach(cols, cxt->columns)
2793         {
2794                 ColumnDef  *col = lfirst(cols);
2795
2796                 if (strcmp(col->colname, colname) == 0)
2797                         return typenameTypeId(col->typename);
2798         }
2799         /* Perhaps it's a system column name */
2800         sysatt = SystemAttributeByName(colname, cxt->hasoids);
2801         if (sysatt)
2802                 return sysatt->atttypid;
2803         /* Look for column among inherited columns (if CREATE TABLE case) */
2804         foreach(inher, cxt->inhRelations)
2805         {
2806                 RangeVar   *inh = lfirst(inher);
2807                 Relation        rel;
2808                 int                     count;
2809
2810                 Assert(IsA(inh, RangeVar));
2811                 rel = heap_openrv(inh, AccessShareLock);
2812                 if (rel->rd_rel->relkind != RELKIND_RELATION)
2813                         elog(ERROR, "inherited table \"%s\" is not a relation",
2814                                  inh->relname);
2815                 for (count = 0; count < rel->rd_att->natts; count++)
2816                 {
2817                         char       *name = NameStr(rel->rd_att->attrs[count]->attname);
2818
2819                         if (strcmp(name, colname) == 0)
2820                         {
2821                                 result = rel->rd_att->attrs[count]->atttypid;
2822                                 heap_close(rel, NoLock);
2823                                 return result;
2824                         }
2825                 }
2826                 heap_close(rel, NoLock);
2827         }
2828         /* Look for column among existing columns (if ALTER TABLE case) */
2829         if (OidIsValid(cxt->relOid))
2830         {
2831                 HeapTuple       atttuple;
2832
2833                 atttuple = SearchSysCache(ATTNAME,
2834                                                                   ObjectIdGetDatum(cxt->relOid),
2835                                                                   PointerGetDatum(colname),
2836                                                                   0, 0);
2837                 if (HeapTupleIsValid(atttuple))
2838                 {
2839                         result = ((Form_pg_attribute) GETSTRUCT(atttuple))->atttypid;
2840                         ReleaseSysCache(atttuple);
2841                         return result;
2842                 }
2843         }
2844
2845         elog(ERROR, "%s: column \"%s\" referenced in foreign key constraint does not exist",
2846                  cxt->stmtType, colname);
2847         return InvalidOid;                      /* keep compiler quiet */
2848 }
2849
2850 /*
2851  * Preprocess a list of column constraint clauses
2852  * to attach constraint attributes to their primary constraint nodes
2853  * and detect inconsistent/misplaced constraint attributes.
2854  *
2855  * NOTE: currently, attributes are only supported for FOREIGN KEY primary
2856  * constraints, but someday they ought to be supported for other constraints.
2857  */
2858 static void
2859 transformConstraintAttrs(List *constraintList)
2860 {
2861         Node       *lastprimarynode = NULL;
2862         bool            saw_deferrability = false;
2863         bool            saw_initially = false;
2864         List       *clist;
2865
2866         foreach(clist, constraintList)
2867         {
2868                 Node       *node = lfirst(clist);
2869
2870                 if (!IsA(node, Constraint))
2871                 {
2872                         lastprimarynode = node;
2873                         /* reset flags for new primary node */
2874                         saw_deferrability = false;
2875                         saw_initially = false;
2876                 }
2877                 else
2878                 {
2879                         Constraint *con = (Constraint *) node;
2880
2881                         switch (con->contype)
2882                         {
2883                                 case CONSTR_ATTR_DEFERRABLE:
2884                                         if (lastprimarynode == NULL ||
2885                                                 !IsA(lastprimarynode, FkConstraint))
2886                                                 elog(ERROR, "Misplaced DEFERRABLE clause");
2887                                         if (saw_deferrability)
2888                                                 elog(ERROR, "Multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed");
2889                                         saw_deferrability = true;
2890                                         ((FkConstraint *) lastprimarynode)->deferrable = true;
2891                                         break;
2892                                 case CONSTR_ATTR_NOT_DEFERRABLE:
2893                                         if (lastprimarynode == NULL ||
2894                                                 !IsA(lastprimarynode, FkConstraint))
2895                                                 elog(ERROR, "Misplaced NOT DEFERRABLE clause");
2896                                         if (saw_deferrability)
2897                                                 elog(ERROR, "Multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed");
2898                                         saw_deferrability = true;
2899                                         ((FkConstraint *) lastprimarynode)->deferrable = false;
2900                                         if (saw_initially &&
2901                                                 ((FkConstraint *) lastprimarynode)->initdeferred)
2902                                                 elog(ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
2903                                         break;
2904                                 case CONSTR_ATTR_DEFERRED:
2905                                         if (lastprimarynode == NULL ||
2906                                                 !IsA(lastprimarynode, FkConstraint))
2907                                                 elog(ERROR, "Misplaced INITIALLY DEFERRED clause");
2908                                         if (saw_initially)
2909                                                 elog(ERROR, "Multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed");
2910                                         saw_initially = true;
2911                                         ((FkConstraint *) lastprimarynode)->initdeferred = true;
2912
2913                                         /*
2914                                          * If only INITIALLY DEFERRED appears, assume
2915                                          * DEFERRABLE
2916                                          */
2917                                         if (!saw_deferrability)
2918                                                 ((FkConstraint *) lastprimarynode)->deferrable = true;
2919                                         else if (!((FkConstraint *) lastprimarynode)->deferrable)
2920                                                 elog(ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
2921                                         break;
2922                                 case CONSTR_ATTR_IMMEDIATE:
2923                                         if (lastprimarynode == NULL ||
2924                                                 !IsA(lastprimarynode, FkConstraint))
2925                                                 elog(ERROR, "Misplaced INITIALLY IMMEDIATE clause");
2926                                         if (saw_initially)
2927                                                 elog(ERROR, "Multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed");
2928                                         saw_initially = true;
2929                                         ((FkConstraint *) lastprimarynode)->initdeferred = false;
2930                                         break;
2931                                 default:
2932                                         /* Otherwise it's not an attribute */
2933                                         lastprimarynode = node;
2934                                         /* reset flags for new primary node */
2935                                         saw_deferrability = false;
2936                                         saw_initially = false;
2937                                         break;
2938                         }
2939                 }
2940         }
2941 }
2942
2943 /* Build a FromExpr node */
2944 static FromExpr *
2945 makeFromExpr(List *fromlist, Node *quals)
2946 {
2947         FromExpr   *f = makeNode(FromExpr);
2948
2949         f->fromlist = fromlist;
2950         f->quals = quals;
2951         return f;
2952 }
2953
2954 /*
2955  * Special handling of type definition for a column
2956  */
2957 static void
2958 transformColumnType(ParseState *pstate, ColumnDef *column)
2959 {
2960         TypeName   *typename = column->typename;
2961         Type            ctype = typenameType(typename);
2962
2963         /*
2964          * Is this the name of a complex type? If so, implement it as a set.
2965          *
2966          * XXX this is a hangover from ancient Berkeley code that probably
2967          * doesn't work anymore anyway.
2968          */
2969         if (typeTypeRelid(ctype) != InvalidOid)
2970         {
2971                 /*
2972                  * (Eventually add in here that the set can only contain one
2973                  * element.)
2974                  */
2975                 typename->setof = true;
2976         }
2977
2978         ReleaseSysCache(ctype);
2979 }
2980
2981 /*
2982  * analyzeCreateSchemaStmt -
2983  *        analyzes the "create schema" statement
2984  *
2985  * Split the schema element list into individual commands and place
2986  * them in the result list in an order such that there are no
2987  * forward references (e.g. GRANT to a table created later in the list).
2988  *
2989  * SQL92 also allows constraints to make forward references, so thumb through
2990  * the table columns and move forward references to a posterior alter-table
2991  * command.
2992  *
2993  * The result is a list of parse nodes that still need to be analyzed ---
2994  * but we can't analyze the later commands until we've executed the earlier
2995  * ones, because of possible inter-object references.
2996  *
2997  * Note: Called from commands/command.c
2998  */
2999 List *
3000 analyzeCreateSchemaStmt(CreateSchemaStmt *stmt)
3001 {
3002         CreateSchemaStmtContext cxt;
3003         List       *result;
3004         List       *elements;
3005
3006         cxt.stmtType = "CREATE SCHEMA";
3007         cxt.schemaname = stmt->schemaname;
3008         cxt.authid = stmt->authid;
3009         cxt.tables = NIL;
3010         cxt.views = NIL;
3011         cxt.grants = NIL;
3012         cxt.fwconstraints = NIL;
3013         cxt.alters = NIL;
3014         cxt.blist = NIL;
3015         cxt.alist = NIL;
3016
3017         /*
3018          * Run through each schema element in the schema element list.
3019          * Separate statements by type, and do preliminary analysis.
3020          */
3021         foreach(elements, stmt->schemaElts)
3022         {
3023                 Node       *element = lfirst(elements);
3024
3025                 switch (nodeTag(element))
3026                 {
3027                         case T_CreateStmt:
3028                                 {
3029                                         CreateStmt *elp = (CreateStmt *) element;
3030
3031                                         if (elp->relation->schemaname == NULL)
3032                                                 elp->relation->schemaname = cxt.schemaname;
3033                                         else if (strcmp(cxt.schemaname, elp->relation->schemaname) != 0)
3034                                                 elog(ERROR, "New table specifies a schema (%s)"
3035                                                         " different from the one being created (%s)",
3036                                                         elp->relation->schemaname, cxt.schemaname);
3037
3038                                         /*
3039                                          * XXX todo: deal with constraints
3040                                          */
3041
3042                                         cxt.tables = lappend(cxt.tables, element);
3043                                 }
3044                                 break;
3045
3046                         case T_ViewStmt:
3047                                 {
3048                                         ViewStmt *elp = (ViewStmt *) element;
3049
3050                                         if (elp->view->schemaname == NULL)
3051                                                 elp->view->schemaname = cxt.schemaname;
3052                                         else if (strcmp(cxt.schemaname, elp->view->schemaname) != 0)
3053                                                 elog(ERROR, "New view specifies a schema (%s)"
3054                                                         " different from the one being created (%s)",
3055                                                         elp->view->schemaname, cxt.schemaname);
3056
3057                                         /*
3058                                          * XXX todo: deal with references between views
3059                                          */
3060
3061                                         cxt.views = lappend(cxt.views, element);
3062                                 }
3063                                 break;
3064
3065                         case T_GrantStmt:
3066                                 cxt.grants = lappend(cxt.grants, element);
3067                                 break;
3068
3069                         default:
3070                                 elog(ERROR, "parser: unsupported schema node (internal error)");
3071                 }
3072         }
3073
3074         result = NIL;
3075         result = nconc(result, cxt.tables);
3076         result = nconc(result, cxt.views);
3077         result = nconc(result, cxt.grants);
3078
3079         return result;
3080 }