OSDN Git Service

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