OSDN Git Service

Ignore copies of columns specified in ORDER/GROUP BY
[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  *
9  * IDENTIFICATION
10  *        $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.46 1997/10/16 06:58:38 vadim Exp $
11  *
12  *-------------------------------------------------------------------------
13  */
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include "postgres.h"
18 #include "nodes/nodes.h"
19 #include "nodes/params.h"
20 #include "nodes/primnodes.h"
21 #include "nodes/parsenodes.h"
22 #include "nodes/relation.h"
23 #include "parse.h"                              /* for AND, OR, etc. */
24 #include "catalog/pg_type.h"    /* for INT4OID, etc. */
25 #include "catalog/pg_proc.h"
26 #include "utils/elog.h"
27 #include "utils/builtins.h"             /* namecmp(), textout() */
28 #include "utils/lsyscache.h"
29 #include "utils/palloc.h"
30 #include "utils/mcxt.h"
31 #include "utils/syscache.h"
32 #include "utils/acl.h"
33 #include "parser/parse_query.h"
34 #include "parser/parse_state.h"
35 #include "nodes/makefuncs.h"    /* for makeResdom(), etc. */
36 #include "nodes/nodeFuncs.h"
37 #include "commands/sequence.h"
38
39 #include "optimizer/clauses.h"
40 #include "access/heapam.h"
41
42 #include "miscadmin.h"
43
44 #include "port-protos.h"                /* strdup() */
45
46 /* convert the parse tree into a query tree */
47 static Query *transformStmt(ParseState *pstate, Node *stmt);
48
49 static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt);
50 static Query *transformInsertStmt(ParseState *pstate, AppendStmt *stmt);
51 static Query *transformIndexStmt(ParseState *pstate, IndexStmt *stmt);
52 static Query *transformExtendStmt(ParseState *pstate, ExtendStmt *stmt);
53 static Query *transformRuleStmt(ParseState *query, RuleStmt *stmt);
54 static Query *transformSelectStmt(ParseState *pstate, RetrieveStmt *stmt);
55 static Query *transformUpdateStmt(ParseState *pstate, ReplaceStmt *stmt);
56 static Query *transformCursorStmt(ParseState *pstate, CursorStmt *stmt);
57 static Node *handleNestedDots(ParseState *pstate, Attr *attr, int *curr_resno);
58
59 #define EXPR_COLUMN_FIRST        1
60 #define EXPR_RELATION_FIRST  2
61 static Node *transformExpr(ParseState *pstate, Node *expr, int precedence);
62 static Node *transformIdent(ParseState *pstate, Node *expr, int precedence);
63
64 static void makeRangeTable(ParseState *pstate, char *relname, List *frmList);
65 static List *expandAllTables(ParseState *pstate);
66 static char *figureColname(Node *expr, Node *resval);
67 static List *makeTargetNames(ParseState *pstate, List *cols);
68 static List *transformTargetList(ParseState *pstate, List *targetlist);
69 static TargetEntry *
70 make_targetlist_expr(ParseState *pstate,
71                                          char *colname, Node *expr,
72                                          List *arrayRef);
73 static bool inWhereClause = false;
74 static Node *transformWhereClause(ParseState *pstate, Node *a_expr);
75 static List *
76 transformGroupClause(ParseState *pstate, List *grouplist,
77                                          List *targetlist);
78 static List *
79 transformSortClause(ParseState *pstate,
80                                         List *orderlist, List *targetlist,
81                                         char *uniqueFlag);
82
83 static void parseFromClause(ParseState *pstate, List *frmList);
84 static Node *
85 ParseFunc(ParseState *pstate, char *funcname,
86                   List *fargs, int *curr_resno);
87 static List *setup_tlist(char *attname, Oid relid);
88 static List *setup_base_tlist(Oid typeid);
89 static void
90 make_arguments(int nargs, List *fargs, Oid *input_typeids,
91                            Oid *function_typeids);
92 static void AddAggToParseState(ParseState *pstate, Aggreg *aggreg);
93 static void finalizeAggregates(ParseState *pstate, Query *qry);
94 static void parseCheckAggregates(ParseState *pstate, Query *qry);
95 static ParseState *makeParseState(void);
96
97 /*****************************************************************************
98  *
99  *****************************************************************************/
100
101 /*
102  * makeParseState() --
103  *        allocate and initialize a new ParseState.
104  *      the CALLERS is responsible for freeing the ParseState* returned
105  *
106  */
107
108 static ParseState *
109 makeParseState(void)
110 {
111         ParseState *pstate;
112
113         pstate = malloc(sizeof(ParseState));
114         pstate->p_last_resno = 1;
115         pstate->p_rtable = NIL;
116         pstate->p_numAgg = 0;
117         pstate->p_aggs = NIL;
118         pstate->p_is_insert = false;
119         pstate->p_insert_columns = NIL;
120         pstate->p_is_update = false;
121         pstate->p_is_rule = false;
122         pstate->p_target_relation = NULL;
123         pstate->p_target_rangetblentry = NULL;
124
125         return (pstate);
126 }
127
128 /*
129  * parse_analyze -
130  *        analyze a list of parse trees and transform them if necessary.
131  *
132  * Returns a list of transformed parse trees. Optimizable statements are
133  * all transformed to Query while the rest stays the same.
134  *
135  * CALLER is responsible for freeing the QueryTreeList* returned
136  */
137 QueryTreeList *
138 parse_analyze(List *pl)
139 {
140         QueryTreeList *result;
141         ParseState *pstate;
142         int                     i = 0;
143
144         result = malloc(sizeof(QueryTreeList));
145         result->len = length(pl);
146         result->qtrees = (Query **) malloc(result->len * sizeof(Query *));
147
148         inWhereClause = false;          /* to avoid nextval(sequence) in WHERE */
149
150         while (pl != NIL)
151         {
152                 pstate = makeParseState();
153                 result->qtrees[i++] = transformStmt(pstate, lfirst(pl));
154                 pl = lnext(pl);
155                 if (pstate->p_target_relation != NULL)
156                         heap_close(pstate->p_target_relation);
157                 free(pstate);
158         }
159
160         return result;
161 }
162
163 /*
164  * transformStmt -
165  *        transform a Parse tree. If it is an optimizable statement, turn it
166  *        into a Query tree.
167  */
168 static Query *
169 transformStmt(ParseState *pstate, Node *parseTree)
170 {
171         Query      *result = NULL;
172
173         switch (nodeTag(parseTree))
174         {
175                         /*------------------------
176                          *      Non-optimizable statements
177                          *------------------------
178                          */
179                 case T_IndexStmt:
180                         result = transformIndexStmt(pstate, (IndexStmt *) parseTree);
181                         break;
182
183                 case T_ExtendStmt:
184                         result = transformExtendStmt(pstate, (ExtendStmt *) parseTree);
185                         break;
186
187                 case T_RuleStmt:
188                         result = transformRuleStmt(pstate, (RuleStmt *) parseTree);
189                         break;
190
191                 case T_ViewStmt:
192                         {
193                                 ViewStmt   *n = (ViewStmt *) parseTree;
194
195                                 n->query = (Query *) transformStmt(pstate, (Node *) n->query);
196                                 result = makeNode(Query);
197                                 result->commandType = CMD_UTILITY;
198                                 result->utilityStmt = (Node *) n;
199                         }
200                         break;
201
202                 case T_VacuumStmt:
203                         {
204                                 MemoryContext oldcontext;
205
206                                 /*
207                                  * make sure that this Query is allocated in TopMemory
208                                  * context because vacuum spans transactions and we don't
209                                  * want to lose the vacuum Query due to end-of-transaction
210                                  * free'ing
211                                  */
212                                 oldcontext = MemoryContextSwitchTo(TopMemoryContext);
213                                 result = makeNode(Query);
214                                 result->commandType = CMD_UTILITY;
215                                 result->utilityStmt = (Node *) parseTree;
216                                 MemoryContextSwitchTo(oldcontext);
217                                 break;
218
219                         }
220                 case T_ExplainStmt:
221                         {
222                                 ExplainStmt *n = (ExplainStmt *) parseTree;
223
224                                 result = makeNode(Query);
225                                 result->commandType = CMD_UTILITY;
226                                 n->query = transformStmt(pstate, (Node *) n->query);
227                                 result->utilityStmt = (Node *) parseTree;
228                         }
229                         break;
230
231                         /*------------------------
232                          *      Optimizable statements
233                          *------------------------
234                          */
235                 case T_AppendStmt:
236                         result = transformInsertStmt(pstate, (AppendStmt *) parseTree);
237                         break;
238
239                 case T_DeleteStmt:
240                         result = transformDeleteStmt(pstate, (DeleteStmt *) parseTree);
241                         break;
242
243                 case T_ReplaceStmt:
244                         result = transformUpdateStmt(pstate, (ReplaceStmt *) parseTree);
245                         break;
246
247                 case T_CursorStmt:
248                         result = transformCursorStmt(pstate, (CursorStmt *) parseTree);
249                         break;
250
251                 case T_RetrieveStmt:
252                         result = transformSelectStmt(pstate, (RetrieveStmt *) parseTree);
253                         break;
254
255                 default:
256
257                         /*
258                          * other statments don't require any transformation-- just
259                          * return the original parsetree
260                          */
261                         result = makeNode(Query);
262                         result->commandType = CMD_UTILITY;
263                         result->utilityStmt = (Node *) parseTree;
264                         break;
265         }
266         return result;
267 }
268
269 /*
270  * transformDeleteStmt -
271  *        transforms a Delete Statement
272  */
273 static Query *
274 transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
275 {
276         Query      *qry = makeNode(Query);
277
278         qry->commandType = CMD_DELETE;
279
280         /* set up a range table */
281         makeRangeTable(pstate, stmt->relname, NULL);
282
283         qry->uniqueFlag = NULL;
284
285         /* fix where clause */
286         qry->qual = transformWhereClause(pstate, stmt->whereClause);
287
288         qry->rtable = pstate->p_rtable;
289         qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
290
291         /* make sure we don't have aggregates in the where clause */
292         if (pstate->p_numAgg > 0)
293                 parseCheckAggregates(pstate, qry);
294
295         return (Query *) qry;
296 }
297
298 /*
299  * transformInsertStmt -
300  *        transform an Insert Statement
301  */
302 static Query *
303 transformInsertStmt(ParseState *pstate, AppendStmt *stmt)
304 {
305         Query      *qry = makeNode(Query);      /* make a new query tree */
306         List       *icolumns;
307
308         qry->commandType = CMD_INSERT;
309         pstate->p_is_insert = true;
310
311         /* set up a range table */
312         makeRangeTable(pstate, stmt->relname, stmt->fromClause);
313
314         qry->uniqueFlag = NULL;
315
316         /* fix the target list */
317         icolumns = pstate->p_insert_columns = makeTargetNames(pstate, stmt->cols);
318         
319         qry->targetList = transformTargetList(pstate, stmt->targetList);
320         
321         /* DEFAULT handling */
322         if (length(qry->targetList) < pstate->p_target_relation->rd_att->natts &&
323                 pstate->p_target_relation->rd_att->constr &&
324                 pstate->p_target_relation->rd_att->constr->num_defval > 0)
325         {
326                 AttributeTupleForm         *att = pstate->p_target_relation->rd_att->attrs;
327                 AttrDefault                        *defval = pstate->p_target_relation->rd_att->constr->defval;
328                 int                                             ndef = pstate->p_target_relation->rd_att->constr->num_defval;
329                 
330                 /* 
331                  * if stmt->cols == NIL then makeTargetNames returns list of all 
332                  * attrs: have to shorter icolumns list...
333                  */
334                 if (stmt->cols == NIL)
335                 {
336                         List   *extrl;
337                         int             i = length(qry->targetList);
338                         
339                         foreach (extrl, icolumns)
340                         {
341                                 if (--i <= 0)
342                                         break;
343                         }
344                         freeList (lnext(extrl));
345                         lnext(extrl) = NIL;
346                 }
347                 
348                 while (ndef-- > 0)
349                 {
350                         List               *tl;
351                         Ident              *id;
352                         TargetEntry        *te;
353                         
354                         foreach (tl, icolumns)
355                         {
356                                 id = (Ident *) lfirst(tl);
357                                 if (!namestrcmp(&(att[defval[ndef].adnum - 1]->attname), id->name))
358                                         break;
359                         }
360                         if (tl != NIL)          /* something given for this attr */
361                                 continue;
362                         /* 
363                          * Nothing given for this attr with DEFAULT expr, so
364                          * add new TargetEntry to qry->targetList. 
365                          * Note, that we set resno to defval[ndef].adnum:
366                          * it's what transformTargetList()->make_targetlist_expr()
367                          * does for INSERT ... SELECT. But for INSERT ... VALUES
368                          * pstate->p_last_resno is used. It doesn't matter for 
369                          * "normal" using (planner creates proper target list
370                          * in preptlist.c), but may break RULEs in some way.
371                          * It seems better to create proper target list here...
372                          */
373                         te = makeNode(TargetEntry);
374                         te->resdom = makeResdom(defval[ndef].adnum,
375                                                                         att[defval[ndef].adnum - 1]->atttypid,
376                                                                         att[defval[ndef].adnum - 1]->attlen,
377                                                                         pstrdup(nameout(&(att[defval[ndef].adnum - 1]->attname))),
378                                                                         0, 0, 0);
379                         te->fjoin = NULL;
380                         te->expr = (Node *) stringToNode(defval[ndef].adbin);
381                         qry->targetList = lappend (qry->targetList, te);
382                 }
383         }
384         
385         /* fix where clause */
386         qry->qual = transformWhereClause(pstate, stmt->whereClause);
387
388         /* now the range table will not change */
389         qry->rtable = pstate->p_rtable;
390         qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
391
392         if (pstate->p_numAgg > 0)
393                 finalizeAggregates(pstate, qry);
394
395         return (Query *) qry;
396 }
397
398 /*
399  * transformIndexStmt -
400  *        transforms the qualification of the index statement
401  */
402 static Query *
403 transformIndexStmt(ParseState *pstate, IndexStmt *stmt)
404 {
405         Query      *q;
406
407         q = makeNode(Query);
408         q->commandType = CMD_UTILITY;
409
410         /* take care of the where clause */
411         stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
412         stmt->rangetable = pstate->p_rtable;
413
414         q->utilityStmt = (Node *) stmt;
415
416         return q;
417 }
418
419 /*
420  * transformExtendStmt -
421  *        transform the qualifications of the Extend Index Statement
422  *
423  */
424 static Query *
425 transformExtendStmt(ParseState *pstate, ExtendStmt *stmt)
426 {
427         Query      *q;
428
429         q = makeNode(Query);
430         q->commandType = CMD_UTILITY;
431
432         /* take care of the where clause */
433         stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
434         stmt->rangetable = pstate->p_rtable;
435
436         q->utilityStmt = (Node *) stmt;
437         return q;
438 }
439
440 /*
441  * transformRuleStmt -
442  *        transform a Create Rule Statement. The actions is a list of parse
443  *        trees which is transformed into a list of query trees.
444  */
445 static Query *
446 transformRuleStmt(ParseState *pstate, RuleStmt *stmt)
447 {
448         Query      *q;
449         List       *actions;
450
451         q = makeNode(Query);
452         q->commandType = CMD_UTILITY;
453
454         actions = stmt->actions;
455
456         /*
457          * transform each statment, like parse_analyze()
458          */
459         while (actions != NIL)
460         {
461
462                 /*
463                  * NOTE: 'CURRENT' must always have a varno equal to 1 and 'NEW'
464                  * equal to 2.
465                  */
466                 addRangeTableEntry(pstate, stmt->object->relname, "*CURRENT*",
467                                                    FALSE, FALSE, NULL);
468                 addRangeTableEntry(pstate, stmt->object->relname, "*NEW*",
469                                                    FALSE, FALSE, NULL);
470
471                 pstate->p_last_resno = 1;
472                 pstate->p_is_rule = true;               /* for expand all */
473                 pstate->p_numAgg = 0;
474                 pstate->p_aggs = NULL;
475
476                 lfirst(actions) = transformStmt(pstate, lfirst(actions));
477                 actions = lnext(actions);
478         }
479
480         /* take care of the where clause */
481         stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
482
483         q->utilityStmt = (Node *) stmt;
484         return q;
485 }
486
487
488 /*
489  * transformSelectStmt -
490  *        transforms a Select Statement
491  *
492  */
493 static Query *
494 transformSelectStmt(ParseState *pstate, RetrieveStmt *stmt)
495 {
496         Query      *qry = makeNode(Query);
497
498         qry->commandType = CMD_SELECT;
499
500         /* set up a range table */
501         makeRangeTable(pstate, NULL, stmt->fromClause);
502
503         qry->uniqueFlag = stmt->unique;
504
505         qry->into = stmt->into;
506         qry->isPortal = FALSE;
507
508         /* fix the target list */
509         qry->targetList = transformTargetList(pstate, stmt->targetList);
510
511         /* fix where clause */
512         qry->qual = transformWhereClause(pstate, stmt->whereClause);
513
514         /* check subselect clause */
515         if (stmt->selectClause)
516                 elog(NOTICE, "UNION not yet supported; using first SELECT only", NULL);
517
518         /* check subselect clause */
519         if (stmt->havingClause)
520                 elog(NOTICE, "HAVING not yet supported; ignore clause", NULL);
521
522         /* fix order clause */
523         qry->sortClause = transformSortClause(pstate,
524                                                                                   stmt->sortClause,
525                                                                                   qry->targetList,
526                                                                                   qry->uniqueFlag);
527
528         /* fix group by clause */
529         qry->groupClause = transformGroupClause(pstate,
530                                                                                         stmt->groupClause,
531                                                                                         qry->targetList);
532         qry->rtable = pstate->p_rtable;
533
534         if (pstate->p_numAgg > 0)
535                 finalizeAggregates(pstate, qry);
536
537         return (Query *) qry;
538 }
539
540 /*
541  * transformUpdateStmt -
542  *        transforms an update statement
543  *
544  */
545 static Query *
546 transformUpdateStmt(ParseState *pstate, ReplaceStmt *stmt)
547 {
548         Query      *qry = makeNode(Query);
549
550         qry->commandType = CMD_UPDATE;
551         pstate->p_is_update = true;
552
553         /*
554          * the FROM clause is non-standard SQL syntax. We used to be able to
555          * do this with REPLACE in POSTQUEL so we keep the feature.
556          */
557         makeRangeTable(pstate, stmt->relname, stmt->fromClause);
558
559         /* fix the target list */
560         qry->targetList = transformTargetList(pstate, stmt->targetList);
561
562         /* fix where clause */
563         qry->qual = transformWhereClause(pstate, stmt->whereClause);
564
565         qry->rtable = pstate->p_rtable;
566         qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
567
568         /* make sure we don't have aggregates in the where clause */
569         if (pstate->p_numAgg > 0)
570                 parseCheckAggregates(pstate, qry);
571
572         return (Query *) qry;
573 }
574
575 /*
576  * transformCursorStmt -
577  *        transform a Create Cursor Statement
578  *
579  */
580 static Query *
581 transformCursorStmt(ParseState *pstate, CursorStmt *stmt)
582 {
583         Query      *qry = makeNode(Query);
584
585         /*
586          * in the old days, a cursor statement is a 'retrieve into portal'; If
587          * you change the following, make sure you also go through the code in
588          * various places that tests the kind of operation.
589          */
590         qry->commandType = CMD_SELECT;
591
592         /* set up a range table */
593         makeRangeTable(pstate, NULL, stmt->fromClause);
594
595         qry->uniqueFlag = stmt->unique;
596
597         qry->into = stmt->portalname;
598         qry->isPortal = TRUE;
599         qry->isBinary = stmt->binary;           /* internal portal */
600
601         /* fix the target list */
602         qry->targetList = transformTargetList(pstate, stmt->targetList);
603
604         /* fix where clause */
605         qry->qual = transformWhereClause(pstate, stmt->whereClause);
606
607         /* fix order clause */
608         qry->sortClause = transformSortClause(pstate,
609                                                                                   stmt->sortClause,
610                                                                                   qry->targetList,
611                                                                                   qry->uniqueFlag);
612         /* fix group by clause */
613         qry->groupClause = transformGroupClause(pstate,
614                                                                                         stmt->groupClause,
615                                                                                         qry->targetList);
616
617         qry->rtable = pstate->p_rtable;
618
619         if (pstate->p_numAgg > 0)
620                 finalizeAggregates(pstate, qry);
621
622         return (Query *) qry;
623 }
624
625 /*****************************************************************************
626  *
627  * Transform Exprs, Aggs, etc.
628  *
629  *****************************************************************************/
630
631 /*
632  * transformExpr -
633  *        analyze and transform expressions. Type checking and type casting is
634  *        done here. The optimizer and the executor cannot handle the original
635  *        (raw) expressions collected by the parse tree. Hence the transformation
636  *        here.
637  */
638 static Node *
639 transformExpr(ParseState *pstate, Node *expr, int precedence)
640 {
641         Node       *result = NULL;
642
643         if (expr == NULL)
644                 return NULL;
645
646         switch (nodeTag(expr))
647         {
648                 case T_Attr:
649                         {
650                                 Attr       *att = (Attr *) expr;
651                                 Node       *temp;
652
653                                 /* what if att.attrs == "*"?? */
654                                 temp = handleNestedDots(pstate, att, &pstate->p_last_resno);
655                                 if (att->indirection != NIL)
656                                 {
657                                         List       *idx = att->indirection;
658
659                                         while (idx != NIL)
660                                         {
661                                                 A_Indices  *ai = (A_Indices *) lfirst(idx);
662                                                 Node       *lexpr = NULL,
663                                                                    *uexpr;
664
665                                                 uexpr = transformExpr(pstate, ai->uidx, precedence);    /* must exists */
666                                                 if (exprType(uexpr) != INT4OID)
667                                                         elog(WARN, "array index expressions must be int4's");
668                                                 if (ai->lidx != NULL)
669                                                 {
670                                                         lexpr = transformExpr(pstate, ai->lidx, precedence);
671                                                         if (exprType(lexpr) != INT4OID)
672                                                                 elog(WARN, "array index expressions must be int4's");
673                                                 }
674 #if 0
675                                                 pfree(ai->uidx);
676                                                 if (ai->lidx != NULL)
677                                                         pfree(ai->lidx);
678 #endif
679                                                 ai->lidx = lexpr;
680                                                 ai->uidx = uexpr;
681
682                                                 /*
683                                                  * note we reuse the list of indices, make sure we
684                                                  * don't free them! Otherwise, make a new list
685                                                  * here
686                                                  */
687                                                 idx = lnext(idx);
688                                         }
689                                         result = (Node *) make_array_ref(temp, att->indirection);
690                                 }
691                                 else
692                                 {
693                                         result = temp;
694                                 }
695                                 break;
696                         }
697                 case T_A_Const:
698                         {
699                                 A_Const    *con = (A_Const *) expr;
700                                 Value      *val = &con->val;
701
702                                 if (con->typename != NULL)
703                                 {
704                                         result = parser_typecast(val, con->typename, -1);
705                                 }
706                                 else
707                                 {
708                                         result = (Node *) make_const(val);
709                                 }
710                                 break;
711                         }
712                 case T_ParamNo:
713                         {
714                                 ParamNo    *pno = (ParamNo *) expr;
715                                 Oid                     toid;
716                                 int                     paramno;
717                                 Param      *param;
718
719                                 paramno = pno->number;
720                                 toid = param_type(paramno);
721                                 if (!OidIsValid(toid))
722                                 {
723                                         elog(WARN, "Parameter '$%d' is out of range",
724                                                  paramno);
725                                 }
726                                 param = makeNode(Param);
727                                 param->paramkind = PARAM_NUM;
728                                 param->paramid = (AttrNumber) paramno;
729                                 param->paramname = "<unnamed>";
730                                 param->paramtype = (Oid) toid;
731                                 param->param_tlist = (List *) NULL;
732
733                                 result = (Node *) param;
734                                 break;
735                         }
736                 case T_A_Expr:
737                         {
738                                 A_Expr     *a = (A_Expr *) expr;
739
740                                 switch (a->oper)
741                                 {
742                                         case OP:
743                                                 {
744                                                         Node       *lexpr = transformExpr(pstate, a->lexpr, precedence);
745                                                         Node       *rexpr = transformExpr(pstate, a->rexpr, precedence);
746
747                                                         result = (Node *) make_op(a->opname, lexpr, rexpr);
748                                                 }
749                                                 break;
750                                         case ISNULL:
751                                                 {
752                                                         Node       *lexpr = transformExpr(pstate, a->lexpr, precedence);
753
754                                                         result = ParseFunc(pstate,
755                                                                                   "nullvalue", lcons(lexpr, NIL),
756                                                                                            &pstate->p_last_resno);
757                                                 }
758                                                 break;
759                                         case NOTNULL:
760                                                 {
761                                                         Node       *lexpr = transformExpr(pstate, a->lexpr, precedence);
762
763                                                         result = ParseFunc(pstate,
764                                                                            "nonnullvalue", lcons(lexpr, NIL),
765                                                                                            &pstate->p_last_resno);
766                                                 }
767                                                 break;
768                                         case AND:
769                                                 {
770                                                         Expr       *expr = makeNode(Expr);
771                                                         Node       *lexpr = transformExpr(pstate, a->lexpr, precedence);
772                                                         Node       *rexpr = transformExpr(pstate, a->rexpr, precedence);
773
774                                                         if (exprType(lexpr) != BOOLOID)
775                                                                 elog(WARN,
776                                                                          "left-hand side of AND is type '%s', not bool",
777                                                                          tname(get_id_type(exprType(lexpr))));
778                                                         if (exprType(rexpr) != BOOLOID)
779                                                                 elog(WARN,
780                                                                          "right-hand side of AND is type '%s', not bool",
781                                                                          tname(get_id_type(exprType(rexpr))));
782                                                         expr->typeOid = BOOLOID;
783                                                         expr->opType = AND_EXPR;
784                                                         expr->args = makeList(lexpr, rexpr, -1);
785                                                         result = (Node *) expr;
786                                                 }
787                                                 break;
788                                         case OR:
789                                                 {
790                                                         Expr       *expr = makeNode(Expr);
791                                                         Node       *lexpr = transformExpr(pstate, a->lexpr, precedence);
792                                                         Node       *rexpr = transformExpr(pstate, a->rexpr, precedence);
793
794                                                         if (exprType(lexpr) != BOOLOID)
795                                                                 elog(WARN,
796                                                                          "left-hand side of OR is type '%s', not bool",
797                                                                          tname(get_id_type(exprType(lexpr))));
798                                                         if (exprType(rexpr) != BOOLOID)
799                                                                 elog(WARN,
800                                                                          "right-hand side of OR is type '%s', not bool",
801                                                                          tname(get_id_type(exprType(rexpr))));
802                                                         expr->typeOid = BOOLOID;
803                                                         expr->opType = OR_EXPR;
804                                                         expr->args = makeList(lexpr, rexpr, -1);
805                                                         result = (Node *) expr;
806                                                 }
807                                                 break;
808                                         case NOT:
809                                                 {
810                                                         Expr       *expr = makeNode(Expr);
811                                                         Node       *rexpr = transformExpr(pstate, a->rexpr, precedence);
812
813                                                         if (exprType(rexpr) != BOOLOID)
814                                                                 elog(WARN,
815                                                                 "argument to NOT is type '%s', not bool",
816                                                                          tname(get_id_type(exprType(rexpr))));
817                                                         expr->typeOid = BOOLOID;
818                                                         expr->opType = NOT_EXPR;
819                                                         expr->args = makeList(rexpr, -1);
820                                                         result = (Node *) expr;
821                                                 }
822                                                 break;
823                                 }
824                                 break;
825                         }
826                 case T_Ident:
827                         {
828
829                                 /*
830                                  * look for a column name or a relation name (the default
831                                  * behavior)
832                                  */
833                                 result = transformIdent(pstate, expr, precedence);
834                                 break;
835                         }
836                 case T_FuncCall:
837                         {
838                                 FuncCall   *fn = (FuncCall *) expr;
839                                 List       *args;
840
841                                 /* transform the list of arguments */
842                                 foreach(args, fn->args)
843                                         lfirst(args) = transformExpr(pstate, (Node *) lfirst(args), precedence);
844                                 result = ParseFunc(pstate,
845                                                   fn->funcname, fn->args, &pstate->p_last_resno);
846                                 break;
847                         }
848                 default:
849                         /* should not reach here */
850                         elog(WARN, "transformExpr: does not know how to transform %d\n",
851                                  nodeTag(expr));
852                         break;
853         }
854
855         return result;
856 }
857
858 static Node *
859 transformIdent(ParseState *pstate, Node *expr, int precedence)
860 {
861         Ident      *ident = (Ident *) expr;
862         RangeTblEntry *rte;
863         Node       *column_result,
864                            *relation_result,
865                            *result;
866
867         column_result = relation_result = result = 0;
868         /* try to find the ident as a column */
869         if ((rte = colnameRangeTableEntry(pstate, ident->name)) != NULL)
870         {
871                 Attr       *att = makeNode(Attr);
872
873                 att->relname = rte->refname;
874                 att->attrs = lcons(makeString(ident->name), NIL);
875                 column_result =
876                         (Node *) handleNestedDots(pstate, att, &pstate->p_last_resno);
877         }
878
879         /* try to find the ident as a relation */
880         if (refnameRangeTableEntry(pstate->p_rtable, ident->name) != NULL)
881         {
882                 ident->isRel = TRUE;
883                 relation_result = (Node *) ident;
884         }
885
886         /* choose the right result based on the precedence */
887         if (precedence == EXPR_COLUMN_FIRST)
888         {
889                 if (column_result)
890                         result = column_result;
891                 else
892                         result = relation_result;
893         }
894         else
895         {
896                 if (relation_result)
897                         result = relation_result;
898                 else
899                         result = column_result;
900         }
901
902         if (result == NULL)
903                 elog(WARN, "attribute \"%s\" not found", ident->name);
904
905         return result;
906 }
907
908 /*****************************************************************************
909  *
910  * From Clause
911  *
912  *****************************************************************************/
913
914 /*
915  * parseFromClause -
916  *        turns the table references specified in the from-clause into a
917  *        range table. The range table may grow as we transform the expressions
918  *        in the target list. (Note that this happens because in POSTQUEL, we
919  *        allow references to relations not specified in the from-clause. We
920  *        also allow that in our POST-SQL)
921  *
922  */
923 static void
924 parseFromClause(ParseState *pstate, List *frmList)
925 {
926         List       *fl;
927
928         foreach(fl, frmList)
929         {
930                 RangeVar   *r = lfirst(fl);
931                 RelExpr    *baserel = r->relExpr;
932                 char       *relname = baserel->relname;
933                 char       *refname = r->name;
934                 RangeTblEntry *rte;
935
936                 if (refname == NULL)
937                         refname = relname;
938
939                 /*
940                  * marks this entry to indicate it comes from the FROM clause. In
941                  * SQL, the target list can only refer to range variables
942                  * specified in the from clause but we follow the more powerful
943                  * POSTQUEL semantics and automatically generate the range
944                  * variable if not specified. However there are times we need to
945                  * know whether the entries are legitimate.
946                  *
947                  * eg. select * from foo f where f.x = 1; will generate wrong answer
948                  * if we expand * to foo.x.
949                  */
950                 rte = addRangeTableEntry(pstate, relname, refname, baserel->inh, TRUE,
951                                                                  baserel->timeRange);
952         }
953 }
954
955 /*
956  * makeRangeTable -
957  *        make a range table with the specified relation (optional) and the
958  *        from-clause.
959  */
960 static void
961 makeRangeTable(ParseState *pstate, char *relname, List *frmList)
962 {
963         RangeTblEntry *rte;
964
965         parseFromClause(pstate, frmList);
966
967         if (relname == NULL)
968                 return;
969
970         if (refnameRangeTablePosn(pstate->p_rtable, relname) < 1)
971                 rte = addRangeTableEntry(pstate, relname, relname, FALSE, FALSE, NULL);
972         else
973                 rte = refnameRangeTableEntry(pstate->p_rtable, relname);
974
975         pstate->p_target_rangetblentry = rte;
976         Assert(pstate->p_target_relation == NULL);
977         pstate->p_target_relation = heap_open(rte->relid);
978         Assert(pstate->p_target_relation != NULL);
979         /* will close relation later */
980 }
981
982 /*
983  *      exprType -
984  *        returns the Oid of the type of the expression. (Used for typechecking.)
985  */
986 Oid
987 exprType(Node *expr)
988 {
989         Oid                     type = (Oid) 0;
990
991         switch (nodeTag(expr))
992         {
993                 case T_Func:
994                         type = ((Func *) expr)->functype;
995                         break;
996                 case T_Iter:
997                         type = ((Iter *) expr)->itertype;
998                         break;
999                 case T_Var:
1000                         type = ((Var *) expr)->vartype;
1001                         break;
1002                 case T_Expr:
1003                         type = ((Expr *) expr)->typeOid;
1004                         break;
1005                 case T_Const:
1006                         type = ((Const *) expr)->consttype;
1007                         break;
1008                 case T_ArrayRef:
1009                         type = ((ArrayRef *) expr)->refelemtype;
1010                         break;
1011                 case T_Aggreg:
1012                         type = ((Aggreg *) expr)->aggtype;
1013                         break;
1014                 case T_Param:
1015                         type = ((Param *) expr)->paramtype;
1016                         break;
1017                 case T_Ident:
1018                         /* is this right? */
1019                         type = UNKNOWNOID;
1020                         break;
1021                 default:
1022                         elog(WARN, "exprType: don't know how to get type for %d node",
1023                                  nodeTag(expr));
1024                         break;
1025         }
1026         return type;
1027 }
1028
1029 /*
1030  * expandAllTables -
1031  *        turns '*' (in the target list) into a list of attributes (of all
1032  *        relations in the range table)
1033  */
1034 static List *
1035 expandAllTables(ParseState *pstate)
1036 {
1037         List       *target = NIL;
1038         List       *legit_rtable = NIL;
1039         List       *rt,
1040                            *rtable;
1041
1042         rtable = pstate->p_rtable;
1043         if (pstate->p_is_rule)
1044         {
1045
1046                 /*
1047                  * skip first two entries, "*new*" and "*current*"
1048                  */
1049                 rtable = lnext(lnext(pstate->p_rtable));
1050         }
1051
1052         /* this should not happen */
1053         if (rtable == NULL)
1054                 elog(WARN, "cannot expand: null p_rtable");
1055
1056         /*
1057          * go through the range table and make a list of range table entries
1058          * which we will expand.
1059          */
1060         foreach(rt, rtable)
1061         {
1062                 RangeTblEntry *rte = lfirst(rt);
1063
1064                 /*
1065                  * we only expand those specify in the from clause. (This will
1066                  * also prevent us from using the wrong table in inserts: eg.
1067                  * tenk2 in "insert into tenk2 select * from tenk1;")
1068                  */
1069                 if (!rte->inFromCl)
1070                         continue;
1071                 legit_rtable = lappend(legit_rtable, rte);
1072         }
1073
1074         foreach(rt, legit_rtable)
1075         {
1076                 RangeTblEntry *rte = lfirst(rt);
1077                 List       *temp = target;
1078
1079                 if (temp == NIL)
1080                         target = expandAll(pstate, rte->relname, rte->refname,
1081                                                            &pstate->p_last_resno);
1082                 else
1083                 {
1084                         while (temp != NIL && lnext(temp) != NIL)
1085                                 temp = lnext(temp);
1086                         lnext(temp) = expandAll(pstate, rte->relname, rte->refname,
1087                                                                         &pstate->p_last_resno);
1088                 }
1089         }
1090         return target;
1091 }
1092
1093
1094 /*
1095  * figureColname -
1096  *        if the name of the resulting column is not specified in the target
1097  *        list, we have to guess.
1098  *
1099  */
1100 static char *
1101 figureColname(Node *expr, Node *resval)
1102 {
1103         switch (nodeTag(expr))
1104         {
1105                         case T_Aggreg:
1106                         return (char *)         /* XXX */
1107                         ((Aggreg *) expr)->aggname;
1108                 case T_Expr:
1109                         if (((Expr *) expr)->opType == FUNC_EXPR)
1110                         {
1111                                 if (nodeTag(resval) == T_FuncCall)
1112                                         return ((FuncCall *) resval)->funcname;
1113                         }
1114                         break;
1115                 default:
1116                         break;
1117         }
1118
1119         return "?column?";
1120 }
1121
1122 /*****************************************************************************
1123  *
1124  * Target list
1125  *
1126  *****************************************************************************/
1127
1128 /*
1129  * makeTargetNames -
1130  *        generate a list of column names if not supplied or
1131  *        test supplied column names to make sure they are in target table
1132  *        (used exclusively for inserts)
1133  */
1134 static List *
1135 makeTargetNames(ParseState *pstate, List *cols)
1136 {
1137         List       *tl = NULL;
1138
1139         /* Generate ResTarget if not supplied */
1140
1141         if (cols == NIL)
1142         {
1143                 int                     numcol;
1144                 int                     i;
1145                 AttributeTupleForm *attr = pstate->p_target_relation->rd_att->attrs;
1146
1147                 numcol = pstate->p_target_relation->rd_rel->relnatts;
1148                 for (i = 0; i < numcol; i++)
1149                 {
1150                         Ident      *id = makeNode(Ident);
1151
1152                         id->name = palloc(NAMEDATALEN);
1153                         strNcpy(id->name, attr[i]->attname.data, NAMEDATALEN - 1);
1154                         id->indirection = NIL;
1155                         id->isRel = false;
1156                         if (tl == NIL)
1157                                 cols = tl = lcons(id, NIL);
1158                         else
1159                         {
1160                                 lnext(tl) = lcons(id, NIL);
1161                                 tl = lnext(tl);
1162                         }
1163                 }
1164         }
1165         else
1166         {
1167                 foreach(tl, cols)
1168                 {
1169                         List       *nxt;
1170                         char       *name = ((Ident *) lfirst(tl))->name;
1171                 
1172                         /* elog on failure */
1173                         varattno(pstate->p_target_relation, name);
1174                         foreach(nxt, lnext(tl))
1175                                 if (!strcmp(name, ((Ident *) lfirst(nxt))->name))
1176                                         elog (WARN, "Attribute %s should be specified only once", name);
1177                 }
1178         }
1179         
1180         return cols;
1181 }
1182
1183 /*
1184  * transformTargetList -
1185  *        turns a list of ResTarget's into a list of TargetEntry's
1186  */
1187 static List *
1188 transformTargetList(ParseState *pstate, List *targetlist)
1189 {
1190         List       *p_target = NIL;
1191         List       *tail_p_target = NIL;
1192
1193         while (targetlist != NIL)
1194         {
1195                 ResTarget  *res = (ResTarget *) lfirst(targetlist);
1196                 TargetEntry *tent = makeNode(TargetEntry);
1197
1198                 switch (nodeTag(res->val))
1199                 {
1200                         case T_Ident:
1201                                 {
1202                                         Node       *expr;
1203                                         Oid                     type_id;
1204                                         int                     type_len;
1205                                         char       *identname;
1206                                         char       *resname;
1207
1208                                         identname = ((Ident *) res->val)->name;
1209                                         handleTargetColname(pstate, &res->name, NULL, identname);
1210
1211                                         /*
1212                                          * here we want to look for column names only, not
1213                                          * relation
1214                                          */
1215
1216                                         /*
1217                                          * names (even though they can be stored in Ident
1218                                          * nodes,
1219                                          */
1220                                         /* too)                                                                                                         */
1221                                         expr = transformIdent(pstate, (Node *) res->val, EXPR_COLUMN_FIRST);
1222                                         type_id = exprType(expr);
1223                                         type_len = tlen(get_id_type(type_id));
1224                                         resname = (res->name) ? res->name : identname;
1225                                         tent->resdom = makeResdom((AttrNumber) pstate->p_last_resno++,
1226                                                                                           (Oid) type_id,
1227                                                                                           (Size) type_len,
1228                                                                                           resname,
1229                                                                                           (Index) 0,
1230                                                                                           (Oid) 0,
1231                                                                                           0);
1232
1233                                         tent->expr = expr;
1234                                         break;
1235                                 }
1236                         case T_ParamNo:
1237                         case T_FuncCall:
1238                         case T_A_Const:
1239                         case T_A_Expr:
1240                                 {
1241                                         Node       *expr = transformExpr(pstate, (Node *) res->val, EXPR_COLUMN_FIRST);
1242
1243                                         handleTargetColname(pstate, &res->name, NULL, NULL);
1244                                         /* note indirection has not been transformed */
1245                                         if (pstate->p_is_insert && res->indirection != NIL)
1246                                         {
1247                                                 /* this is an array assignment */
1248                                                 char       *val;
1249                                                 char       *str,
1250                                                                    *save_str;
1251                                                 List       *elt;
1252                                                 int                     i = 0,
1253                                                                         ndims;
1254                                                 int                     lindx[MAXDIM],
1255                                                                         uindx[MAXDIM];
1256                                                 int                     resdomno;
1257                                                 Relation        rd;
1258                                                 Value      *constval;
1259
1260                                                 if (exprType(expr) != UNKNOWNOID ||
1261                                                         !IsA(expr, Const))
1262                                                         elog(WARN, "yyparse: string constant expected");
1263
1264                                                 val = (char *) textout((struct varlena *)
1265                                                                                    ((Const *) expr)->constvalue);
1266                                                 str = save_str = (char *) palloc(strlen(val) + MAXDIM * 25 + 2);
1267                                                 foreach(elt, res->indirection)
1268                                                 {
1269                                                         A_Indices  *aind = (A_Indices *) lfirst(elt);
1270
1271                                                         aind->uidx = transformExpr(pstate, aind->uidx, EXPR_COLUMN_FIRST);
1272                                                         if (!IsA(aind->uidx, Const))
1273                                                                 elog(WARN,
1274                                                                          "Array Index for Append should be a constant");
1275                                                         uindx[i] = ((Const *) aind->uidx)->constvalue;
1276                                                         if (aind->lidx != NULL)
1277                                                         {
1278                                                                 aind->lidx = transformExpr(pstate, aind->lidx, EXPR_COLUMN_FIRST);
1279                                                                 if (!IsA(aind->lidx, Const))
1280                                                                         elog(WARN,
1281                                                                                  "Array Index for Append should be a constant");
1282                                                                 lindx[i] = ((Const *) aind->lidx)->constvalue;
1283                                                         }
1284                                                         else
1285                                                         {
1286                                                                 lindx[i] = 1;
1287                                                         }
1288                                                         if (lindx[i] > uindx[i])
1289                                                                 elog(WARN, "yyparse: lower index cannot be greater than upper index");
1290                                                         sprintf(str, "[%d:%d]", lindx[i], uindx[i]);
1291                                                         str += strlen(str);
1292                                                         i++;
1293                                                 }
1294                                                 sprintf(str, "=%s", val);
1295                                                 rd = pstate->p_target_relation;
1296                                                 Assert(rd != NULL);
1297                                                 resdomno = varattno(rd, res->name);
1298                                                 ndims = att_attnelems(rd, resdomno);
1299                                                 if (i != ndims)
1300                                                         elog(WARN, "yyparse: array dimensions do not match");
1301                                                 constval = makeNode(Value);
1302                                                 constval->type = T_String;
1303                                                 constval->val.str = save_str;
1304                                                 tent = make_targetlist_expr(pstate, res->name,
1305                                                                                    (Node *) make_const(constval),
1306                                                                                                         NULL);
1307                                                 pfree(save_str);
1308                                         }
1309                                         else
1310                                         {
1311                                                 char       *colname = res->name;
1312
1313                                                 /* this is not an array assignment */
1314                                                 if (colname == NULL)
1315                                                 {
1316
1317                                                         /*
1318                                                          * if you're wondering why this is here, look
1319                                                          * at the yacc grammar for why a name can be
1320                                                          * missing. -ay
1321                                                          */
1322                                                         colname = figureColname(expr, res->val);
1323                                                 }
1324                                                 if (res->indirection)
1325                                                 {
1326                                                         List       *ilist = res->indirection;
1327
1328                                                         while (ilist != NIL)
1329                                                         {
1330                                                                 A_Indices  *ind = lfirst(ilist);
1331
1332                                                                 ind->lidx = transformExpr(pstate, ind->lidx, EXPR_COLUMN_FIRST);
1333                                                                 ind->uidx = transformExpr(pstate, ind->uidx, EXPR_COLUMN_FIRST);
1334                                                                 ilist = lnext(ilist);
1335                                                         }
1336                                                 }
1337                                                 res->name = colname;
1338                                                 tent = make_targetlist_expr(pstate, res->name, expr,
1339                                                                                                         res->indirection);
1340                                         }
1341                                         break;
1342                                 }
1343                         case T_Attr:
1344                                 {
1345                                         Oid                     type_id;
1346                                         int                     type_len;
1347                                         Attr       *att = (Attr *) res->val;
1348                                         Node       *result;
1349                                         char       *attrname;
1350                                         char       *resname;
1351                                         Resdom     *resnode;
1352                                         List       *attrs = att->attrs;
1353
1354                                         /*
1355                                          * Target item is a single '*', expand all tables (eg.
1356                                          * SELECT * FROM emp)
1357                                          */
1358                                         if (att->relname != NULL && !strcmp(att->relname, "*"))
1359                                         {
1360                                                 if (tail_p_target == NIL)
1361                                                         p_target = tail_p_target = expandAllTables(pstate);
1362                                                 else
1363                                                         lnext(tail_p_target) = expandAllTables(pstate);
1364
1365                                                 while (lnext(tail_p_target) != NIL)
1366                                                         /* make sure we point to the last target entry */
1367                                                         tail_p_target = lnext(tail_p_target);
1368
1369                                                 /*
1370                                                  * skip rest of while loop
1371                                                  */
1372                                                 targetlist = lnext(targetlist);
1373                                                 continue;
1374                                         }
1375
1376                                         /*
1377                                          * Target item is relation.*, expand the table (eg.
1378                                          * SELECT emp.*, dname FROM emp, dept)
1379                                          */
1380                                         attrname = strVal(lfirst(att->attrs));
1381                                         if (att->attrs != NIL && !strcmp(attrname, "*"))
1382                                         {
1383
1384                                                 /*
1385                                                  * tail_p_target is the target list we're building
1386                                                  * in the while loop. Make sure we fix it after
1387                                                  * appending more nodes.
1388                                                  */
1389                                                 if (tail_p_target == NIL)
1390                                                         p_target = tail_p_target = expandAll(pstate, att->relname,
1391                                                                         att->relname, &pstate->p_last_resno);
1392                                                 else
1393                                                         lnext(tail_p_target) =
1394                                                                 expandAll(pstate, att->relname, att->relname,
1395                                                                                   &pstate->p_last_resno);
1396                                                 while (lnext(tail_p_target) != NIL)
1397                                                         /* make sure we point to the last target entry */
1398                                                         tail_p_target = lnext(tail_p_target);
1399
1400                                                 /*
1401                                                  * skip the rest of the while loop
1402                                                  */
1403                                                 targetlist = lnext(targetlist);
1404                                                 continue;
1405                                         }
1406
1407
1408                                         /*
1409                                          * Target item is fully specified: ie.
1410                                          * relation.attribute
1411                                          */
1412                                         result = handleNestedDots(pstate, att, &pstate->p_last_resno);
1413                                         handleTargetColname(pstate, &res->name, att->relname, attrname);
1414                                         if (att->indirection != NIL)
1415                                         {
1416                                                 List       *ilist = att->indirection;
1417
1418                                                 while (ilist != NIL)
1419                                                 {
1420                                                         A_Indices  *ind = lfirst(ilist);
1421
1422                                                         ind->lidx = transformExpr(pstate, ind->lidx, EXPR_COLUMN_FIRST);
1423                                                         ind->uidx = transformExpr(pstate, ind->uidx, EXPR_COLUMN_FIRST);
1424                                                         ilist = lnext(ilist);
1425                                                 }
1426                                                 result = (Node *) make_array_ref(result, att->indirection);
1427                                         }
1428                                         type_id = exprType(result);
1429                                         type_len = tlen(get_id_type(type_id));
1430                                         /* move to last entry */
1431                                         while (lnext(attrs) != NIL)
1432                                                 attrs = lnext(attrs);
1433                                         resname = (res->name) ? res->name : strVal(lfirst(attrs));
1434                                         resnode = makeResdom((AttrNumber) pstate->p_last_resno++,
1435                                                                                  (Oid) type_id,
1436                                                                                  (Size) type_len,
1437                                                                                  resname,
1438                                                                                  (Index) 0,
1439                                                                                  (Oid) 0,
1440                                                                                  0);
1441                                         tent->resdom = resnode;
1442                                         tent->expr = result;
1443                                         break;
1444                                 }
1445                         default:
1446                                 /* internal error */
1447                                 elog(WARN,
1448                                          "internal error: do not know how to transform targetlist");
1449                                 break;
1450                 }
1451
1452                 if (p_target == NIL)
1453                 {
1454                         p_target = tail_p_target = lcons(tent, NIL);
1455                 }
1456                 else
1457                 {
1458                         lnext(tail_p_target) = lcons(tent, NIL);
1459                         tail_p_target = lnext(tail_p_target);
1460                 }
1461                 targetlist = lnext(targetlist);
1462         }
1463
1464         return p_target;
1465 }
1466
1467
1468 /*
1469  * make_targetlist_expr -
1470  *        make a TargetEntry from an expression
1471  *
1472  * arrayRef is a list of transformed A_Indices
1473  */
1474 static TargetEntry *
1475 make_targetlist_expr(ParseState *pstate,
1476                                          char *colname,
1477                                          Node *expr,
1478                                          List *arrayRef)
1479 {
1480         Oid                     type_id,
1481                                 attrtype;
1482         int                     type_len,
1483                                 attrlen;
1484         int                     resdomno;
1485         Relation        rd;
1486         bool            attrisset;
1487         TargetEntry *tent;
1488         Resdom     *resnode;
1489
1490         if (expr == NULL)
1491                 elog(WARN, "make_targetlist_expr: invalid use of NULL expression");
1492
1493         type_id = exprType(expr);
1494         if (type_id == InvalidOid)
1495         {
1496                 type_len = 0;
1497         }
1498         else
1499                 type_len = tlen(get_id_type(type_id));
1500
1501         /* I have no idea what the following does! */
1502         /* It appears to process target columns that will be receiving results */
1503         if (pstate->p_is_insert || pstate->p_is_update)
1504         {
1505
1506                 /*
1507                  * append or replace query -- append, replace work only on one
1508                  * relation, so multiple occurence of same resdomno is bogus
1509                  */
1510                 rd = pstate->p_target_relation;
1511                 Assert(rd != NULL);
1512                 resdomno = varattno(rd, colname);
1513                 attrisset = varisset(rd, colname);
1514                 attrtype = att_typeid(rd, resdomno);
1515                 if ((arrayRef != NIL) && (lfirst(arrayRef) == NIL))
1516                         attrtype = GetArrayElementType(attrtype);
1517                 if (attrtype == BPCHAROID || attrtype == VARCHAROID)
1518                 {
1519                         attrlen = rd->rd_att->attrs[resdomno - 1]->attlen;
1520                 }
1521                 else
1522                 {
1523                         attrlen = tlen(get_id_type(attrtype));
1524                 }
1525 #if 0
1526                 if (Input_is_string && Typecast_ok)
1527                 {
1528                         Datum           val;
1529
1530                         if (type_id == typeid(type("unknown")))
1531                         {
1532                                 val = (Datum) textout((struct varlena *)
1533                                                                           ((Const) lnext(expr))->constvalue);
1534                         }
1535                         else
1536                         {
1537                                 val = ((Const) lnext(expr))->constvalue;
1538                         }
1539                         if (attrisset)
1540                         {
1541                                 lnext(expr) = makeConst(attrtype,
1542                                                                                 attrlen,
1543                                                                                 val,
1544                                                                                 false,
1545                                                                                 true,
1546                                                                                 true,   /* is set */
1547                                                                                 false);
1548                         }
1549                         else
1550                         {
1551                                 lnext(expr) =
1552                                         makeConst(attrtype,
1553                                                           attrlen,
1554                                                           (Datum) fmgr(typeid_get_retinfunc(attrtype),
1555                                                                                  val, get_typelem(attrtype), -1),
1556                                                           false,
1557                                                           true /* Maybe correct-- 80% chance */ ,
1558                                                           false,        /* is not a set */
1559                                                           false);
1560                         }
1561                 }
1562                 else if ((Typecast_ok) && (attrtype != type_id))
1563                 {
1564                         lnext(expr) =
1565                                 parser_typecast2(expr, get_id_type(attrtype));
1566                 }
1567                 else if (attrtype != type_id)
1568                 {
1569                         if ((attrtype == INT2OID) && (type_id == INT4OID))
1570                                 lfirst(expr) = lispInteger(INT2OID);    /* handle CASHOID too */
1571                         else if ((attrtype == FLOAT4OID) && (type_id == FLOAT8OID))
1572                                 lfirst(expr) = lispInteger(FLOAT4OID);
1573                         else
1574                                 elog(WARN, "unequal type in tlist : %s \n", colname);
1575                 }
1576
1577                 Input_is_string = false;
1578                 Input_is_integer = false;
1579                 Typecast_ok = true;
1580 #endif
1581
1582                 if (attrtype != type_id)
1583                 {
1584                         if (IsA(expr, Const))
1585                         {
1586                                 /* try to cast the constant */
1587                                 if (arrayRef && !(((A_Indices *) lfirst(arrayRef))->lidx))
1588                                 {
1589                                         /* updating a single item */
1590                                         Oid                     typelem = get_typelem(attrtype);
1591
1592                                         expr = (Node *) parser_typecast2(expr,
1593                                                                                                          type_id,
1594                                                                                                          get_id_type(typelem),
1595                                                                                                          attrlen);
1596                                 }
1597                                 else
1598                                         expr = (Node *) parser_typecast2(expr,
1599                                                                                                          type_id,
1600                                                                                                    get_id_type(attrtype),
1601                                                                                                          attrlen);
1602                         }
1603                         else
1604                         {
1605                                 /* currently, we can't handle casting of expressions */
1606                                 elog(WARN, "parser: attribute '%s' is of type '%s' but expression is of type '%s'",
1607                                          colname,
1608                                          get_id_typname(attrtype),
1609                                          get_id_typname(type_id));
1610                         }
1611                 }
1612
1613                 if (arrayRef != NIL)
1614                 {
1615                         Expr       *target_expr;
1616                         Attr       *att = makeNode(Attr);
1617                         List       *ar = arrayRef;
1618                         List       *upperIndexpr = NIL;
1619                         List       *lowerIndexpr = NIL;
1620
1621                         att->relname = pstrdup(RelationGetRelationName(rd)->data);
1622                         att->attrs = lcons(makeString(colname), NIL);
1623                         target_expr = (Expr *) handleNestedDots(pstate, att,
1624                                                                                                   &pstate->p_last_resno);
1625                         while (ar != NIL)
1626                         {
1627                                 A_Indices  *ind = lfirst(ar);
1628
1629                                 if (lowerIndexpr || (!upperIndexpr && ind->lidx))
1630                                 {
1631
1632                                         /*
1633                                          * XXX assume all lowerIndexpr is non-null in this
1634                                          * case
1635                                          */
1636                                         lowerIndexpr = lappend(lowerIndexpr, ind->lidx);
1637                                 }
1638                                 upperIndexpr = lappend(upperIndexpr, ind->uidx);
1639                                 ar = lnext(ar);
1640                         }
1641
1642                         expr = (Node *) make_array_set(target_expr,
1643                                                                                    upperIndexpr,
1644                                                                                    lowerIndexpr,
1645                                                                                    (Expr *) expr);
1646                         attrtype = att_typeid(rd, resdomno);
1647                         attrlen = tlen(get_id_type(attrtype));
1648                 }
1649         }
1650         else
1651         {
1652                 resdomno = pstate->p_last_resno++;
1653                 attrtype = type_id;
1654                 attrlen = type_len;
1655         }
1656         tent = makeNode(TargetEntry);
1657
1658         resnode = makeResdom((AttrNumber) resdomno,
1659                                                  (Oid) attrtype,
1660                                                  (Size) attrlen,
1661                                                  colname,
1662                                                  (Index) 0,
1663                                                  (Oid) 0,
1664                                                  0);
1665
1666         tent->resdom = resnode;
1667         tent->expr = expr;
1668
1669         return tent;
1670 }
1671
1672
1673 /*****************************************************************************
1674  *
1675  * Where Clause
1676  *
1677  *****************************************************************************/
1678
1679 /*
1680  * transformWhereClause -
1681  *        transforms the qualification and make sure it is of type Boolean
1682  *
1683  */
1684 static Node *
1685 transformWhereClause(ParseState *pstate, Node *a_expr)
1686 {
1687         Node       *qual;
1688
1689         if (a_expr == NULL)
1690                 return (Node *) NULL;   /* no qualifiers */
1691
1692         inWhereClause = true;
1693         qual = transformExpr(pstate, a_expr, EXPR_COLUMN_FIRST);
1694         inWhereClause = false;
1695         if (exprType(qual) != BOOLOID)
1696         {
1697                 elog(WARN,
1698                          "where clause must return type bool, not %s",
1699                          tname(get_id_type(exprType(qual))));
1700         }
1701         return qual;
1702 }
1703
1704 /*****************************************************************************
1705  *
1706  * Sort Clause
1707  *
1708  *****************************************************************************/
1709
1710 /*
1711  *      find_targetlist_entry -
1712  *        returns the Resdom in the target list matching the specified varname
1713  *        and range
1714  *
1715  */
1716 static TargetEntry *
1717 find_targetlist_entry(ParseState *pstate, SortGroupBy *sortgroupby, List *tlist)
1718 {
1719         List       *i;
1720         int                     real_rtable_pos = 0,
1721                                 target_pos = 0;
1722         TargetEntry *target_result = NULL;
1723
1724         if (sortgroupby->range)
1725                 real_rtable_pos = refnameRangeTablePosn(pstate->p_rtable,
1726                                                                                                 sortgroupby->range);
1727
1728         foreach(i, tlist)
1729         {
1730                 TargetEntry *target = (TargetEntry *) lfirst(i);
1731                 Resdom     *resnode = target->resdom;
1732                 Var                *var = (Var *) target->expr;
1733                 char       *resname = resnode->resname;
1734                 int                     test_rtable_pos = var->varno;
1735
1736 #ifdef PARSEDEBUG
1737                 printf("find_targetlist_entry- target name is %s, position %d, resno %d\n",
1738                            (sortgroupby->name ? sortgroupby->name : "(null)"), target_pos + 1, sortgroupby->resno);
1739 #endif
1740
1741                 if (!sortgroupby->name)
1742                 {
1743                         if (sortgroupby->resno == ++target_pos)
1744                         {
1745                                 target_result = target;
1746                                 break;
1747                         }
1748                 }
1749                 else
1750                 {
1751                         if (!strcmp(resname, sortgroupby->name))
1752                         {
1753                                 if (sortgroupby->range)
1754                                 {
1755                                         if (real_rtable_pos == test_rtable_pos)
1756                                         {
1757                                                 if (target_result != NULL)
1758                                                         elog(WARN, "Order/Group By %s is ambiguous", sortgroupby->name);
1759                                                 else
1760                                                         target_result = target;
1761                                         }
1762                                 }
1763                                 else
1764                                 {
1765                                         if (target_result != NULL)
1766                                                 elog(WARN, "Order/Group By %s is ambiguous", sortgroupby->name);
1767                                         else
1768                                                 target_result = target;
1769                                 }
1770                         }
1771                 }
1772         }
1773         return target_result;
1774 }
1775
1776 static Oid
1777 any_ordering_op(int restype)
1778 {
1779         Operator        order_op;
1780         Oid                     order_opid;
1781
1782         order_op = oper("<", restype, restype, false);
1783         order_opid = oprid(order_op);
1784
1785         return order_opid;
1786 }
1787
1788 /*
1789  * transformGroupClause -
1790  *        transform a Group By clause
1791  *
1792  */
1793 static List *
1794 transformGroupClause(ParseState *pstate, List *grouplist, List *targetlist)
1795 {
1796         List       *glist = NIL,
1797                            *gl = NIL;
1798
1799         while (grouplist != NIL)
1800         {
1801                 GroupClause *grpcl = makeNode(GroupClause);
1802                 TargetEntry *restarget;
1803                 Resdom     *resdom;
1804
1805                 restarget = find_targetlist_entry(pstate, lfirst(grouplist), targetlist);
1806
1807                 if (restarget == NULL)
1808                         elog(WARN, "The field being grouped by must appear in the target list");
1809
1810                 grpcl->entry = restarget;
1811                 resdom = restarget->resdom;
1812                 grpcl->grpOpoid = oprid(oper("<",
1813                                                                          resdom->restype,
1814                                                                          resdom->restype, false));
1815                 if (glist == NIL)
1816                         gl = glist = lcons(grpcl, NIL);
1817                 else
1818                 {
1819                         List       *i;
1820                         
1821                         foreach (i, glist)
1822                         {
1823                                 GroupClause *gcl = (GroupClause *) lfirst (i);
1824                                 
1825                                 if ( gcl->entry == grpcl->entry )
1826                                         break;
1827                         }
1828                         if ( i == NIL )                 /* not in grouplist already */
1829                         {
1830                                 lnext(gl) = lcons(grpcl, NIL);
1831                                 gl = lnext(gl);
1832                         }
1833                         else
1834                                 pfree (grpcl);          /* get rid of this */
1835                 }
1836                 grouplist = lnext(grouplist);
1837         }
1838
1839         return glist;
1840 }
1841
1842 /*
1843  * transformSortClause -
1844  *        transform an Order By clause
1845  *
1846  */
1847 static List *
1848 transformSortClause(ParseState *pstate,
1849                                         List *orderlist, List *targetlist,
1850                                         char *uniqueFlag)
1851 {
1852         List       *sortlist = NIL;
1853         List       *s = NIL;
1854
1855         while (orderlist != NIL)
1856         {
1857                 SortGroupBy *sortby = lfirst(orderlist);
1858                 SortClause *sortcl = makeNode(SortClause);
1859                 TargetEntry *restarget;
1860                 Resdom     *resdom;
1861
1862                 restarget = find_targetlist_entry(pstate, sortby, targetlist);
1863                 if (restarget == NULL)
1864                         elog(WARN, "The field being ordered by must appear in the target list");
1865
1866                 sortcl->resdom = resdom = restarget->resdom;
1867                 sortcl->opoid = oprid(oper(sortby->useOp,
1868                                                                    resdom->restype,
1869                                                                    resdom->restype, false));
1870                 if (sortlist == NIL)
1871                 {
1872                         s = sortlist = lcons(sortcl, NIL);
1873                 }
1874                 else
1875                 {
1876                         List       *i;
1877                         
1878                         foreach (i, sortlist)
1879                         {
1880                                 SortClause *scl = (SortClause *) lfirst (i);
1881                                 
1882                                 if ( scl->resdom == sortcl->resdom )
1883                                         break;
1884                         }
1885                         if ( i == NIL )                 /* not in sortlist already */
1886                         {
1887                                 lnext(s) = lcons(sortcl, NIL);
1888                                 s = lnext(s);
1889                         }
1890                         else
1891                                 pfree (sortcl);         /* get rid of this */
1892                 }
1893                 orderlist = lnext(orderlist);
1894         }
1895
1896         if (uniqueFlag)
1897         {
1898                 List       *i;
1899                 
1900                 if (uniqueFlag[0] == '*')
1901                 {
1902
1903                         /*
1904                          * concatenate all elements from target list that are not
1905                          * already in the sortby list
1906                          */
1907                         foreach(i, targetlist)
1908                         {
1909                                 TargetEntry *tlelt = (TargetEntry *) lfirst(i);
1910
1911                                 s = sortlist;
1912                                 while (s != NIL)
1913                                 {
1914                                         SortClause *sortcl = lfirst(s);
1915
1916                                         if (sortcl->resdom == tlelt->resdom)
1917                                                 break;
1918                                         s = lnext(s);
1919                                 }
1920                                 if (s == NIL)
1921                                 {
1922                                         /* not a member of the sortclauses yet */
1923                                         SortClause *sortcl = makeNode(SortClause);
1924
1925                                         sortcl->resdom = tlelt->resdom;
1926                                         sortcl->opoid = any_ordering_op(tlelt->resdom->restype);
1927
1928                                         sortlist = lappend(sortlist, sortcl);
1929                                 }
1930                         }
1931                 }
1932                 else
1933                 {
1934                         TargetEntry *tlelt = NULL;
1935                         char       *uniqueAttrName = uniqueFlag;
1936
1937                         /* only create sort clause with the specified unique attribute */
1938                         foreach(i, targetlist)
1939                         {
1940                                 tlelt = (TargetEntry *) lfirst(i);
1941                                 if (strcmp(tlelt->resdom->resname, uniqueAttrName) == 0)
1942                                         break;
1943                         }
1944                         if (i == NIL)
1945                         {
1946                                 elog(WARN, "The field specified in the UNIQUE ON clause is not in the targetlist");
1947                         }
1948                         s = sortlist;
1949                         foreach(s, sortlist)
1950                         {
1951                                 SortClause *sortcl = lfirst(s);
1952
1953                                 if (sortcl->resdom == tlelt->resdom)
1954                                         break;
1955                         }
1956                         if (s == NIL)
1957                         {
1958                                 /* not a member of the sortclauses yet */
1959                                 SortClause *sortcl = makeNode(SortClause);
1960
1961                                 sortcl->resdom = tlelt->resdom;
1962                                 sortcl->opoid = any_ordering_op(tlelt->resdom->restype);
1963
1964                                 sortlist = lappend(sortlist, sortcl);
1965                         }
1966                 }
1967
1968         }
1969
1970         return sortlist;
1971 }
1972
1973 /*
1974  ** HandleNestedDots --
1975  **    Given a nested dot expression (i.e. (relation func ... attr), build up
1976  ** a tree with of Iter and Func nodes.
1977  */
1978 static Node *
1979 handleNestedDots(ParseState *pstate, Attr *attr, int *curr_resno)
1980 {
1981         List       *mutator_iter;
1982         Node       *retval = NULL;
1983
1984         if (attr->paramNo != NULL)
1985         {
1986                 Param      *param = (Param *) transformExpr(pstate, (Node *) attr->paramNo, EXPR_RELATION_FIRST);
1987
1988                 retval =
1989                         ParseFunc(pstate, strVal(lfirst(attr->attrs)),
1990                                           lcons(param, NIL),
1991                                           curr_resno);
1992         }
1993         else
1994         {
1995                 Ident      *ident = makeNode(Ident);
1996
1997                 ident->name = attr->relname;
1998                 ident->isRel = TRUE;
1999                 retval =
2000                         ParseFunc(pstate, strVal(lfirst(attr->attrs)),
2001                                           lcons(ident, NIL),
2002                                           curr_resno);
2003         }
2004
2005         foreach(mutator_iter, lnext(attr->attrs))
2006         {
2007                 retval = ParseFunc(pstate, strVal(lfirst(mutator_iter)),
2008                                                    lcons(retval, NIL),
2009                                                    curr_resno);
2010         }
2011
2012         return (retval);
2013 }
2014
2015 /*
2016  ** make_arguments --
2017  **   Given the number and types of arguments to a function, and the
2018  **   actual arguments and argument types, do the necessary typecasting.
2019  */
2020 static void
2021 make_arguments(int nargs,
2022                            List *fargs,
2023                            Oid *input_typeids,
2024                            Oid *function_typeids)
2025 {
2026
2027         /*
2028          * there are two ways an input typeid can differ from a function
2029          * typeid : either the input type inherits the function type, so no
2030          * typecasting is necessary, or the input type can be typecast into
2031          * the function type. right now, we only typecast unknowns, and that
2032          * is all we check for.
2033          */
2034
2035         List       *current_fargs;
2036         int                     i;
2037
2038         for (i = 0, current_fargs = fargs;
2039                  i < nargs;
2040                  i++, current_fargs = lnext(current_fargs))
2041         {
2042
2043                 if (input_typeids[i] == UNKNOWNOID && function_typeids[i] != InvalidOid)
2044                 {
2045                         lfirst(current_fargs) =
2046                                 parser_typecast2(lfirst(current_fargs),
2047                                                                  input_typeids[i],
2048                                                                  get_id_type(function_typeids[i]),
2049                                                                  -1);
2050                 }
2051         }
2052 }
2053
2054 /*
2055  ** setup_tlist --
2056  **             Build a tlist that says which attribute to project to.
2057  **             This routine is called by ParseFunc() to set up a target list
2058  **             on a tuple parameter or return value.  Due to a bug in 4.0,
2059  **             it's not possible to refer to system attributes in this case.
2060  */
2061 static List *
2062 setup_tlist(char *attname, Oid relid)
2063 {
2064         TargetEntry *tle;
2065         Resdom     *resnode;
2066         Var                *varnode;
2067         Oid                     typeid;
2068         int                     attno;
2069
2070         attno = get_attnum(relid, attname);
2071         if (attno < 0)
2072                 elog(WARN, "cannot reference attribute %s of tuple params/return values for functions", attname);
2073
2074         typeid = find_atttype(relid, attname);
2075         resnode = makeResdom(1,
2076                                                  typeid,
2077                                                  tlen(get_id_type(typeid)),
2078                                                  get_attname(relid, attno),
2079                                                  0,
2080                                                  (Oid) 0,
2081                                                  0);
2082         varnode = makeVar(-1, attno, typeid, -1, attno);
2083
2084         tle = makeNode(TargetEntry);
2085         tle->resdom = resnode;
2086         tle->expr = (Node *) varnode;
2087         return (lcons(tle, NIL));
2088 }
2089
2090 /*
2091  ** setup_base_tlist --
2092  **             Build a tlist that extracts a base type from the tuple
2093  **             returned by the executor.
2094  */
2095 static List *
2096 setup_base_tlist(Oid typeid)
2097 {
2098         TargetEntry *tle;
2099         Resdom     *resnode;
2100         Var                *varnode;
2101
2102         resnode = makeResdom(1,
2103                                                  typeid,
2104                                                  tlen(get_id_type(typeid)),
2105                                                  "<noname>",
2106                                                  0,
2107                                                  (Oid) 0,
2108                                                  0);
2109         varnode = makeVar(-1, 1, typeid, -1, 1);
2110         tle = makeNode(TargetEntry);
2111         tle->resdom = resnode;
2112         tle->expr = (Node *) varnode;
2113
2114         return (lcons(tle, NIL));
2115 }
2116
2117 /*
2118  * ParseComplexProjection -
2119  *        handles function calls with a single argument that is of complex type.
2120  *        This routine returns NULL if it can't handle the projection (eg. sets).
2121  */
2122 static Node *
2123 ParseComplexProjection(ParseState *pstate,
2124                                            char *funcname,
2125                                            Node *first_arg,
2126                                            bool *attisset)
2127 {
2128         Oid                     argtype;
2129         Oid                     argrelid;
2130         Name            relname;
2131         Relation        rd;
2132         Oid                     relid;
2133         int                     attnum;
2134
2135         switch (nodeTag(first_arg))
2136         {
2137                 case T_Iter:
2138                         {
2139                                 Func       *func;
2140                                 Iter       *iter;
2141
2142                                 iter = (Iter *) first_arg;
2143                                 func = (Func *) ((Expr *) iter->iterexpr)->oper;
2144                                 argtype = funcid_get_rettype(func->funcid);
2145                                 argrelid = typeid_get_relid(argtype);
2146                                 if (argrelid &&
2147                                         ((attnum = get_attnum(argrelid, funcname))
2148                                          != InvalidAttrNumber))
2149                                 {
2150
2151                                         /*
2152                                          * the argument is a function returning a tuple, so
2153                                          * funcname may be a projection
2154                                          */
2155
2156                                         /* add a tlist to the func node and return the Iter */
2157                                         rd = heap_openr(tname(get_id_type(argtype)));
2158                                         if (RelationIsValid(rd))
2159                                         {
2160                                                 relid = RelationGetRelationId(rd);
2161                                                 relname = RelationGetRelationName(rd);
2162                                                 heap_close(rd);
2163                                         }
2164                                         if (RelationIsValid(rd))
2165                                         {
2166                                                 func->func_tlist =
2167                                                         setup_tlist(funcname, argrelid);
2168                                                 iter->itertype = att_typeid(rd, attnum);
2169                                                 return ((Node *) iter);
2170                                         }
2171                                         else
2172                                         {
2173                                                 elog(WARN,
2174                                                          "Function %s has bad returntype %d",
2175                                                          funcname, argtype);
2176                                         }
2177                                 }
2178                                 else
2179                                 {
2180                                         /* drop through */
2181                                         ;
2182                                 }
2183                                 break;
2184                         }
2185                 case T_Var:
2186                         {
2187
2188                                 /*
2189                                  * The argument is a set, so this is either a projection
2190                                  * or a function call on this set.
2191                                  */
2192                                 *attisset = true;
2193                                 break;
2194                         }
2195                 case T_Expr:
2196                         {
2197                                 Expr       *expr = (Expr *) first_arg;
2198                                 Func       *funcnode;
2199
2200                                 if (expr->opType != FUNC_EXPR)
2201                                         break;
2202
2203                                 funcnode = (Func *) expr->oper;
2204                                 argtype = funcid_get_rettype(funcnode->funcid);
2205                                 argrelid = typeid_get_relid(argtype);
2206
2207                                 /*
2208                                  * the argument is a function returning a tuple, so
2209                                  * funcname may be a projection
2210                                  */
2211                                 if (argrelid &&
2212                                         (attnum = get_attnum(argrelid, funcname))
2213                                         != InvalidAttrNumber)
2214                                 {
2215
2216                                         /* add a tlist to the func node */
2217                                         rd = heap_openr(tname(get_id_type(argtype)));
2218                                         if (RelationIsValid(rd))
2219                                         {
2220                                                 relid = RelationGetRelationId(rd);
2221                                                 relname = RelationGetRelationName(rd);
2222                                                 heap_close(rd);
2223                                         }
2224                                         if (RelationIsValid(rd))
2225                                         {
2226                                                 Expr       *newexpr;
2227
2228                                                 funcnode->func_tlist =
2229                                                         setup_tlist(funcname, argrelid);
2230                                                 funcnode->functype = att_typeid(rd, attnum);
2231
2232                                                 newexpr = makeNode(Expr);
2233                                                 newexpr->typeOid = funcnode->functype;
2234                                                 newexpr->opType = FUNC_EXPR;
2235                                                 newexpr->oper = (Node *) funcnode;
2236                                                 newexpr->args = lcons(first_arg, NIL);
2237
2238                                                 return ((Node *) newexpr);
2239                                         }
2240
2241                                 }
2242
2243                                 elog(WARN, "Function %s has bad returntype %d",
2244                                          funcname, argtype);
2245                                 break;
2246                         }
2247                 case T_Param:
2248                         {
2249                                 Param      *param = (Param *) first_arg;
2250
2251                                 /*
2252                                  * If the Param is a complex type, this could be a
2253                                  * projection
2254                                  */
2255                                 rd = heap_openr(tname(get_id_type(param->paramtype)));
2256                                 if (RelationIsValid(rd))
2257                                 {
2258                                         relid = RelationGetRelationId(rd);
2259                                         relname = RelationGetRelationName(rd);
2260                                         heap_close(rd);
2261                                 }
2262                                 if (RelationIsValid(rd) &&
2263                                         (attnum = get_attnum(relid, funcname))
2264                                         != InvalidAttrNumber)
2265                                 {
2266
2267                                         param->paramtype = att_typeid(rd, attnum);
2268                                         param->param_tlist = setup_tlist(funcname, relid);
2269                                         return ((Node *) param);
2270                                 }
2271                                 break;
2272                         }
2273                 default:
2274                         break;
2275         }
2276
2277         return NULL;
2278 }
2279
2280 static Node *
2281 ParseFunc(ParseState *pstate, char *funcname, List *fargs, int *curr_resno)
2282 {
2283         Oid                     rettype = (Oid) 0;
2284         Oid                     argrelid = (Oid) 0;
2285         Oid                     funcid = (Oid) 0;
2286         List       *i = NIL;
2287         Node       *first_arg = NULL;
2288         char       *relname = NULL;
2289         char       *refname = NULL;
2290         Relation        rd;
2291         Oid                     relid;
2292         int                     nargs;
2293         Func       *funcnode;
2294         Oid                     oid_array[8];
2295         Oid                *true_oid_array;
2296         Node       *retval;
2297         bool            retset;
2298         bool            exists;
2299         bool            attisset = false;
2300         Oid                     toid = (Oid) 0;
2301         Expr       *expr;
2302
2303         if (fargs)
2304         {
2305                 first_arg = lfirst(fargs);
2306                 if (first_arg == NULL)
2307                         elog(WARN, "function %s does not allow NULL input", funcname);
2308         }
2309
2310         /*
2311          * * check for projection methods: if function takes one argument, and *
2312          * that argument is a relation, param, or PQ function returning a
2313          * complex * type, then the function could be a projection.
2314          */
2315         if (length(fargs) == 1)
2316         {
2317
2318                 if (nodeTag(first_arg) == T_Ident && ((Ident *) first_arg)->isRel)
2319                 {
2320                         RangeTblEntry *rte;
2321                         Ident      *ident = (Ident *) first_arg;
2322
2323                         /*
2324                          * first arg is a relation. This could be a projection.
2325                          */
2326                         refname = ident->name;
2327
2328                         rte = refnameRangeTableEntry(pstate->p_rtable, refname);
2329                         if (rte == NULL)
2330                                 rte = addRangeTableEntry(pstate, refname, refname, FALSE, FALSE, NULL);
2331
2332                         relname = rte->relname;
2333                         relid = rte->relid;
2334
2335                         /*
2336                          * If the attr isn't a set, just make a var for it.  If it is
2337                          * a set, treat it like a function and drop through.
2338                          */
2339                         if (get_attnum(relid, funcname) != InvalidAttrNumber)
2340                         {
2341                                 Oid                     dummyTypeId;
2342
2343                                 return
2344                                         ((Node *) make_var(pstate,
2345                                                                            refname,
2346                                                                            funcname,
2347                                                                            &dummyTypeId));
2348                         }
2349                         else
2350                         {
2351                                 /* drop through - attr is a set */
2352                                 ;
2353                         }
2354                 }
2355                 else if (ISCOMPLEX(exprType(first_arg)))
2356                 {
2357
2358                         /*
2359                          * Attempt to handle projection of a complex argument. If
2360                          * ParseComplexProjection can't handle the projection, we have
2361                          * to keep going.
2362                          */
2363                         retval = ParseComplexProjection(pstate,
2364                                                                                         funcname,
2365                                                                                         first_arg,
2366                                                                                         &attisset);
2367                         if (attisset)
2368                         {
2369                                 toid = exprType(first_arg);
2370                                 rd = heap_openr(tname(get_id_type(toid)));
2371                                 if (RelationIsValid(rd))
2372                                 {
2373                                         relname = RelationGetRelationName(rd)->data;
2374                                         heap_close(rd);
2375                                 }
2376                                 else
2377                                         elog(WARN,
2378                                                  "Type %s is not a relation type",
2379                                                  tname(get_id_type(toid)));
2380                                 argrelid = typeid_get_relid(toid);
2381
2382                                 /*
2383                                  * A projection contains either an attribute name or the
2384                                  * "*".
2385                                  */
2386                                 if ((get_attnum(argrelid, funcname) == InvalidAttrNumber)
2387                                         && strcmp(funcname, "*"))
2388                                 {
2389                                         elog(WARN, "Functions on sets are not yet supported");
2390                                 }
2391                         }
2392
2393                         if (retval)
2394                                 return retval;
2395                 }
2396                 else
2397                 {
2398
2399                         /*
2400                          * Parsing aggregates.
2401                          */
2402                         Oid                     basetype;
2403
2404                         /*
2405                          * the aggregate count is a special case, ignore its base
2406                          * type.  Treat it as zero
2407                          */
2408                         if (strcmp(funcname, "count") == 0)
2409                                 basetype = 0;
2410                         else
2411                                 basetype = exprType(lfirst(fargs));
2412                         if (SearchSysCacheTuple(AGGNAME,
2413                                                                         PointerGetDatum(funcname),
2414                                                                         ObjectIdGetDatum(basetype),
2415                                                                         0, 0))
2416                         {
2417                                 Aggreg     *aggreg = ParseAgg(funcname, basetype, lfirst(fargs));
2418
2419                                 AddAggToParseState(pstate, aggreg);
2420                                 return (Node *) aggreg;
2421                         }
2422                 }
2423         }
2424
2425
2426         /*
2427          * * If we dropped through to here it's really a function (or a set,
2428          * which * is implemented as a function.) * extract arg type info and
2429          * transform relation name arguments into * varnodes of the
2430          * appropriate form.
2431          */
2432         MemSet(&oid_array[0], 0, 8 * sizeof(Oid));
2433
2434         nargs = 0;
2435         foreach(i, fargs)
2436         {
2437                 int                     vnum;
2438                 RangeTblEntry *rte;
2439                 Node       *pair = lfirst(i);
2440
2441                 if (nodeTag(pair) == T_Ident && ((Ident *) pair)->isRel)
2442                 {
2443
2444                         /*
2445                          * a relation
2446                          */
2447                         refname = ((Ident *) pair)->name;
2448
2449                         rte = refnameRangeTableEntry(pstate->p_rtable, refname);
2450                         if (rte == NULL)
2451                                 rte = addRangeTableEntry(pstate, refname, refname,
2452                                                                                  FALSE, FALSE, NULL);
2453                         relname = rte->relname;
2454
2455                         vnum = refnameRangeTablePosn(pstate->p_rtable, rte->refname);
2456
2457                         /*
2458                          * for func(relname), the param to the function is the tuple
2459                          * under consideration.  we build a special VarNode to reflect
2460                          * this -- it has varno set to the correct range table entry,
2461                          * but has varattno == 0 to signal that the whole tuple is the
2462                          * argument.
2463                          */
2464                         toid = typeid(type(relname));
2465                         /* replace it in the arg list */
2466                         lfirst(fargs) =
2467                                 makeVar(vnum, 0, toid, vnum, 0);
2468                 }
2469                 else if (!attisset)
2470                 {                                               /* set functions don't have parameters */
2471
2472                         /*
2473                          * any functiona args which are typed "unknown", but aren't
2474                          * constants, we don't know what to do with, because we can't
2475                          * cast them    - jolly
2476                          */
2477                         if (exprType(pair) == UNKNOWNOID &&
2478                                 !IsA(pair, Const))
2479                         {
2480                                 elog(WARN, "ParseFunc: no function named %s that takes in an unknown type as argument #%d", funcname, nargs);
2481                         }
2482                         else
2483                                 toid = exprType(pair);
2484                 }
2485
2486                 oid_array[nargs++] = toid;
2487         }
2488
2489         /*
2490          * func_get_detail looks up the function in the catalogs, does
2491          * disambiguation for polymorphic functions, handles inheritance, and
2492          * returns the funcid and type and set or singleton status of the
2493          * function's return value.  it also returns the true argument types
2494          * to the function.  if func_get_detail returns true, the function
2495          * exists.      otherwise, there was an error.
2496          */
2497         if (attisset)
2498         {                                                       /* we know all of these fields already */
2499
2500                 /*
2501                  * We create a funcnode with a placeholder function SetEval.
2502                  * SetEval() never actually gets executed.      When the function
2503                  * evaluation routines see it, they use the funcid projected out
2504                  * from the relation as the actual function to call. Example:
2505                  * retrieve (emp.mgr.name) The plan for this will scan the emp
2506                  * relation, projecting out the mgr attribute, which is a funcid.
2507                  * This function is then called (instead of SetEval) and "name" is
2508                  * projected from its result.
2509                  */
2510                 funcid = SetEvalRegProcedure;
2511                 rettype = toid;
2512                 retset = true;
2513                 true_oid_array = oid_array;
2514                 exists = true;
2515         }
2516         else
2517         {
2518                 exists = func_get_detail(funcname, nargs, oid_array, &funcid,
2519                                                                  &rettype, &retset, &true_oid_array);
2520         }
2521
2522         if (!exists)
2523                 elog(WARN, "no such attribute or function %s", funcname);
2524
2525         /* got it */
2526         funcnode = makeNode(Func);
2527         funcnode->funcid = funcid;
2528         funcnode->functype = rettype;
2529         funcnode->funcisindex = false;
2530         funcnode->funcsize = 0;
2531         funcnode->func_fcache = NULL;
2532         funcnode->func_tlist = NIL;
2533         funcnode->func_planlist = NIL;
2534
2535         /* perform the necessary typecasting */
2536         make_arguments(nargs, fargs, oid_array, true_oid_array);
2537
2538         /*
2539          * for functions returning base types, we want to project out the
2540          * return value.  set up a target list to do that.      the executor will
2541          * ignore these for c functions, and do the right thing for postquel
2542          * functions.
2543          */
2544
2545         if (typeid_get_relid(rettype) == InvalidOid)
2546                 funcnode->func_tlist = setup_base_tlist(rettype);
2547
2548         /*
2549          * For sets, we want to make a targetlist to project out this
2550          * attribute of the set tuples.
2551          */
2552         if (attisset)
2553         {
2554                 if (!strcmp(funcname, "*"))
2555                 {
2556                         funcnode->func_tlist =
2557                                 expandAll(pstate, relname, refname, curr_resno);
2558                 }
2559                 else
2560                 {
2561                         funcnode->func_tlist = setup_tlist(funcname, argrelid);
2562                         rettype = find_atttype(argrelid, funcname);
2563                 }
2564         }
2565
2566         /*
2567          * Sequence handling.
2568          */
2569         if (funcid == SeqNextValueRegProcedure ||
2570                 funcid == SeqCurrValueRegProcedure)
2571         {
2572                 Const      *seq;
2573                 char       *seqrel;
2574                 text       *seqname;
2575                 int32           aclcheck_result = -1;
2576                 extern text *lower (text *string);
2577
2578                 Assert(length(fargs) == 1);
2579                 seq = (Const *) lfirst(fargs);
2580                 if (!IsA((Node *) seq, Const))
2581                         elog(WARN, "%s: only constant sequence names are acceptable", funcname);
2582                 seqname = lower ((text*)DatumGetPointer(seq->constvalue));
2583                 pfree (DatumGetPointer(seq->constvalue));
2584                 seq->constvalue = PointerGetDatum (seqname);
2585                 seqrel = textout(seqname);
2586
2587                 if ((aclcheck_result = pg_aclcheck(seqrel, GetPgUserName(),
2588                            ((funcid == SeqNextValueRegProcedure) ? ACL_WR : ACL_RD)))
2589                         != ACLCHECK_OK)
2590                         elog(WARN, "%s.%s: %s",
2591                           seqrel, funcname, aclcheck_error_strings[aclcheck_result]);
2592
2593                 pfree(seqrel);
2594
2595                 if (funcid == SeqNextValueRegProcedure && inWhereClause)
2596                         elog(WARN, "nextval of a sequence in WHERE disallowed");
2597         }
2598
2599         expr = makeNode(Expr);
2600         expr->typeOid = rettype;
2601         expr->opType = FUNC_EXPR;
2602         expr->oper = (Node *) funcnode;
2603         expr->args = fargs;
2604         retval = (Node *) expr;
2605
2606         /*
2607          * if the function returns a set of values, then we need to iterate
2608          * over all the returned values in the executor, so we stick an iter
2609          * node here.  if it returns a singleton, then we don't need the iter
2610          * node.
2611          */
2612
2613         if (retset)
2614         {
2615                 Iter       *iter = makeNode(Iter);
2616
2617                 iter->itertype = rettype;
2618                 iter->iterexpr = retval;
2619                 retval = (Node *) iter;
2620         }
2621
2622         return (retval);
2623 }
2624
2625 /*****************************************************************************
2626  *
2627  *****************************************************************************/
2628
2629 /*
2630  * AddAggToParseState -
2631  *        add the aggregate to the list of unique aggregates in pstate.
2632  *
2633  * SIDE EFFECT: aggno in target list entry will be modified
2634  */
2635 static void
2636 AddAggToParseState(ParseState *pstate, Aggreg *aggreg)
2637 {
2638         List       *ag;
2639         int                     i;
2640
2641         /*
2642          * see if we have the aggregate already (we only need to record the
2643          * aggregate once)
2644          */
2645         i = 0;
2646         foreach(ag, pstate->p_aggs)
2647         {
2648                 Aggreg     *a = lfirst(ag);
2649
2650                 if (!strcmp(a->aggname, aggreg->aggname) &&
2651                         equal(a->target, aggreg->target))
2652                 {
2653
2654                         /* fill in the aggno and we're done */
2655                         aggreg->aggno = i;
2656                         return;
2657                 }
2658                 i++;
2659         }
2660
2661         /* not found, new aggregate */
2662         aggreg->aggno = i;
2663         pstate->p_numAgg++;
2664         pstate->p_aggs = lappend(pstate->p_aggs, aggreg);
2665         return;
2666 }
2667
2668 /*
2669  * finalizeAggregates -
2670  *        fill in qry_aggs from pstate. Also checks to make sure that aggregates
2671  *        are used in the proper place.
2672  */
2673 static void
2674 finalizeAggregates(ParseState *pstate, Query *qry)
2675 {
2676         List       *l;
2677         int                     i;
2678
2679         parseCheckAggregates(pstate, qry);
2680
2681         qry->qry_numAgg = pstate->p_numAgg;
2682         qry->qry_aggs =
2683                 (Aggreg **) palloc(sizeof(Aggreg *) * qry->qry_numAgg);
2684         i = 0;
2685         foreach(l, pstate->p_aggs)
2686                 qry->qry_aggs[i++] = (Aggreg *) lfirst(l);
2687 }
2688
2689 /*
2690  * contain_agg_clause--
2691  *        Recursively find aggreg nodes from a clause.
2692  *
2693  *        Returns true if any aggregate found.
2694  */
2695 static bool
2696 contain_agg_clause(Node *clause)
2697 {
2698         if (clause == NULL)
2699                 return FALSE;
2700         else if (IsA(clause, Aggreg))
2701                 return TRUE;
2702         else if (IsA(clause, Iter))
2703                 return contain_agg_clause(((Iter *) clause)->iterexpr);
2704         else if (single_node(clause))
2705                 return FALSE;
2706         else if (or_clause(clause))
2707         {
2708                 List       *temp;
2709
2710                 foreach(temp, ((Expr *) clause)->args)
2711                         if (contain_agg_clause(lfirst(temp)))
2712                         return TRUE;
2713                 return FALSE;
2714         }
2715         else if (is_funcclause(clause))
2716         {
2717                 List       *temp;
2718
2719                 foreach(temp, ((Expr *) clause)->args)
2720                         if (contain_agg_clause(lfirst(temp)))
2721                         return TRUE;
2722                 return FALSE;
2723         }
2724         else if (IsA(clause, ArrayRef))
2725         {
2726                 List       *temp;
2727
2728                 foreach(temp, ((ArrayRef *) clause)->refupperindexpr)
2729                         if (contain_agg_clause(lfirst(temp)))
2730                         return TRUE;
2731                 foreach(temp, ((ArrayRef *) clause)->reflowerindexpr)
2732                         if (contain_agg_clause(lfirst(temp)))
2733                         return TRUE;
2734                 if (contain_agg_clause(((ArrayRef *) clause)->refexpr))
2735                         return TRUE;
2736                 if (contain_agg_clause(((ArrayRef *) clause)->refassgnexpr))
2737                         return TRUE;
2738                 return FALSE;
2739         }
2740         else if (not_clause(clause))
2741                 return contain_agg_clause((Node *) get_notclausearg((Expr *) clause));
2742         else if (is_opclause(clause))
2743                 return (contain_agg_clause((Node *) get_leftop((Expr *) clause)) ||
2744                           contain_agg_clause((Node *) get_rightop((Expr *) clause)));
2745
2746         return FALSE;
2747 }
2748
2749 /*
2750  * exprIsAggOrGroupCol -
2751  *        returns true if the expression does not contain non-group columns.
2752  */
2753 static bool
2754 exprIsAggOrGroupCol(Node *expr, List *groupClause)
2755 {
2756         List       *gl;
2757
2758         if (expr == NULL || IsA(expr, Const) ||
2759                 IsA(expr, Param) ||IsA(expr, Aggreg))
2760                 return TRUE;
2761
2762         foreach(gl, groupClause)
2763         {
2764                 GroupClause *grpcl = lfirst(gl);
2765
2766                 if (equal(expr, grpcl->entry->expr))
2767                         return TRUE;
2768         }
2769
2770         if (IsA(expr, Expr))
2771         {
2772                 List       *temp;
2773
2774                 foreach(temp, ((Expr *) expr)->args)
2775                         if (!exprIsAggOrGroupCol(lfirst(temp), groupClause))
2776                         return FALSE;
2777                 return TRUE;
2778         }
2779
2780         return FALSE;
2781 }
2782
2783 /*
2784  * tleIsAggOrGroupCol -
2785  *        returns true if the TargetEntry is Agg or GroupCol.
2786  */
2787 static bool
2788 tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause)
2789 {
2790         Node       *expr = tle->expr;
2791         List       *gl;
2792
2793         if (expr == NULL || IsA(expr, Const) ||IsA(expr, Param))
2794                 return TRUE;
2795
2796         foreach(gl, groupClause)
2797         {
2798                 GroupClause *grpcl = lfirst(gl);
2799
2800                 if (tle->resdom->resno == grpcl->entry->resdom->resno)
2801                 {
2802                         if (contain_agg_clause((Node *) expr))
2803                                 elog(WARN, "parser: aggregates not allowed in GROUP BY clause");
2804                         return TRUE;
2805                 }
2806         }
2807
2808         if (IsA(expr, Aggreg))
2809                 return TRUE;
2810
2811         if (IsA(expr, Expr))
2812         {
2813                 List       *temp;
2814
2815                 foreach(temp, ((Expr *) expr)->args)
2816                         if (!exprIsAggOrGroupCol(lfirst(temp), groupClause))
2817                         return FALSE;
2818                 return TRUE;
2819         }
2820
2821         return FALSE;
2822 }
2823
2824 /*
2825  * parseCheckAggregates -
2826  *        this should really be done earlier but the current grammar
2827  *        cannot differentiate functions from aggregates. So we have do check
2828  *        here when the target list and the qualifications are finalized.
2829  */
2830 static void
2831 parseCheckAggregates(ParseState *pstate, Query *qry)
2832 {
2833         List       *tl;
2834
2835         Assert(pstate->p_numAgg > 0);
2836
2837         /*
2838          * aggregates never appear in WHERE clauses. (we have to check where
2839          * clause first because if there is an aggregate, the check for
2840          * non-group column in target list may fail.)
2841          */
2842         if (contain_agg_clause(qry->qual))
2843                 elog(WARN, "parser: aggregates not allowed in WHERE clause");
2844
2845         /*
2846          * the target list can only contain aggregates, group columns and
2847          * functions thereof.
2848          */
2849         foreach(tl, qry->targetList)
2850         {
2851                 TargetEntry *tle = lfirst(tl);
2852
2853                 if (!tleIsAggOrGroupCol(tle, qry->groupClause))
2854                         elog(WARN,
2855                                  "parser: illegal use of aggregates or non-group column in target list");
2856         }
2857
2858         /*
2859          * the expression specified in the HAVING clause has the same
2860          * restriction as those in the target list.
2861          */
2862 /*
2863  * Need to change here when we get HAVING works. Currently
2864  * qry->havingQual is NULL.             - vadim 04/05/97
2865         if (!exprIsAggOrGroupCol(qry->havingQual, qry->groupClause))
2866                 elog(WARN,
2867                          "parser: illegal use of aggregates or non-group column in HAVING clause");
2868  */
2869         return;
2870 }