OSDN Git Service

Mega-commit to make heap_open/heap_openr/heap_close take an
[pg-rex/syncrep.git] / src / backend / parser / analyze.c
1 /*-------------------------------------------------------------------------
2  *
3  * analyze.c
4  *        transform the parse tree into a query tree
5  *
6  * Copyright (c) 1994, Regents of the University of California
7  *
8  *      $Id: analyze.c,v 1.119 1999/09/18 19:07:12 tgl Exp $
9  *
10  *-------------------------------------------------------------------------
11  */
12
13 #include "postgres.h"
14
15 #include "access/heapam.h"
16 #include "catalog/pg_type.h"
17 #include "nodes/makefuncs.h"
18 #include "parse.h"
19 #include "parser/analyze.h"
20 #include "parser/parse_agg.h"
21 #include "parser/parse_clause.h"
22 #include "parser/parse_relation.h"
23 #include "parser/parse_target.h"
24 #include "utils/builtins.h"
25
26 static Query *transformStmt(ParseState *pstate, Node *stmt);
27 static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt);
28 static Query *transformInsertStmt(ParseState *pstate, InsertStmt *stmt);
29 static Query *transformIndexStmt(ParseState *pstate, IndexStmt *stmt);
30 static Query *transformExtendStmt(ParseState *pstate, ExtendStmt *stmt);
31 static Query *transformRuleStmt(ParseState *query, RuleStmt *stmt);
32 static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt);
33 static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt);
34 static Query *transformCursorStmt(ParseState *pstate, SelectStmt *stmt);
35 static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt);
36
37 static void transformForUpdate(Query *qry, List *forUpdate);
38 void            CheckSelectForUpdate(Query *qry);
39
40 /* kluge to return extra info from transformCreateStmt() */
41 static List        *extras_before;
42 static List        *extras_after;
43
44
45 /*
46  * parse_analyze -
47  *        analyze a list of parse trees and transform them if necessary.
48  *
49  * Returns a list of transformed parse trees. Optimizable statements are
50  * all transformed to Query while the rest stays the same.
51  *
52  */
53 List *
54 parse_analyze(List *pl, ParseState *parentParseState)
55 {
56         List       *result = NIL;
57         ParseState *pstate;
58         Query      *parsetree;
59
60         while (pl != NIL)
61         {
62                 extras_before = extras_after = NIL;
63                 pstate = make_parsestate(parentParseState);
64
65                 parsetree = transformStmt(pstate, lfirst(pl));
66                 if (pstate->p_target_relation != NULL)
67                         heap_close(pstate->p_target_relation, AccessShareLock);
68                 pstate->p_target_relation = NULL;
69                 pstate->p_target_rangetblentry = NULL;
70
71                 while (extras_before != NIL)
72                 {
73                         result = lappend(result,
74                                                          transformStmt(pstate, lfirst(extras_before)));
75                         if (pstate->p_target_relation != NULL)
76                                 heap_close(pstate->p_target_relation, AccessShareLock);
77                         pstate->p_target_relation = NULL;
78                         pstate->p_target_rangetblentry = NULL;
79                         extras_before = lnext(extras_before);
80                 }
81
82                 result = lappend(result, parsetree);
83
84                 while (extras_after != NIL)
85                 {
86                         result = lappend(result,
87                                                          transformStmt(pstate, lfirst(extras_after)));
88                         if (pstate->p_target_relation != NULL)
89                                 heap_close(pstate->p_target_relation, AccessShareLock);
90                         pstate->p_target_relation = NULL;
91                         pstate->p_target_rangetblentry = NULL;
92                         extras_after = lnext(extras_after);
93                 }
94
95                 pfree(pstate);
96                 pl = lnext(pl);
97         }
98
99         return result;
100 }
101
102 /*
103  * transformStmt -
104  *        transform a Parse tree. If it is an optimizable statement, turn it
105  *        into a Query tree.
106  */
107 static Query *
108 transformStmt(ParseState *pstate, Node *parseTree)
109 {
110         Query      *result = NULL;
111
112         switch (nodeTag(parseTree))
113         {
114                         /*------------------------
115                          *      Non-optimizable statements
116                          *------------------------
117                          */
118                 case T_CreateStmt:
119                         result = transformCreateStmt(pstate, (CreateStmt *) parseTree);
120                         break;
121
122                 case T_IndexStmt:
123                         result = transformIndexStmt(pstate, (IndexStmt *) parseTree);
124                         break;
125
126                 case T_ExtendStmt:
127                         result = transformExtendStmt(pstate, (ExtendStmt *) parseTree);
128                         break;
129
130                 case T_RuleStmt:
131                         result = transformRuleStmt(pstate, (RuleStmt *) parseTree);
132                         break;
133
134                 case T_ViewStmt:
135                         {
136                                 ViewStmt   *n = (ViewStmt *) parseTree;
137
138                                 n->query = (Query *) transformStmt(pstate, (Node *) n->query);
139                                 result = makeNode(Query);
140                                 result->commandType = CMD_UTILITY;
141                                 result->utilityStmt = (Node *) n;
142                         }
143                         break;
144
145                 case T_VacuumStmt:
146                         {
147                                 MemoryContext oldcontext;
148
149                                 /*
150                                  * make sure that this Query is allocated in TopMemory
151                                  * context because vacuum spans transactions and we don't
152                                  * want to lose the vacuum Query due to end-of-transaction
153                                  * free'ing
154                                  */
155                                 oldcontext = MemoryContextSwitchTo(TopMemoryContext);
156                                 result = makeNode(Query);
157                                 result->commandType = CMD_UTILITY;
158                                 result->utilityStmt = (Node *) parseTree;
159                                 MemoryContextSwitchTo(oldcontext);
160                         }
161                         break;
162
163                 case T_ExplainStmt:
164                         {
165                                 ExplainStmt *n = (ExplainStmt *) parseTree;
166
167                                 result = makeNode(Query);
168                                 result->commandType = CMD_UTILITY;
169                                 n->query = transformStmt(pstate, (Node *) n->query);
170                                 result->utilityStmt = (Node *) parseTree;
171                         }
172                         break;
173
174                         /*------------------------
175                          *      Optimizable statements
176                          *------------------------
177                          */
178                 case T_InsertStmt:
179                         result = transformInsertStmt(pstate, (InsertStmt *) parseTree);
180                         break;
181
182                 case T_DeleteStmt:
183                         result = transformDeleteStmt(pstate, (DeleteStmt *) parseTree);
184                         break;
185
186                 case T_UpdateStmt:
187                         result = transformUpdateStmt(pstate, (UpdateStmt *) parseTree);
188                         break;
189
190                 case T_SelectStmt:
191                         if (!((SelectStmt *) parseTree)->portalname)
192                         {
193                                 result = transformSelectStmt(pstate, (SelectStmt *) parseTree);
194                                 result->limitOffset = ((SelectStmt *) parseTree)->limitOffset;
195                                 result->limitCount = ((SelectStmt *) parseTree)->limitCount;
196                         }
197                         else
198                                 result = transformCursorStmt(pstate, (SelectStmt *) parseTree);
199                         break;
200
201                 default:
202
203                         /*
204                          * other statments don't require any transformation-- just
205                          * return the original parsetree, yea!
206                          */
207                         result = makeNode(Query);
208                         result->commandType = CMD_UTILITY;
209                         result->utilityStmt = (Node *) parseTree;
210                         break;
211         }
212         return result;
213 }
214
215 /*
216  * transformDeleteStmt -
217  *        transforms a Delete Statement
218  */
219 static Query *
220 transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
221 {
222         Query      *qry = makeNode(Query);
223
224         qry->commandType = CMD_DELETE;
225
226         /* set up a range table */
227         makeRangeTable(pstate, NULL, NULL);
228         setTargetTable(pstate, stmt->relname);
229
230         qry->uniqueFlag = NULL;
231
232         /* fix where clause */
233         qry->qual = transformWhereClause(pstate, stmt->whereClause, NULL);
234         qry->hasSubLinks = pstate->p_hasSubLinks;
235
236         qry->rtable = pstate->p_rtable;
237         qry->resultRelation = refnameRangeTablePosn(pstate, stmt->relname, NULL);
238
239         qry->hasAggs = pstate->p_hasAggs;
240         if (pstate->p_hasAggs)
241                 parseCheckAggregates(pstate, qry);
242
243         return (Query *) qry;
244 }
245
246 /*
247  * transformInsertStmt -
248  *        transform an Insert Statement
249  */
250 static Query *
251 transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
252 {
253         Query      *qry = makeNode(Query);
254         Node       *fromQual;
255         List       *icolumns;
256         List       *tl;
257         TupleDesc       rd_att;
258
259         qry->commandType = CMD_INSERT;
260         pstate->p_is_insert = true;
261
262         /*----------
263          * Initial processing steps are just like SELECT, which should not
264          * be surprising, since we may be handling an INSERT ... SELECT.
265          * It is important that we finish processing all the SELECT subclauses
266          * before we start doing any INSERT-specific processing; otherwise
267          * the behavior of SELECT within INSERT might be different from a
268          * stand-alone SELECT.  (Indeed, Postgres up through 6.5 had bugs of
269          * just that nature...)
270          *----------
271          */
272
273         /* set up a range table --- note INSERT target is not in it yet */
274         makeRangeTable(pstate, stmt->fromClause, &fromQual);
275
276         qry->uniqueFlag = stmt->unique;
277
278         qry->targetList = transformTargetList(pstate, stmt->targetList);
279
280         qry->qual = transformWhereClause(pstate, stmt->whereClause, fromQual);
281
282         /* Initial processing of HAVING clause is just like WHERE clause.
283          * Additional work will be done in optimizer/plan/planner.c.
284          */
285         qry->havingQual = transformWhereClause(pstate, stmt->havingClause, NULL);
286
287         qry->groupClause = transformGroupClause(pstate,
288                                                                                         stmt->groupClause,
289                                                                                         qry->targetList);
290
291         /* An InsertStmt has no sortClause, but we still call
292          * transformSortClause because it also handles uniqueFlag.
293          */
294         qry->sortClause = transformSortClause(pstate,
295                                                                                   NIL,
296                                                                                   qry->targetList,
297                                                                                   qry->uniqueFlag);
298
299         qry->hasSubLinks = pstate->p_hasSubLinks;
300         qry->hasAggs = pstate->p_hasAggs;
301         if (pstate->p_hasAggs || qry->groupClause)
302                 parseCheckAggregates(pstate, qry);
303
304         /*
305          * If there is a havingQual but there are no aggregates, then there is
306          * something wrong with the query because HAVING must contain
307          * aggregates in its expressions! Otherwise the query could have been
308          * formulated using the WHERE clause.
309          */
310         if (qry->havingQual && ! qry->hasAggs)
311                 elog(ERROR, "SELECT/HAVING requires aggregates to be valid");
312
313         /*
314          * The INSERT INTO ... SELECT ... could have a UNION in child, so
315          * unionClause may be false
316          */
317         qry->unionall = stmt->unionall;
318
319         /*
320          * Just hand through the unionClause and intersectClause. We will
321          * handle it in the function Except_Intersect_Rewrite()
322          */
323         qry->unionClause = stmt->unionClause;
324         qry->intersectClause = stmt->intersectClause;
325
326         /*
327          * Now we are done with SELECT-like processing, and can get on with
328          * transforming the target list to match the INSERT target columns.
329          *
330          * In particular, it's time to add the INSERT target to the rangetable.
331          * (We didn't want it there until now since it shouldn't be visible in
332          * the SELECT part.)
333          */
334         setTargetTable(pstate, stmt->relname);
335
336         /* now the range table will not change */
337         qry->rtable = pstate->p_rtable;
338         qry->resultRelation = refnameRangeTablePosn(pstate, stmt->relname, NULL);
339
340         /* Prepare to assign non-conflicting resnos to resjunk attributes */
341         if (pstate->p_last_resno <= pstate->p_target_relation->rd_rel->relnatts)
342                 pstate->p_last_resno = pstate->p_target_relation->rd_rel->relnatts + 1;
343
344         /* Validate stmt->cols list, or build default list if no list given */
345         icolumns = makeTargetNames(pstate, stmt->cols);
346
347         /* Prepare non-junk columns for assignment to target table */
348         foreach(tl, qry->targetList)
349         {
350                 TargetEntry *tle = (TargetEntry *) lfirst(tl);
351                 Resdom     *resnode = tle->resdom;
352                 Ident      *id;
353
354                 if (resnode->resjunk)
355                 {
356                         /* Resjunk nodes need no additional processing, but be sure they
357                          * have names and resnos that do not match any target columns;
358                          * else rewriter or planner might get confused.
359                          */
360                         resnode->resname = "?resjunk?";
361                         resnode->resno = (AttrNumber) pstate->p_last_resno++;
362                         continue;
363                 }
364                 if (icolumns == NIL)
365                         elog(ERROR, "INSERT has more expressions than target columns");
366                 id = (Ident *) lfirst(icolumns);
367                 updateTargetListEntry(pstate, tle, id->name, id->indirection);
368                 icolumns = lnext(icolumns);
369         }
370
371         /*
372          * Add targetlist items to assign DEFAULT values to any columns that
373          * have defaults and were not assigned to by the user.
374          * XXX wouldn't it make more sense to do this further downstream,
375          * after the rule rewriter?
376          */
377         rd_att = pstate->p_target_relation->rd_att;
378         if (rd_att->constr && rd_att->constr->num_defval > 0)
379         {
380                 Form_pg_attribute *att = rd_att->attrs;
381                 AttrDefault *defval = rd_att->constr->defval;
382                 int                     ndef = rd_att->constr->num_defval;
383
384                 while (ndef-- > 0)
385                 {
386                         Form_pg_attribute thisatt = att[defval[ndef].adnum - 1];
387                         TargetEntry *te;
388
389                         foreach(tl, qry->targetList)
390                         {
391                                 TargetEntry *tle = (TargetEntry *) lfirst(tl);
392                                 Resdom     *resnode = tle->resdom;
393
394                                 if (resnode->resjunk)
395                                         continue;       /* ignore resjunk nodes */
396                                 if (namestrcmp(&(thisatt->attname), resnode->resname) == 0)
397                                         break;
398                         }
399                         if (tl != NIL)          /* something given for this attr */
400                                 continue;
401                         /*
402                          * No user-supplied value, so add a targetentry with DEFAULT expr
403                          * and correct data for the target column.
404                          */
405                         te = makeTargetEntry(
406                                 makeResdom(defval[ndef].adnum,
407                                                    thisatt->atttypid,
408                                                    thisatt->atttypmod,
409                                                    pstrdup(nameout(&(thisatt->attname))),
410                                                    0, 0, false),
411                                 stringToNode(defval[ndef].adbin));
412                         qry->targetList = lappend(qry->targetList, te);
413                         /*
414                          * Make sure the value is coerced to the target column type
415                          * (might not be right type if it's not a constant!)
416                          */
417                         updateTargetListEntry(pstate, te, te->resdom->resname, NIL);
418                 }
419         }
420
421         if (stmt->forUpdate != NULL)
422                 transformForUpdate(qry, stmt->forUpdate);
423
424         return (Query *) qry;
425 }
426
427 /*
428  *      makeObjectName()
429  *
430  *      Create a name for an implicitly created index, sequence, constraint, etc.
431  *
432  *      The parameters are: the original table name, the original field name, and
433  *      a "type" string (such as "seq" or "pkey").  The field name and/or type
434  *      can be NULL if not relevant.
435  *
436  *      The result is a palloc'd string.
437  *
438  *      The basic result we want is "name1_name2_type", omitting "_name2" or
439  *      "_type" when those parameters are NULL.  However, we must generate
440  *      a name with less than NAMEDATALEN characters!  So, we truncate one or
441  *      both names if necessary to make a short-enough string.  The type part
442  *      is never truncated (so it had better be reasonably short).
443  *
444  *      To reduce the probability of collisions, we might someday add more
445  *      smarts to this routine, like including some "hash" characters computed
446  *      from the truncated characters.  Currently it seems best to keep it simple,
447  *      so that the generated names are easily predictable by a person.
448  */
449 static char *
450 makeObjectName(char *name1, char *name2, char *typename)
451 {
452         char       *name;
453         int                     overhead = 0;   /* chars needed for type and underscores */
454         int                     availchars;             /* chars available for name(s) */
455         int                     name1chars;             /* chars allocated to name1 */
456         int                     name2chars;             /* chars allocated to name2 */
457         int                     ndx;
458
459         name1chars = strlen(name1);
460         if (name2)
461         {
462                 name2chars = strlen(name2);
463                 overhead++;                             /* allow for separating underscore */
464         }
465         else
466                 name2chars = 0;
467         if (typename)
468                 overhead += strlen(typename) + 1;
469
470         availchars = NAMEDATALEN-1 - overhead;
471
472         /* If we must truncate,  preferentially truncate the longer name.
473          * This logic could be expressed without a loop, but it's simple and
474          * obvious as a loop.
475          */
476         while (name1chars + name2chars > availchars)
477         {
478                 if (name1chars > name2chars)
479                         name1chars--;
480                 else
481                         name2chars--;
482         }
483
484         /* Now construct the string using the chosen lengths */
485         name = palloc(name1chars + name2chars + overhead + 1);
486         strncpy(name, name1, name1chars);
487         ndx = name1chars;
488         if (name2)
489         {
490                 name[ndx++] = '_';
491                 strncpy(name+ndx, name2, name2chars);
492                 ndx += name2chars;
493         }
494         if (typename)
495         {
496                 name[ndx++] = '_';
497                 strcpy(name+ndx, typename);
498         }
499         else
500                 name[ndx] = '\0';
501
502         return name;
503 }
504
505 static char *
506 CreateIndexName(char *table_name, char *column_name, char *label, List *indices)
507 {
508         int                     pass = 0;
509         char       *iname = NULL;
510         List       *ilist;
511         char            typename[NAMEDATALEN];
512
513         /* The type name for makeObjectName is label, or labelN if that's
514          * necessary to prevent collisions among multiple indexes for the same
515          * table.  Note there is no check for collisions with already-existing
516          * indexes; this ought to be rethought someday.
517          */
518         strcpy(typename, label);
519
520         for (;;)
521         {
522                 iname = makeObjectName(table_name, column_name, typename);
523
524                 foreach(ilist, indices)
525                 {
526                         IndexStmt  *index = lfirst(ilist);
527                         if (strcasecmp(iname, index->idxname) == 0)
528                                 break;
529                 }
530                 /* ran through entire list? then no name conflict found so done */
531                 if (ilist == NIL)
532                         break;
533
534                 /* the last one conflicted, so try a new name component */
535                 pfree(iname);
536                 sprintf(typename, "%s%d", label, ++pass);
537         }
538
539         return iname;
540 }
541
542 /*
543  * transformCreateStmt -
544  *        transforms the "create table" statement
545  *        SQL92 allows constraints to be scattered all over, so thumb through
546  *         the columns and collect all constraints into one place.
547  *        If there are any implied indices (e.g. UNIQUE or PRIMARY KEY)
548  *         then expand those into multiple IndexStmt blocks.
549  *        - thomas 1997-12-02
550  */
551 static Query *
552 transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
553 {
554         Query      *q;
555         List       *elements;
556         Node       *element;
557         List       *columns;
558         List       *dlist;
559         ColumnDef  *column;
560         List       *constraints,
561                            *clist;
562         Constraint *constraint;
563         List       *keys;
564         Ident      *key;
565         List       *blist = NIL;        /* "before list" of things to do before
566                                                                  * creating the table */
567         List       *ilist = NIL;        /* "index list" of things to do after
568                                                                  * creating the table */
569         IndexStmt  *index,
570                            *pkey = NULL;
571         IndexElem  *iparam;
572
573         q = makeNode(Query);
574         q->commandType = CMD_UTILITY;
575
576         elements = stmt->tableElts;
577         constraints = stmt->constraints;
578         columns = NIL;
579         dlist = NIL;
580
581         /*
582          * Run through each primary element in the table creation clause
583          */
584         while (elements != NIL)
585         {
586                 element = lfirst(elements);
587                 switch (nodeTag(element))
588                 {
589                         case T_ColumnDef:
590                                 column = (ColumnDef *) element;
591                                 columns = lappend(columns, column);
592
593                                 /* Special case SERIAL type? */
594                                 if (column->is_sequence)
595                                 {
596                                         char       *sname;
597                                         char       *cstring;
598                                         CreateSeqStmt *sequence;
599
600                                         sname = makeObjectName(stmt->relname, column->colname,
601                                                                                    "seq");
602                                         constraint = makeNode(Constraint);
603                                         constraint->contype = CONSTR_DEFAULT;
604                                         constraint->name = sname;
605                                         cstring = palloc(10 + strlen(constraint->name) + 3 + 1);
606                                         strcpy(cstring, "nextval('\"");
607                                         strcat(cstring, constraint->name);
608                                         strcat(cstring, "\"')");
609                                         constraint->def = cstring;
610                                         constraint->keys = NULL;
611
612                                         column->constraints = lappend(column->constraints, constraint);
613
614                                         constraint = makeNode(Constraint);
615                                         constraint->contype = CONSTR_UNIQUE;
616                                         constraint->name = makeObjectName(stmt->relname,
617                                                                                                           column->colname,
618                                                                                                           "key");
619                                         column->constraints = lappend(column->constraints, constraint);
620
621                                         sequence = makeNode(CreateSeqStmt);
622                                         sequence->seqname = pstrdup(sname);
623                                         sequence->options = NIL;
624
625                                         elog(NOTICE, "CREATE TABLE will create implicit sequence '%s' for SERIAL column '%s.%s'",
626                                           sequence->seqname, stmt->relname, column->colname);
627
628                                         blist = lcons(sequence, NIL);
629                                 }
630
631                                 /* Check for column constraints, if any... */
632                                 if (column->constraints != NIL)
633                                 {
634                                         clist = column->constraints;
635                                         while (clist != NIL)
636                                         {
637                                                 constraint = lfirst(clist);
638                                                 switch (constraint->contype)
639                                                 {
640                                                         case CONSTR_NULL:
641
642                                                                 /*
643                                                                  * We should mark this explicitly, so we
644                                                                  * can tell if NULL and NOT NULL are both
645                                                                  * specified
646                                                                  */
647                                                                 if (column->is_not_null)
648                                                                         elog(ERROR, "CREATE TABLE/(NOT) NULL conflicting declaration"
649                                                                                  " for '%s.%s'", stmt->relname, column->colname);
650                                                                 column->is_not_null = FALSE;
651                                                                 break;
652
653                                                         case CONSTR_NOTNULL:
654                                                                 if (column->is_not_null)
655                                                                         elog(ERROR, "CREATE TABLE/NOT NULL already specified"
656                                                                                  " for '%s.%s'", stmt->relname, column->colname);
657                                                                 column->is_not_null = TRUE;
658                                                                 break;
659
660                                                         case CONSTR_DEFAULT:
661                                                                 if (column->defval != NULL)
662                                                                         elog(ERROR, "CREATE TABLE/DEFAULT multiple values specified"
663                                                                                  " for '%s.%s'", stmt->relname, column->colname);
664                                                                 column->defval = constraint->def;
665                                                                 break;
666
667                                                         case CONSTR_PRIMARY:
668                                                                 if (constraint->name == NULL)
669                                                                         constraint->name = makeObjectName(stmt->relname, NULL, "pkey");
670                                                                 if (constraint->keys == NIL)
671                                                                         constraint->keys = lappend(constraint->keys, column);
672                                                                 dlist = lappend(dlist, constraint);
673                                                                 break;
674
675                                                         case CONSTR_UNIQUE:
676                                                                 if (constraint->name == NULL)
677                                                                         constraint->name = makeObjectName(stmt->relname, column->colname, "key");
678                                                                 if (constraint->keys == NIL)
679                                                                         constraint->keys = lappend(constraint->keys, column);
680                                                                 dlist = lappend(dlist, constraint);
681                                                                 break;
682
683                                                         case CONSTR_CHECK:
684                                                                 constraints = lappend(constraints, constraint);
685                                                                 if (constraint->name == NULL)
686                                                                         constraint->name = makeObjectName(stmt->relname, column->colname, NULL);
687                                                                 break;
688
689                                                         default:
690                                                                 elog(ERROR, "parser: unrecognized constraint (internal error)", NULL);
691                                                                 break;
692                                                 }
693                                                 clist = lnext(clist);
694                                         }
695                                 }
696                                 break;
697
698                         case T_Constraint:
699                                 constraint = (Constraint *) element;
700                                 switch (constraint->contype)
701                                 {
702                                         case CONSTR_PRIMARY:
703                                                 if (constraint->name == NULL)
704                                                         constraint->name = makeObjectName(stmt->relname, NULL, "pkey");
705                                                 dlist = lappend(dlist, constraint);
706                                                 break;
707
708                                         case CONSTR_UNIQUE:
709                                                 dlist = lappend(dlist, constraint);
710                                                 break;
711
712                                         case CONSTR_CHECK:
713                                                 constraints = lappend(constraints, constraint);
714                                                 break;
715
716                                         case CONSTR_NOTNULL:
717                                         case CONSTR_DEFAULT:
718                                                 elog(ERROR, "parser: illegal context for constraint (internal error)", NULL);
719                                                 break;
720                                         default:
721                                                 elog(ERROR, "parser: unrecognized constraint (internal error)", NULL);
722                                                 break;
723                                 }
724                                 break;
725
726                         default:
727                                 elog(ERROR, "parser: unrecognized node (internal error)", NULL);
728                 }
729
730                 elements = lnext(elements);
731         }
732
733         stmt->tableElts = columns;
734         stmt->constraints = constraints;
735
736 /* Now run through the "deferred list" to complete the query transformation.
737  * For PRIMARY KEYs, mark each column as NOT NULL and create an index.
738  * For UNIQUE, create an index as for PRIMARY KEYS, but do not insist on NOT NULL.
739  *
740  * Note that this code does not currently look for all possible redundant cases
741  *      and either ignore or stop with warning. The create might fail later when
742  *      names for indices turn out to be duplicated, or a user might have specified
743  *      extra useless indices which might hurt performance. - thomas 1997-12-08
744  */
745         while (dlist != NIL)
746         {
747                 constraint = lfirst(dlist);
748                 Assert(nodeTag(constraint) == T_Constraint);
749                 Assert((constraint->contype == CONSTR_PRIMARY)
750                            || (constraint->contype == CONSTR_UNIQUE));
751
752                 index = makeNode(IndexStmt);
753
754                 index->unique = TRUE;
755                 index->primary = (constraint->contype == CONSTR_PRIMARY ? TRUE : FALSE);
756                 if (index->primary)
757                 {
758                         if (pkey != NULL)
759                                 elog(ERROR, "CREATE TABLE/PRIMARY KEY multiple primary keys"
760                                          " for table '%s' are not allowed", stmt->relname);
761                         pkey = (IndexStmt *) index;
762                 }
763
764                 if (constraint->name != NULL)
765                         index->idxname = pstrdup(constraint->name);
766                 else if (constraint->contype == CONSTR_PRIMARY)
767                         index->idxname = makeObjectName(stmt->relname, NULL, "pkey");
768                 else
769                         index->idxname = NULL;
770
771                 index->relname = stmt->relname;
772                 index->accessMethod = "btree";
773                 index->indexParams = NIL;
774                 index->withClause = NIL;
775                 index->whereClause = NULL;
776
777                 keys = constraint->keys;
778                 while (keys != NIL)
779                 {
780                         key = lfirst(keys);
781                         columns = stmt->tableElts;
782                         column = NULL;
783                         while (columns != NIL)
784                         {
785                                 column = lfirst(columns);
786                                 if (strcasecmp(column->colname, key->name) == 0)
787                                         break;
788                                 else
789                                         column = NULL;
790                                 columns = lnext(columns);
791                         }
792                         if (column == NULL)
793                                 elog(ERROR, "CREATE TABLE column '%s' in key does not exist", key->name);
794
795                         if (constraint->contype == CONSTR_PRIMARY)
796                                 column->is_not_null = TRUE;
797                         iparam = makeNode(IndexElem);
798                         iparam->name = pstrdup(column->colname);
799                         iparam->args = NIL;
800                         iparam->class = NULL;
801                         iparam->typename = NULL;
802                         index->indexParams = lappend(index->indexParams, iparam);
803
804                         if (index->idxname == NULL)
805                                 index->idxname = CreateIndexName(stmt->relname, iparam->name, "key", ilist);
806
807                         keys = lnext(keys);
808                 }
809
810                 if (index->idxname == NULL)     /* should not happen */
811                         elog(ERROR, "CREATE TABLE: failed to make implicit index name");
812
813                 ilist = lappend(ilist, index);
814                 dlist = lnext(dlist);
815         }
816
817 /* OK, now finally, if there is a primary key, then make sure that there aren't any redundant
818  * unique indices defined on columns. This can arise if someone specifies UNIQUE explicitly
819  * or if a SERIAL column was defined along with a table PRIMARY KEY constraint.
820  * - thomas 1999-05-11
821  */
822         if (pkey != NULL)
823         {
824                 dlist = ilist;
825                 ilist = NIL;
826                 while (dlist != NIL)
827                 {
828                         List *pcols, *icols;
829                         int plen, ilen;
830                         int     keep = TRUE;
831
832                         index = lfirst(dlist);
833                         pcols = pkey->indexParams;
834                         icols = index->indexParams;
835
836                         plen = length(pcols);
837                         ilen = length(icols);
838
839                         /* Not the same as the primary key? Then we should look... */
840                         if ((index != pkey) && (ilen == plen))
841                         {
842                                 keep = FALSE;
843                                 while ((pcols != NIL) && (icols != NIL))
844                                 {
845                                         IndexElem *pcol = lfirst(pcols);
846                                         IndexElem *icol = lfirst(icols);
847                                         char *pname = pcol->name;
848                                         char *iname = icol->name;
849
850                                         /* different names? then no match... */
851                                         if (strcmp(iname, pname) != 0)
852                                         {
853                                                 keep = TRUE;
854                                                 break;
855                                         }
856                                         pcols = lnext(pcols);
857                                         icols = lnext(icols);
858                                 }
859                         }
860
861                         if (keep)
862                                 ilist = lappend(ilist, index);
863                         dlist = lnext(dlist);
864                 }
865         }
866
867         dlist = ilist;
868         while (dlist != NIL)
869         {
870                 index = lfirst(dlist);
871                 elog(NOTICE, "CREATE TABLE/%s will create implicit index '%s' for table '%s'",
872                          (index->primary ? "PRIMARY KEY" : "UNIQUE"),
873                          index->idxname, stmt->relname);
874                 dlist = lnext(dlist);
875         }
876
877         q->utilityStmt = (Node *) stmt;
878         extras_before = blist;
879         extras_after = ilist;
880
881         return q;
882 }       /* transformCreateStmt() */
883
884 /*
885  * transformIndexStmt -
886  *        transforms the qualification of the index statement
887  */
888 static Query *
889 transformIndexStmt(ParseState *pstate, IndexStmt *stmt)
890 {
891         Query      *qry;
892
893         qry = makeNode(Query);
894         qry->commandType = CMD_UTILITY;
895
896         /* take care of the where clause */
897         stmt->whereClause = transformWhereClause(pstate, stmt->whereClause, NULL);
898         qry->hasSubLinks = pstate->p_hasSubLinks;
899
900         stmt->rangetable = pstate->p_rtable;
901
902         qry->utilityStmt = (Node *) stmt;
903
904         return qry;
905 }
906
907 /*
908  * transformExtendStmt -
909  *        transform the qualifications of the Extend Index Statement
910  *
911  */
912 static Query *
913 transformExtendStmt(ParseState *pstate, ExtendStmt *stmt)
914 {
915         Query      *qry;
916
917         qry = makeNode(Query);
918         qry->commandType = CMD_UTILITY;
919
920         /* take care of the where clause */
921         stmt->whereClause = transformWhereClause(pstate, stmt->whereClause, NULL);
922         qry->hasSubLinks = pstate->p_hasSubLinks;
923
924         stmt->rangetable = pstate->p_rtable;
925
926         qry->utilityStmt = (Node *) stmt;
927         return qry;
928 }
929
930 /*
931  * transformRuleStmt -
932  *        transform a Create Rule Statement. The actions is a list of parse
933  *        trees which is transformed into a list of query trees.
934  */
935 static Query *
936 transformRuleStmt(ParseState *pstate, RuleStmt *stmt)
937 {
938         Query      *qry;
939         Query      *action;
940         List       *actions;
941
942         qry = makeNode(Query);
943         qry->commandType = CMD_UTILITY;
944
945         /*
946          * 'instead nothing' rules with a qualification need a query a
947          * rangetable so the rewrite handler can add the negated rule
948          * qualification to the original query. We create a query with the new
949          * command type CMD_NOTHING here that is treated special by the
950          * rewrite system.
951          */
952         if (stmt->actions == NIL)
953         {
954                 Query      *nothing_qry = makeNode(Query);
955
956                 nothing_qry->commandType = CMD_NOTHING;
957
958                 addRangeTableEntry(pstate, stmt->object->relname, "*CURRENT*",
959                                                    FALSE, FALSE);
960                 addRangeTableEntry(pstate, stmt->object->relname, "*NEW*",
961                                                    FALSE, FALSE);
962
963                 nothing_qry->rtable = pstate->p_rtable;
964
965                 stmt->actions = lappend(NIL, nothing_qry);
966         }
967
968         actions = stmt->actions;
969
970         /*
971          * transform each statment, like parse_analyze()
972          */
973         while (actions != NIL)
974         {
975
976                 /*
977                  * NOTE: 'CURRENT' must always have a varno equal to 1 and 'NEW'
978                  * equal to 2.
979                  */
980                 addRangeTableEntry(pstate, stmt->object->relname, "*CURRENT*",
981                                                    FALSE, FALSE);
982                 addRangeTableEntry(pstate, stmt->object->relname, "*NEW*",
983                                                    FALSE, FALSE);
984
985                 pstate->p_last_resno = 1;
986                 pstate->p_is_rule = true;               /* for expand all */
987                 pstate->p_hasAggs = false;
988
989                 action = (Query *) lfirst(actions);
990                 if (action->commandType != CMD_NOTHING)
991                         lfirst(actions) = transformStmt(pstate, lfirst(actions));
992                 actions = lnext(actions);
993         }
994
995         /* take care of the where clause */
996         stmt->whereClause = transformWhereClause(pstate, stmt->whereClause, NULL);
997         qry->hasSubLinks = pstate->p_hasSubLinks;
998
999         qry->utilityStmt = (Node *) stmt;
1000         return qry;
1001 }
1002
1003
1004 /*
1005  * transformSelectStmt -
1006  *        transforms a Select Statement
1007  *
1008  */
1009 static Query *
1010 transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
1011 {
1012         Query      *qry = makeNode(Query);
1013         Node       *fromQual;
1014
1015         qry->commandType = CMD_SELECT;
1016
1017         /* set up a range table */
1018         makeRangeTable(pstate, stmt->fromClause, &fromQual);
1019
1020         qry->uniqueFlag = stmt->unique;
1021
1022         qry->into = stmt->into;
1023         qry->isTemp = stmt->istemp;
1024         qry->isPortal = FALSE;
1025
1026         qry->targetList = transformTargetList(pstate, stmt->targetList);
1027
1028         qry->qual = transformWhereClause(pstate, stmt->whereClause, fromQual);
1029
1030         /* Initial processing of HAVING clause is just like WHERE clause.
1031          * Additional work will be done in optimizer/plan/planner.c.
1032          */
1033         qry->havingQual = transformWhereClause(pstate, stmt->havingClause, NULL);
1034
1035         qry->groupClause = transformGroupClause(pstate,
1036                                                                                         stmt->groupClause,
1037                                                                                         qry->targetList);
1038
1039         qry->sortClause = transformSortClause(pstate,
1040                                                                                   stmt->sortClause,
1041                                                                                   qry->targetList,
1042                                                                                   qry->uniqueFlag);
1043
1044         qry->hasSubLinks = pstate->p_hasSubLinks;
1045         qry->hasAggs = pstate->p_hasAggs;
1046         if (pstate->p_hasAggs || qry->groupClause)
1047                 parseCheckAggregates(pstate, qry);
1048
1049         /*
1050          * If there is a havingQual but there are no aggregates, then there is
1051          * something wrong with the query because HAVING must contain
1052          * aggregates in its expressions! Otherwise the query could have been
1053          * formulated using the WHERE clause.
1054          */
1055         if (qry->havingQual && ! qry->hasAggs)
1056                 elog(ERROR, "SELECT/HAVING requires aggregates to be valid");
1057
1058         /*
1059          * The INSERT INTO ... SELECT ... could have a UNION in child, so
1060          * unionClause may be false
1061          */
1062         qry->unionall = stmt->unionall;
1063
1064         /*
1065          * Just hand through the unionClause and intersectClause. We will
1066          * handle it in the function Except_Intersect_Rewrite()
1067          */
1068         qry->unionClause = stmt->unionClause;
1069         qry->intersectClause = stmt->intersectClause;
1070
1071         qry->rtable = pstate->p_rtable;
1072
1073         if (stmt->forUpdate != NULL)
1074                 transformForUpdate(qry, stmt->forUpdate);
1075
1076         return (Query *) qry;
1077 }
1078
1079 /*
1080  * transformUpdateStmt -
1081  *        transforms an update statement
1082  *
1083  */
1084 static Query *
1085 transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
1086 {
1087         Query      *qry = makeNode(Query);
1088         List       *origTargetList;
1089         List       *tl;
1090
1091         qry->commandType = CMD_UPDATE;
1092         pstate->p_is_update = true;
1093
1094         /*
1095          * the FROM clause is non-standard SQL syntax. We used to be able to
1096          * do this with REPLACE in POSTQUEL so we keep the feature.
1097          */
1098         makeRangeTable(pstate, stmt->fromClause, NULL);
1099         setTargetTable(pstate, stmt->relname);
1100
1101         qry->targetList = transformTargetList(pstate, stmt->targetList);
1102
1103         qry->qual = transformWhereClause(pstate, stmt->whereClause, NULL);
1104
1105         qry->hasSubLinks = pstate->p_hasSubLinks;
1106
1107         qry->rtable = pstate->p_rtable;
1108         qry->resultRelation = refnameRangeTablePosn(pstate, stmt->relname, NULL);
1109
1110         qry->hasAggs = pstate->p_hasAggs;
1111         if (pstate->p_hasAggs)
1112                 parseCheckAggregates(pstate, qry);
1113
1114         /*
1115          * Now we are done with SELECT-like processing, and can get on with
1116          * transforming the target list to match the UPDATE target columns.
1117          */
1118
1119         /* Prepare to assign non-conflicting resnos to resjunk attributes */
1120         if (pstate->p_last_resno <= pstate->p_target_relation->rd_rel->relnatts)
1121                 pstate->p_last_resno = pstate->p_target_relation->rd_rel->relnatts + 1;
1122
1123         /* Prepare non-junk columns for assignment to target table */
1124         origTargetList = stmt->targetList;
1125         foreach(tl, qry->targetList)
1126         {
1127                 TargetEntry *tle = (TargetEntry *) lfirst(tl);
1128                 Resdom     *resnode = tle->resdom;
1129                 ResTarget  *origTarget;
1130
1131                 if (resnode->resjunk)
1132                 {
1133                         /* Resjunk nodes need no additional processing, but be sure they
1134                          * have names and resnos that do not match any target columns;
1135                          * else rewriter or planner might get confused.
1136                          */
1137                         resnode->resname = "?resjunk?";
1138                         resnode->resno = (AttrNumber) pstate->p_last_resno++;
1139                         continue;
1140                 }
1141                 if (origTargetList == NIL)
1142                         elog(ERROR, "UPDATE target count mismatch --- internal error");
1143                 origTarget = (ResTarget *) lfirst(origTargetList);
1144                 updateTargetListEntry(pstate, tle,
1145                                                           origTarget->name, origTarget->indirection);
1146                 origTargetList = lnext(origTargetList);
1147         }
1148         if (origTargetList != NIL)
1149                 elog(ERROR, "UPDATE target count mismatch --- internal error");
1150
1151         return (Query *) qry;
1152 }
1153
1154 /*
1155  * transformCursorStmt -
1156  *        transform a Create Cursor Statement
1157  *
1158  */
1159 static Query *
1160 transformCursorStmt(ParseState *pstate, SelectStmt *stmt)
1161 {
1162         Query      *qry;
1163
1164         qry = transformSelectStmt(pstate, stmt);
1165
1166         qry->into = stmt->portalname;
1167         qry->isTemp = stmt->istemp;
1168         qry->isPortal = TRUE;
1169         qry->isBinary = stmt->binary;           /* internal portal */
1170
1171         return qry;
1172 }
1173
1174 /* This function steps through the tree
1175  * built up by the select_w_o_sort rule
1176  * and builds a list of all SelectStmt Nodes found
1177  * The built up list is handed back in **select_list.
1178  * If one of the SelectStmt Nodes has the 'unionall' flag
1179  * set to true *unionall_present hands back 'true' */
1180 void
1181 create_select_list(Node *ptr, List **select_list, bool *unionall_present)
1182 {
1183         if (IsA(ptr, SelectStmt))
1184         {
1185                 *select_list = lappend(*select_list, ptr);
1186                 if (((SelectStmt *) ptr)->unionall == TRUE)
1187                         *unionall_present = TRUE;
1188                 return;
1189         }
1190
1191         /* Recursively call for all arguments. A NOT expr has no lexpr! */
1192         if (((A_Expr *) ptr)->lexpr != NULL)
1193                 create_select_list(((A_Expr *) ptr)->lexpr, select_list, unionall_present);
1194         create_select_list(((A_Expr *) ptr)->rexpr, select_list, unionall_present);
1195 }
1196
1197 /* Changes the A_Expr Nodes to Expr Nodes and exchanges ANDs and ORs.
1198  * The reason for the exchange is easy: We implement INTERSECTs and EXCEPTs
1199  * by rewriting these queries to semantically equivalent queries that use
1200  * IN and NOT IN subselects. To be able to use all three operations
1201  * (UNIONs INTERSECTs and EXCEPTs) in one complex query we have to
1202  * translate the queries into Disjunctive Normal Form (DNF). Unfortunately
1203  * there is no function 'dnfify' but there is a function 'cnfify'
1204  * which produces DNF when we exchange ANDs and ORs before calling
1205  * 'cnfify' and exchange them back in the result.
1206  *
1207  * If an EXCEPT or INTERSECT is present *intersect_present
1208  * hands back 'true' */
1209 Node *
1210 A_Expr_to_Expr(Node *ptr, bool *intersect_present)
1211 {
1212         Node       *result = NULL;
1213
1214         switch (nodeTag(ptr))
1215         {
1216                 case T_A_Expr:
1217                         {
1218                                 A_Expr     *a = (A_Expr *) ptr;
1219
1220                                 switch (a->oper)
1221                                 {
1222                                         case AND:
1223                                                 {
1224                                                         Expr       *expr = makeNode(Expr);
1225                                                         Node       *lexpr = A_Expr_to_Expr(((A_Expr *) ptr)->lexpr, intersect_present);
1226                                                         Node       *rexpr = A_Expr_to_Expr(((A_Expr *) ptr)->rexpr, intersect_present);
1227
1228                                                         *intersect_present = TRUE;
1229
1230                                                         expr->typeOid = BOOLOID;
1231                                                         expr->opType = OR_EXPR;
1232                                                         expr->args = makeList(lexpr, rexpr, -1);
1233                                                         result = (Node *) expr;
1234                                                         break;
1235                                                 }
1236                                         case OR:
1237                                                 {
1238                                                         Expr       *expr = makeNode(Expr);
1239                                                         Node       *lexpr = A_Expr_to_Expr(((A_Expr *) ptr)->lexpr, intersect_present);
1240                                                         Node       *rexpr = A_Expr_to_Expr(((A_Expr *) ptr)->rexpr, intersect_present);
1241
1242                                                         expr->typeOid = BOOLOID;
1243                                                         expr->opType = AND_EXPR;
1244                                                         expr->args = makeList(lexpr, rexpr, -1);
1245                                                         result = (Node *) expr;
1246                                                         break;
1247                                                 }
1248                                         case NOT:
1249                                                 {
1250                                                         Expr       *expr = makeNode(Expr);
1251                                                         Node       *rexpr = A_Expr_to_Expr(((A_Expr *) ptr)->rexpr, intersect_present);
1252
1253                                                         expr->typeOid = BOOLOID;
1254                                                         expr->opType = NOT_EXPR;
1255                                                         expr->args = makeList(rexpr, -1);
1256                                                         result = (Node *) expr;
1257                                                         break;
1258                                                 }
1259                                 }
1260                                 break;
1261                         }
1262                 default:
1263                         result = ptr;
1264         }
1265         return result;
1266 }
1267
1268 void
1269 CheckSelectForUpdate(Query *qry)
1270 {
1271         if (qry->unionClause != NULL)
1272                 elog(ERROR, "SELECT FOR UPDATE is not allowed with UNION/INTERSECT/EXCEPT clause");
1273         if (qry->uniqueFlag != NULL)
1274                 elog(ERROR, "SELECT FOR UPDATE is not allowed with DISTINCT clause");
1275         if (qry->groupClause != NULL)
1276                 elog(ERROR, "SELECT FOR UPDATE is not allowed with GROUP BY clause");
1277         if (qry->hasAggs)
1278                 elog(ERROR, "SELECT FOR UPDATE is not allowed with AGGREGATE");
1279 }
1280
1281 static void
1282 transformForUpdate(Query *qry, List *forUpdate)
1283 {
1284         List       *rowMark = NULL;
1285         RowMark    *newrm;
1286         List       *l;
1287         Index           i;
1288
1289         CheckSelectForUpdate(qry);
1290
1291         if (lfirst(forUpdate) == NULL)          /* all tables */
1292         {
1293                 i = 1;
1294                 foreach(l, qry->rtable)
1295                 {
1296                         newrm = makeNode(RowMark);
1297                         newrm->rti = i++;
1298                         newrm->info = ROW_MARK_FOR_UPDATE | ROW_ACL_FOR_UPDATE;
1299                         rowMark = lappend(rowMark, newrm);
1300                 }
1301                 qry->rowMark = nconc(qry->rowMark, rowMark);
1302                 return;
1303         }
1304
1305         foreach(l, forUpdate)
1306         {
1307                 List       *l2;
1308                 List       *l3;
1309
1310                 i = 1;
1311                 foreach(l2, qry->rtable)
1312                 {
1313                         if (strcmp(((RangeTblEntry *) lfirst(l2))->refname, lfirst(l)) == 0)
1314                         {
1315                                 foreach(l3, rowMark)
1316                                 {
1317                                         if (((RowMark *) lfirst(l3))->rti == i)         /* duplicate */
1318                                                 break;
1319                                 }
1320                                 if (l3 == NULL)
1321                                 {
1322                                         newrm = makeNode(RowMark);
1323                                         newrm->rti = i;
1324                                         newrm->info = ROW_MARK_FOR_UPDATE | ROW_ACL_FOR_UPDATE;
1325                                         rowMark = lappend(rowMark, newrm);
1326                                 }
1327                                 break;
1328                         }
1329                         i++;
1330                 }
1331                 if (l2 == NULL)
1332                         elog(ERROR, "FOR UPDATE: relation %s not found in FROM clause", lfirst(l));
1333         }
1334
1335         qry->rowMark = rowMark;
1336         return;
1337 }