OSDN Git Service

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