OSDN Git Service

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