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