]> granicus.if.org Git - postgresql/blob - src/backend/parser/analyze.c
This patch changes quite a few instances of references of Oid's
[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.18 1996/11/30 18:06:20 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      Oid type_id, attrtype;
1237      int type_len, attrlen;
1238      int resdomno;
1239      Relation rd;
1240      bool attrisset;
1241      TargetEntry *tent;
1242      Resdom *resnode;
1243      
1244      if (expr == NULL)
1245          elog(WARN, "make_targetlist_expr: invalid use of NULL expression");
1246
1247      type_id = exprType(expr);
1248      if (type_id == InvalidOid) {
1249          type_len = 0;
1250      } else
1251      type_len = tlen(get_id_type(type_id));
1252
1253      /* I have no idea what the following does! */
1254      /* It appears to process target columns that will be receiving results */
1255      if (pstate->p_is_insert||pstate->p_is_update) {
1256           /*
1257            * append or replace query -- 
1258            * append, replace work only on one relation,
1259            * so multiple occurence of same resdomno is bogus
1260            */
1261           rd = pstate->p_target_relation;
1262           Assert(rd != NULL);
1263           resdomno = varattno(rd,colname);
1264           attrisset = varisset(rd,colname);
1265           attrtype = att_typeid(rd,resdomno);
1266           if ((arrayRef != NIL) && (lfirst(arrayRef) == NIL))
1267                attrtype = GetArrayElementType(attrtype);
1268           if (attrtype==BPCHAROID || attrtype==VARCHAROID) {
1269               attrlen = rd->rd_att->attrs[resdomno-1]->attlen;
1270           } else {
1271               attrlen = tlen(get_id_type(attrtype));
1272           }
1273 #if 0
1274           if(Input_is_string && Typecast_ok){
1275                Datum val;
1276                if (type_id == typeid(type("unknown"))){
1277                     val = (Datum)textout((struct varlena *)
1278                                          ((Const)lnext(expr))->constvalue);
1279                }else{
1280                     val = ((Const)lnext(expr))->constvalue;
1281                }
1282                if (attrisset) {
1283                     lnext(expr) =  makeConst(attrtype,
1284                                            attrlen,
1285                                            val,
1286                                            false,
1287                                            true,
1288                                            true /* is set */);
1289                } else {
1290                     lnext(expr) = 
1291                          makeConst(attrtype, 
1292                                    attrlen,
1293                                    (Datum)fmgr(typeid_get_retinfunc(attrtype),
1294                                                val,get_typelem(attrtype),-1),
1295                                    false, 
1296                                    true /* Maybe correct-- 80% chance */,
1297                                    false /* is not a set */);
1298                }
1299           } else if((Typecast_ok) && (attrtype != type_id)){
1300                lnext(expr) = 
1301                     parser_typecast2(expr, get_id_type(attrtype));
1302           } else
1303                if (attrtype != type_id) {
1304                     if ((attrtype == INT2OID) && (type_id == INT4OID))
1305                          lfirst(expr) = lispInteger (INT2OID);
1306                     else if ((attrtype == FLOAT4OID) && (type_id == FLOAT8OID))
1307                          lfirst(expr) = lispInteger (FLOAT4OID);
1308                     else
1309                          elog(WARN, "unequal type in tlist : %s \n",
1310                               colname));
1311                }
1312           
1313           Input_is_string = false;
1314           Input_is_integer = false;
1315           Typecast_ok = true;
1316 #endif
1317
1318           if (attrtype != type_id) {
1319               if (IsA(expr,Const)) {
1320                   /* try to cast the constant */
1321                   if (arrayRef && !(((A_Indices *)lfirst(arrayRef))->lidx)) {
1322                       /* updating a single item */
1323                       Oid typelem = get_typelem(attrtype);
1324                       expr = (Node*)parser_typecast2(expr,
1325                                                    type_id,
1326                                                    get_id_type(typelem),
1327                                                    attrlen);
1328                   } else
1329                   expr = (Node*)parser_typecast2(expr,
1330                                                  type_id,
1331                                                  get_id_type(attrtype),
1332                                                  attrlen);
1333               } else {
1334                   /* currently, we can't handle casting of expressions */
1335                   elog(WARN, "parser: attribute '%s' is of type '%.*s' but expression is of type '%.*s'",
1336                        colname,
1337                        NAMEDATALEN, get_id_typname(attrtype),
1338                        NAMEDATALEN, get_id_typname(type_id));
1339               }
1340           }
1341
1342           if (arrayRef != NIL) {
1343                Expr *target_expr;
1344                Attr *att = makeNode(Attr);
1345                List *ar = arrayRef;
1346                List *upperIndexpr = NIL;
1347                List *lowerIndexpr = NIL;
1348
1349                att->relname = pstrdup(RelationGetRelationName(rd)->data);
1350                att->attrs = lcons(makeString(colname), NIL);
1351                target_expr = (Expr*)handleNestedDots(pstate, att,
1352                                                      &pstate->p_last_resno);
1353                while(ar!=NIL) {
1354                    A_Indices *ind = lfirst(ar);
1355                    if (lowerIndexpr || (!upperIndexpr && ind->lidx)) {
1356                        /* XXX assume all lowerIndexpr is non-null in
1357                         * this case
1358                         */
1359                        lowerIndexpr = lappend(lowerIndexpr, ind->lidx);
1360                    }
1361                    upperIndexpr = lappend(upperIndexpr, ind->uidx);
1362                    ar = lnext(ar);
1363                }
1364                
1365                expr = (Node*)make_array_set(target_expr,
1366                                             upperIndexpr,
1367                                             lowerIndexpr,
1368                                             (Expr*)expr);       
1369                attrtype = att_typeid(rd,resdomno);
1370                attrlen = tlen(get_id_type(attrtype)); 
1371           }
1372      } else {
1373           resdomno = pstate->p_last_resno++;
1374           attrtype = type_id;
1375           attrlen = type_len;
1376      }
1377      tent = makeNode(TargetEntry);
1378
1379      resnode = makeResdom((AttrNumber)resdomno,
1380                           (Oid) attrtype,
1381                           (Size) attrlen,
1382                           colname, 
1383                           (Index)0,
1384                           (Oid)0,
1385                           0);
1386
1387      tent->resdom = resnode;
1388      tent->expr = expr;
1389          
1390      return  tent;
1391  }
1392
1393
1394 /*****************************************************************************
1395  *
1396  * Where Clause
1397  *
1398  *****************************************************************************/
1399
1400 /*
1401  * transformWhereClause -
1402  *    transforms the qualification and make sure it is of type Boolean
1403  *
1404  */
1405 static Node *
1406 transformWhereClause(ParseState *pstate, Node *a_expr)
1407 {
1408     Node *qual;
1409
1410     if (a_expr == NULL)
1411         return (Node *)NULL;            /* no qualifiers */
1412
1413     qual = transformExpr(pstate, a_expr);
1414     if (exprType(qual) != BOOLOID) {
1415         elog(WARN,
1416              "where clause must return type bool, not %s",
1417              tname(get_id_type(exprType(qual))));
1418     }
1419     return qual;
1420 }
1421
1422 /*****************************************************************************
1423  *
1424  * Sort Clause
1425  *
1426  *****************************************************************************/
1427
1428 /*
1429  *  find_tl_elt -
1430  *    returns the Resdom in the target list matching the specified varname
1431  *    and range
1432  *
1433  */
1434 static Resdom *
1435 find_tl_elt(ParseState *pstate, char *refname, char *colname, List *tlist)
1436 {
1437     List *i;
1438     int real_rtable_pos = 0;
1439
1440     if(refname)
1441         real_rtable_pos = refnameRangeTablePosn(pstate->p_rtable, refname);
1442
1443     foreach(i, tlist) {
1444         TargetEntry *target = (TargetEntry *)lfirst(i);
1445         Resdom *resnode = target->resdom;
1446         Var *var = (Var *)target->expr;
1447         char *resname = resnode->resname;
1448         int test_rtable_pos = var->varno;
1449
1450         if (!strcmp(resname, colname)) {
1451             if(refname) {
1452                 if(real_rtable_pos == test_rtable_pos) {
1453                     return (resnode);
1454                 }
1455             } else {
1456                 return (resnode);
1457             }
1458         }
1459     }
1460     return ((Resdom *)NULL);
1461 }
1462
1463 static Oid
1464 any_ordering_op(int restype)
1465 {
1466     Operator order_op;
1467     Oid order_opid;
1468     
1469     order_op = oper("<",restype,restype);
1470     order_opid = oprid(order_op);
1471     
1472     return order_opid;
1473 }
1474
1475 /*
1476  * transformGroupClause -
1477  *    transform an Group By clause
1478  *
1479  */
1480 static List *
1481 transformGroupClause(ParseState *pstate, List *grouplist)
1482 {
1483     List *glist = NIL, *gl = NIL;
1484
1485     while (grouplist != NIL) {
1486         GroupClause *grpcl = makeNode(GroupClause);
1487         Var *groupAttr = (Var*)transformExpr(pstate, (Node*)lfirst(grouplist));
1488
1489         if (nodeTag(groupAttr) != T_Var) {
1490             elog(WARN, "parser: can only specify attribute in group by");
1491         }
1492         grpcl->grpAttr = groupAttr;
1493         grpcl->grpOpoid = any_ordering_op(groupAttr->vartype);
1494         if (glist == NIL) {
1495             gl = glist = lcons(grpcl, NIL);
1496         } else {
1497             lnext(gl) = lcons(grpcl, NIL);
1498             gl = lnext(gl);
1499         }
1500         grouplist = lnext(grouplist);
1501     }
1502
1503     return glist;
1504 }
1505
1506 /*
1507  * transformSortClause -
1508  *    transform an Order By clause
1509  *
1510  */
1511 static List *
1512 transformSortClause(ParseState *pstate,
1513                     List *orderlist, List *targetlist,
1514                     char* uniqueFlag)
1515 {
1516     List *sortlist = NIL;
1517     List *s = NIL, *i;
1518
1519     while(orderlist != NIL) {
1520         SortBy *sortby = lfirst(orderlist);
1521         SortClause *sortcl = makeNode(SortClause);
1522         Resdom *resdom;
1523         
1524         resdom = find_tl_elt(pstate, sortby->range, sortby->name, targetlist);
1525         if (resdom == NULL)
1526             elog(WARN,"The field being sorted by must appear in the target list");
1527         
1528         sortcl->resdom = resdom;
1529         sortcl->opoid = oprid(oper(sortby->useOp,
1530                                    resdom->restype,
1531                                    resdom->restype));
1532         if (sortlist == NIL) {
1533             s = sortlist = lcons(sortcl, NIL);
1534         }else {
1535             lnext(s) = lcons(sortcl, NIL);
1536             s = lnext(s);
1537         }
1538         orderlist = lnext(orderlist);
1539     }
1540     
1541     if (uniqueFlag) {
1542       if (uniqueFlag[0] == '*') {
1543         /* concatenate all elements from target list
1544            that are not already in the sortby list */
1545         foreach (i,targetlist) {
1546             TargetEntry *tlelt = (TargetEntry *)lfirst(i);
1547
1548             s = sortlist;
1549             while(s != NIL) {
1550                 SortClause *sortcl = lfirst(s);
1551                 if (sortcl->resdom==tlelt->resdom)
1552                     break;
1553                 s = lnext(s);
1554             }
1555             if (s == NIL) {
1556                 /* not a member of the sortclauses yet */
1557                 SortClause *sortcl = makeNode(SortClause);
1558                 
1559                 sortcl->resdom = tlelt->resdom;
1560                 sortcl->opoid = any_ordering_op(tlelt->resdom->restype);
1561
1562                 sortlist = lappend(sortlist, sortcl);
1563               }
1564           }
1565       }
1566       else {
1567         TargetEntry *tlelt = NULL;
1568         char* uniqueAttrName = uniqueFlag;
1569
1570           /* only create sort clause with the specified unique attribute */
1571           foreach (i, targetlist) {
1572             tlelt = (TargetEntry*)lfirst(i);
1573             if (strcmp(tlelt->resdom->resname, uniqueAttrName) == 0)
1574               break;
1575           }
1576           if (i == NIL) {
1577             elog(WARN, "The field specified in the UNIQUE ON clause is not in the targetlist");
1578           }
1579           s = sortlist;
1580           foreach (s, sortlist) {
1581             SortClause *sortcl = lfirst(s);
1582             if (sortcl->resdom == tlelt->resdom)
1583               break;
1584           }
1585           if (s == NIL) { 
1586                 /* not a member of the sortclauses yet */
1587                 SortClause *sortcl = makeNode(SortClause);
1588                 
1589                 sortcl->resdom = tlelt->resdom;
1590                 sortcl->opoid = any_ordering_op(tlelt->resdom->restype);
1591
1592                 sortlist = lappend(sortlist, sortcl);
1593               }
1594         }
1595
1596     }
1597     
1598     return sortlist;
1599 }
1600
1601 /*
1602  ** HandleNestedDots --
1603  **    Given a nested dot expression (i.e. (relation func ... attr), build up
1604  ** a tree with of Iter and Func nodes.
1605  */
1606 static Node*
1607 handleNestedDots(ParseState *pstate, Attr *attr, int *curr_resno)
1608 {
1609     List *mutator_iter;
1610     Node *retval = NULL;
1611     
1612     if (attr->paramNo != NULL) {
1613         Param *param = (Param *)transformExpr(pstate, (Node*)attr->paramNo);
1614
1615         retval = 
1616             ParseFunc(pstate, strVal(lfirst(attr->attrs)),
1617                       lcons(param, NIL),
1618                       curr_resno);
1619     } else {
1620         Ident *ident = makeNode(Ident);
1621
1622         ident->name = attr->relname;
1623         ident->isRel = TRUE;
1624         retval =
1625             ParseFunc(pstate, strVal(lfirst(attr->attrs)),
1626                       lcons(ident, NIL),
1627                       curr_resno);
1628     }
1629     
1630     foreach (mutator_iter, lnext(attr->attrs)) {
1631         retval = ParseFunc(pstate,strVal(lfirst(mutator_iter)), 
1632                            lcons(retval, NIL),
1633                            curr_resno);
1634     }
1635     
1636     return(retval);
1637 }
1638
1639 /*
1640  ** make_arguments --
1641  **   Given the number and types of arguments to a function, and the 
1642  **   actual arguments and argument types, do the necessary typecasting.
1643  */
1644 static void
1645 make_arguments(int nargs,
1646                List *fargs,
1647                Oid *input_typeids,
1648                Oid *function_typeids)
1649 {
1650     /*
1651      * there are two ways an input typeid can differ from a function typeid :
1652      * either the input type inherits the function type, so no typecasting is
1653      * necessary, or the input type can be typecast into the function type.
1654      * right now, we only typecast unknowns, and that is all we check for.
1655      */
1656     
1657     List *current_fargs;
1658     int i;
1659     
1660     for (i=0, current_fargs = fargs;
1661          i<nargs;
1662          i++, current_fargs = lnext(current_fargs)) {
1663
1664         if (input_typeids[i] == UNKNOWNOID && function_typeids[i] != InvalidOid) {
1665             lfirst(current_fargs) =
1666                 parser_typecast2(lfirst(current_fargs),
1667                                  input_typeids[i],
1668                                  get_id_type(function_typeids[i]),
1669                                  -1);
1670         }
1671     }
1672 }
1673
1674 /*
1675  ** setup_tlist --
1676  **     Build a tlist that says which attribute to project to.
1677  **     This routine is called by ParseFunc() to set up a target list
1678  **     on a tuple parameter or return value.  Due to a bug in 4.0,
1679  **     it's not possible to refer to system attributes in this case.
1680  */
1681 static List *
1682 setup_tlist(char *attname, Oid relid)
1683 {
1684     TargetEntry *tle;
1685     Resdom *resnode;
1686     Var *varnode;
1687     Oid typeid;
1688     int attno;
1689     
1690     attno = get_attnum(relid, attname);
1691     if (attno < 0)
1692         elog(WARN, "cannot reference attribute %s of tuple params/return values for functions", attname);
1693     
1694     typeid = find_atttype(relid, attname);
1695     resnode = makeResdom(1,
1696                          typeid,
1697                          tlen(get_id_type(typeid)),
1698                          get_attname(relid, attno),
1699                          0,
1700                          (Oid)0,
1701                          0);
1702     varnode = makeVar(-1, attno, typeid, -1, attno);
1703
1704     tle = makeNode(TargetEntry);
1705     tle->resdom = resnode;
1706     tle->expr = (Node*)varnode;
1707     return (lcons(tle, NIL));
1708 }
1709
1710 /*
1711  ** setup_base_tlist --
1712  **     Build a tlist that extracts a base type from the tuple
1713  **     returned by the executor.
1714  */
1715 static List *
1716 setup_base_tlist(Oid typeid)
1717 {
1718     TargetEntry *tle;
1719     Resdom *resnode;
1720     Var *varnode;
1721     
1722     resnode = makeResdom(1,
1723                          typeid,
1724                          tlen(get_id_type(typeid)),
1725                          "<noname>",
1726                          0,
1727                          (Oid)0,
1728                          0);
1729     varnode = makeVar(-1, 1, typeid, -1, 1);
1730     tle = makeNode(TargetEntry);
1731     tle->resdom = resnode;
1732     tle->expr = (Node*)varnode;
1733
1734     return (lcons(tle, NIL));
1735 }
1736
1737 /*
1738  * ParseComplexProjection -
1739  *    handles function calls with a single argument that is of complex type.
1740  *    This routine returns NULL if it can't handle the projection (eg. sets).
1741  */
1742 static Node *
1743 ParseComplexProjection(ParseState *pstate,
1744                        char *funcname,
1745                        Node *first_arg,
1746                        bool *attisset)
1747 {
1748     Oid argtype;
1749     Oid argrelid;
1750     Name relname;
1751     Relation rd;
1752     Oid relid;
1753     int attnum;
1754
1755     switch (nodeTag(first_arg)) {
1756     case T_Iter:
1757         {
1758             Func *func;
1759             Iter *iter;
1760
1761             iter = (Iter*)first_arg;        
1762             func = (Func *)((Expr*)iter->iterexpr)->oper;
1763             argtype = funcid_get_rettype(func->funcid);
1764             argrelid = typeid_get_relid(argtype);
1765             if (argrelid &&
1766                 ((attnum = get_attnum(argrelid, funcname))
1767                 != InvalidAttrNumber)) {
1768                 
1769                 /* the argument is a function returning a tuple, so funcname
1770                    may be a projection */
1771
1772                 /* add a tlist to the func node and return the Iter */
1773                 rd = heap_openr(tname(get_id_type(argtype)));
1774                 if (RelationIsValid(rd)) {
1775                     relid = RelationGetRelationId(rd);
1776                     relname = RelationGetRelationName(rd);
1777                     heap_close(rd);
1778                 }
1779                 if (RelationIsValid(rd)) {
1780                     func->func_tlist =
1781                         setup_tlist(funcname, argrelid);
1782                     iter->itertype = att_typeid(rd,attnum);
1783                     return ((Node*)iter);
1784                 }else {
1785                     elog(WARN, 
1786                          "Function %s has bad returntype %d", 
1787                          funcname, argtype);
1788                 }
1789             }else { 
1790                 /* drop through */
1791                 ;
1792             }
1793             break;
1794         }
1795     case T_Var:
1796         {
1797             /*
1798              * The argument is a set, so this is either a projection
1799              * or a function call on this set.
1800              */
1801             *attisset = true;
1802             break;
1803         }
1804     case T_Expr:
1805         {
1806             Expr *expr = (Expr*)first_arg;
1807             Func *funcnode;
1808
1809             if (expr->opType != FUNC_EXPR)
1810                 break;
1811
1812             funcnode= (Func *) expr->oper;
1813             argtype = funcid_get_rettype(funcnode->funcid);
1814             argrelid = typeid_get_relid(argtype);
1815             /*
1816              * the argument is a function returning a tuple, so funcname
1817              * may be a projection
1818              */
1819             if (argrelid &&
1820                 (attnum = get_attnum(argrelid, funcname)) 
1821                 != InvalidAttrNumber) {
1822
1823                 /* add a tlist to the func node */
1824                 rd = heap_openr(tname(get_id_type(argtype)));
1825                 if (RelationIsValid(rd)) {
1826                     relid = RelationGetRelationId(rd);
1827                     relname = RelationGetRelationName(rd);
1828                     heap_close(rd);
1829                 }
1830                 if (RelationIsValid(rd)) {
1831                     Expr *newexpr;
1832                     
1833                     funcnode->func_tlist =
1834                         setup_tlist(funcname, argrelid);
1835                     funcnode->functype = att_typeid(rd,attnum);
1836
1837                     newexpr = makeNode(Expr);
1838                     newexpr->typeOid = funcnode->functype;
1839                     newexpr->opType = FUNC_EXPR;
1840                     newexpr->oper = (Node *)funcnode;
1841                     newexpr->args = lcons(first_arg, NIL);
1842
1843                     return ((Node*)newexpr);
1844                 }
1845             
1846             }
1847
1848             elog(WARN, "Function %s has bad returntype %d", 
1849                 funcname, argtype);
1850             break;
1851         }
1852     case T_Param:
1853         {
1854             Param *param = (Param*)first_arg;
1855             /*
1856              * If the Param is a complex type, this could be a projection
1857              */
1858             rd = heap_openr(tname(get_id_type(param->paramtype)));
1859             if (RelationIsValid(rd)) {
1860                 relid = RelationGetRelationId(rd);
1861                 relname = RelationGetRelationName(rd);
1862                 heap_close(rd);
1863             }
1864             if (RelationIsValid(rd) && 
1865                 (attnum = get_attnum(relid, funcname))
1866                 != InvalidAttrNumber) {
1867
1868                 param->paramtype = att_typeid(rd, attnum);
1869                 param->param_tlist = setup_tlist(funcname, relid);
1870                 return ((Node*)param);
1871             }
1872             break;
1873         }
1874     default:
1875         break;
1876     }
1877
1878     return NULL;
1879 }
1880                        
1881 static
1882 bool is_lowercase(char *string)
1883 {
1884     int i;
1885
1886     for(i = 0; i < strlen(string); i++) {
1887         if(string[i] >= 'A' && string[i] <= 'Z') {
1888             return false;
1889         }
1890     }
1891
1892     return true;
1893 }
1894
1895 static
1896 void make_lowercase(char *string)
1897 {
1898     int i;
1899
1900     for(i = 0; i < strlen(string); i++) {
1901         if(string[i] >= 'A' && string[i] <= 'Z') {
1902             string[i] = (string[i] - 'A') + 'a';
1903         }
1904     }
1905 }
1906                        
1907 static Node *
1908 ParseFunc(ParseState *pstate, char *funcname, List *fargs, int *curr_resno)
1909 {
1910     Oid rettype = (Oid)0;
1911     Oid argrelid = (Oid)0;
1912     Oid funcid = (Oid)0;
1913     List *i = NIL;
1914     Node *first_arg= NULL;
1915     char *relname = NULL;
1916     char *refname = NULL;
1917     Relation rd;
1918     Oid relid;
1919     int nargs;
1920     Func *funcnode;
1921     Oid oid_array[8];
1922     Oid *true_oid_array;
1923     Node *retval;
1924     bool retset;
1925     bool exists;
1926     bool attisset = false;
1927     Oid toid = (Oid)0;
1928     Expr *expr;
1929
1930     if (fargs) {
1931         first_arg = lfirst(fargs);
1932         if (first_arg == NULL)
1933             elog (WARN,"function %s does not allow NULL input",funcname);
1934     }
1935     
1936     /*
1937      ** check for projection methods: if function takes one argument, and 
1938      ** that argument is a relation, param, or PQ function returning a complex 
1939      ** type, then the function could be a projection.
1940      */
1941     if (length(fargs) == 1) {
1942         
1943         if (nodeTag(first_arg)==T_Ident && ((Ident*)first_arg)->isRel) {
1944             RangeTblEntry *rte;
1945             Ident *ident = (Ident*)first_arg;
1946
1947             /*
1948              * first arg is a relation. This could be a projection.
1949              */
1950             refname = ident->name;
1951
1952             rte = refnameRangeTableEntry(pstate->p_rtable, refname);
1953             if (rte == NULL)
1954                 rte = addRangeTableEntry(pstate, refname, refname, FALSE, FALSE,NULL);
1955
1956             relname = rte->relname;
1957             relid = rte->relid;
1958
1959             /* If the attr isn't a set, just make a var for it.  If
1960              * it is a set, treat it like a function and drop through.
1961              */
1962             if (get_attnum(relid, funcname) != InvalidAttrNumber) {
1963                 Oid dummyTypeId;
1964
1965                 return
1966                     ((Node*)make_var(pstate,
1967                                      refname,
1968                                      funcname,
1969                                      &dummyTypeId));
1970             } else {
1971                 /* drop through - attr is a set */
1972                 ;
1973             }
1974         } else if (ISCOMPLEX(exprType(first_arg))) {
1975             /*
1976              * Attempt to handle projection of a complex argument. If
1977              * ParseComplexProjection can't handle the projection, we
1978              * have to keep going.
1979              */
1980             retval = ParseComplexProjection(pstate,
1981                                             funcname,
1982                                             first_arg,
1983                                             &attisset);
1984             if (attisset) {
1985                 toid = exprType(first_arg);
1986                 rd = heap_openr(tname(get_id_type(toid)));
1987                 if (RelationIsValid(rd)) {
1988                     relname = RelationGetRelationName(rd)->data;
1989                     heap_close(rd);
1990                 } else
1991                     elog(WARN,
1992                          "Type %s is not a relation type",
1993                          tname(get_id_type(toid)));
1994                 argrelid = typeid_get_relid(toid);
1995                 /* A projection contains either an attribute name or the
1996                  * "*".
1997                  */
1998                 if ((get_attnum(argrelid, funcname) == InvalidAttrNumber) 
1999                     && strcmp(funcname, "*")) {
2000                     elog(WARN, "Functions on sets are not yet supported");
2001                 }
2002             }
2003                 
2004             if (retval)
2005                 return retval;
2006         } else {
2007             /*
2008              * Parsing aggregates.
2009              */
2010             Oid basetype;
2011             /* the aggregate count is a special case,
2012                ignore its base type.  Treat it as zero */
2013             if (strcmp(funcname, "count") == 0)
2014                 basetype = 0;
2015             else
2016                 basetype = exprType(lfirst(fargs));
2017             if (SearchSysCacheTuple(AGGNAME, 
2018                                     PointerGetDatum(funcname), 
2019                                     ObjectIdGetDatum(basetype),
2020                                     0, 0)) {
2021                 Aggreg *aggreg = ParseAgg(funcname, basetype, lfirst(fargs));
2022
2023                 AddAggToParseState(pstate, aggreg);
2024                 return (Node*)aggreg;
2025             } else {
2026                 /* try one more time with lowercase --djm 8/17/96 */
2027                 if(!is_lowercase(funcname)) {
2028                     char *lowercase_funcname = pstrdup(funcname);
2029
2030                     make_lowercase(lowercase_funcname);
2031                     if (strcmp(lowercase_funcname, "count") == 0)
2032                       basetype = 0;
2033                     else
2034                       basetype = exprType(lfirst(fargs));
2035                     if (SearchSysCacheTuple(AGGNAME, 
2036                                             PointerGetDatum(lowercase_funcname), 
2037                                             ObjectIdGetDatum(basetype),
2038                                             0, 0)) {
2039                         Aggreg *aggreg = ParseAgg(lowercase_funcname, 
2040                                                   basetype, lfirst(fargs));
2041
2042                         AddAggToParseState(pstate, aggreg);
2043                         return (Node*)aggreg;
2044                     }
2045                 }
2046             }
2047         }
2048     }
2049     
2050     
2051     /*
2052      ** If we dropped through to here it's really a function (or a set, which
2053      ** is implemented as a function.)
2054      ** extract arg type info and transform relation name arguments into
2055      ** varnodes of the appropriate form.
2056      */
2057     memset(&oid_array[0], 0, 8 * sizeof(Oid)); 
2058
2059     nargs=0;
2060     foreach ( i , fargs ) {
2061         int vnum;
2062         RangeTblEntry *rte;
2063         Node *pair = lfirst(i);
2064
2065         if (nodeTag(pair)==T_Ident && ((Ident*)pair)->isRel) {
2066             /*
2067              * a relation
2068              */
2069             refname = ((Ident*)pair)->name;
2070                     
2071             rte = refnameRangeTableEntry(pstate->p_rtable, refname);
2072             if (rte == NULL)
2073                 rte = addRangeTableEntry(pstate, refname, refname,
2074                                                 FALSE, FALSE, NULL);
2075             relname = rte->relname;
2076
2077             vnum = refnameRangeTablePosn (pstate->p_rtable, rte->refname);
2078            
2079             /*
2080              *  for func(relname), the param to the function
2081              *  is the tuple under consideration.  we build a special
2082              *  VarNode to reflect this -- it has varno set to the 
2083              *  correct range table entry, but has varattno == 0 to 
2084              *  signal that the whole tuple is the argument.
2085              */
2086             toid = typeid(type(relname));                  
2087             /* replace it in the arg list */
2088             lfirst(fargs) =
2089                 makeVar(vnum, 0, toid, vnum, 0);
2090         }else if (!attisset) { /* set functions don't have parameters */
2091  
2092           /* any functiona args which are typed "unknown", but aren't
2093              constants, we don't know what to do with, because we
2094              can't cast them    - jolly*/
2095           if (exprType(pair) == UNKNOWNOID &&
2096                !IsA(pair, Const))
2097               {
2098                   elog(WARN, "ParseFunc: no function named %s that takes in an unknown type as argument #%d", funcname, nargs);
2099               }
2100           else
2101               toid = exprType(pair);
2102         }
2103             
2104         oid_array[nargs++] = toid;
2105     }
2106     
2107     /*
2108      *  func_get_detail looks up the function in the catalogs, does
2109      *  disambiguation for polymorphic functions, handles inheritance,
2110      *  and returns the funcid and type and set or singleton status of
2111      *  the function's return value.  it also returns the true argument
2112      *  types to the function.  if func_get_detail returns true,
2113      *  the function exists.  otherwise, there was an error.
2114      */
2115     if (attisset) { /* we know all of these fields already */
2116         /* We create a funcnode with a placeholder function SetEval.
2117          * SetEval() never actually gets executed.  When the function
2118          * evaluation routines see it, they use the funcid projected
2119          * out from the relation as the actual function to call.
2120          * Example:  retrieve (emp.mgr.name)
2121          * The plan for this will scan the emp relation, projecting
2122          * out the mgr attribute, which is a funcid.  This function
2123          * is then called (instead of SetEval) and "name" is projected
2124          * from its result.
2125          */
2126         funcid = SetEvalRegProcedure;
2127         rettype = toid;
2128         retset = true;
2129         true_oid_array = oid_array;
2130         exists = true;
2131     } else {
2132         exists = func_get_detail(funcname, nargs, oid_array, &funcid,
2133                                  &rettype, &retset, &true_oid_array);
2134     }
2135     
2136     if (!exists)
2137         elog(WARN, "no such attribute or function %s", funcname);
2138     
2139     /* got it */
2140     funcnode = makeNode(Func);
2141     funcnode->funcid = funcid;
2142     funcnode->functype = rettype;
2143     funcnode->funcisindex = false;
2144     funcnode->funcsize = 0;
2145     funcnode->func_fcache = NULL;
2146     funcnode->func_tlist = NIL;
2147     funcnode->func_planlist = NIL;
2148     
2149     /* perform the necessary typecasting */
2150     make_arguments(nargs, fargs, oid_array, true_oid_array);
2151     
2152     /*
2153      *  for functions returning base types, we want to project out the
2154      *  return value.  set up a target list to do that.  the executor
2155      *  will ignore these for c functions, and do the right thing for
2156      *  postquel functions.
2157      */
2158     
2159     if (typeid_get_relid(rettype) == InvalidOid)
2160         funcnode->func_tlist = setup_base_tlist(rettype);
2161     
2162     /* For sets, we want to make a targetlist to project out this
2163      * attribute of the set tuples.
2164      */
2165     if (attisset) {
2166         if (!strcmp(funcname, "*")) {
2167             funcnode->func_tlist =
2168                 expandAll(pstate, relname, refname, curr_resno);
2169         } else {
2170             funcnode->func_tlist = setup_tlist(funcname,argrelid);
2171             rettype = find_atttype(argrelid, funcname);
2172         }
2173     }
2174
2175     expr = makeNode(Expr);
2176     expr->typeOid = rettype;
2177     expr->opType = FUNC_EXPR;
2178     expr->oper = (Node *)funcnode;
2179     expr->args = fargs;
2180     retval = (Node*)expr;
2181     
2182     /*
2183      *  if the function returns a set of values, then we need to iterate
2184      *  over all the returned values in the executor, so we stick an
2185      *  iter node here.  if it returns a singleton, then we don't need
2186      *  the iter node.
2187      */
2188     
2189     if (retset) {
2190         Iter *iter = makeNode(Iter);
2191         iter->itertype = rettype;
2192         iter->iterexpr = retval;
2193         retval = (Node*)iter;
2194     }
2195     
2196     return(retval);
2197 }
2198
2199 /*****************************************************************************
2200  *
2201  *****************************************************************************/
2202
2203 /*
2204  * AddAggToParseState -
2205  *    add the aggregate to the list of unique aggregates in pstate. 
2206  *
2207  * SIDE EFFECT: aggno in target list entry will be modified
2208  */
2209 static void
2210 AddAggToParseState(ParseState *pstate, Aggreg *aggreg)
2211 {
2212     List *ag;
2213     int i;
2214
2215     /*
2216      * see if we have the aggregate already (we only need to record
2217      * the aggregate once)
2218      */
2219     i = 0;
2220     foreach(ag, pstate->p_aggs) {
2221         Aggreg *a = lfirst(ag);
2222         
2223         if (!strcmp(a->aggname, aggreg->aggname) &&
2224             equal(a->target, aggreg->target)) {
2225
2226             /* fill in the aggno and we're done */
2227             aggreg->aggno = i;
2228             return;
2229         }
2230         i++;
2231     }
2232
2233     /* not found, new aggregate */
2234     aggreg->aggno = i;
2235     pstate->p_numAgg++;
2236     pstate->p_aggs = lappend(pstate->p_aggs, aggreg);
2237     return;
2238 }
2239
2240 /*
2241  * finalizeAggregates -
2242  *    fill in qry_aggs from pstate. Also checks to make sure that aggregates
2243  *    are used in the proper place.
2244  */
2245 static void
2246 finalizeAggregates(ParseState *pstate, Query *qry)
2247 {    
2248     List *l;
2249     int i;
2250
2251     parseCheckAggregates(pstate, qry);
2252         
2253     qry->qry_numAgg = pstate->p_numAgg;
2254     qry->qry_aggs =
2255         (Aggreg **)palloc(sizeof(Aggreg *) * qry->qry_numAgg);
2256     i = 0;
2257     foreach(l, pstate->p_aggs)
2258         qry->qry_aggs[i++] = (Aggreg*)lfirst(l);
2259 }
2260
2261 /*    
2262  * contain_agg_clause--
2263  *    Recursively find aggreg nodes from a clause.
2264  *    
2265  *    Returns true if any aggregate found.
2266  */
2267 static bool
2268 contain_agg_clause(Node *clause)
2269 {
2270     if (clause==NULL) 
2271         return FALSE;
2272     else if (IsA(clause,Aggreg))
2273         return TRUE;
2274     else if (IsA(clause,Iter))
2275         return contain_agg_clause(((Iter*)clause)->iterexpr);
2276     else if (single_node(clause)) 
2277         return FALSE;
2278     else if (or_clause(clause)) {
2279         List *temp;
2280
2281         foreach (temp, ((Expr*)clause)->args)
2282             if (contain_agg_clause(lfirst(temp)))
2283                 return TRUE;
2284         return FALSE;
2285     } else if (is_funcclause (clause)) {
2286         List *temp;
2287
2288         foreach(temp, ((Expr *)clause)->args)
2289             if (contain_agg_clause(lfirst(temp)))
2290                 return TRUE;
2291         return FALSE;
2292     } else if (IsA(clause,ArrayRef)) {
2293         List *temp;
2294
2295         foreach(temp, ((ArrayRef*)clause)->refupperindexpr)
2296             if (contain_agg_clause(lfirst(temp)))
2297                 return TRUE;
2298         foreach(temp, ((ArrayRef*)clause)->reflowerindexpr)
2299             if (contain_agg_clause(lfirst(temp)))
2300                 return TRUE;
2301         if (contain_agg_clause(((ArrayRef*)clause)->refexpr))
2302             return TRUE;
2303         if (contain_agg_clause(((ArrayRef*)clause)->refassgnexpr))
2304             return TRUE;
2305         return FALSE;
2306     } else if (not_clause(clause))
2307         return contain_agg_clause((Node*)get_notclausearg((Expr*)clause));
2308     else if (is_opclause(clause))
2309         return (contain_agg_clause((Node*)get_leftop((Expr*)clause)) ||
2310                 contain_agg_clause((Node*)get_rightop((Expr*)clause)));
2311
2312     return FALSE;
2313 }
2314
2315 /*
2316  * exprIsAggOrGroupCol -
2317  *    returns true if the expression does not contain non-group columns.
2318  */
2319 static bool
2320 exprIsAggOrGroupCol(Node *expr, List *groupClause)
2321 {
2322     if (expr==NULL)
2323         return TRUE;
2324     else if (IsA(expr,Const))
2325         return TRUE;
2326     else if (IsA(expr,Var)) {
2327         List *gl;
2328         Var *var = (Var*)expr;
2329         /*
2330          * only group columns are legal
2331          */
2332         foreach (gl, groupClause) {
2333             GroupClause *grpcl = lfirst(gl);
2334             if ((grpcl->grpAttr->varno == var->varno) &&
2335                 (grpcl->grpAttr->varattno == var->varattno))
2336                 return TRUE;
2337         }
2338         return FALSE;
2339     } else if (IsA(expr,Aggreg))
2340         /* aggregates can take group column or non-group column as argument,
2341            no further check necessary. */
2342         return TRUE;
2343     else if (IsA(expr,Expr)) {
2344         List *temp;
2345
2346         foreach (temp, ((Expr*)expr)->args)
2347             if (!exprIsAggOrGroupCol(lfirst(temp),groupClause))
2348                 return FALSE;
2349         return TRUE;
2350     }
2351
2352     return FALSE;
2353 }
2354
2355 /*
2356  * parseCheckAggregates -
2357  *    this should really be done earlier but the current grammar
2358  *    cannot differentiate functions from aggregates. So we have do check
2359  *    here when the target list and the qualifications are finalized.
2360  */
2361 static void
2362 parseCheckAggregates(ParseState *pstate, Query *qry)
2363 {
2364     List *tl;
2365     Assert(pstate->p_numAgg > 0);
2366
2367     /*
2368      * aggregates never appear in WHERE clauses. (we have to check where
2369      * clause first because if there is an aggregate, the check for
2370      * non-group column in target list may fail.)
2371      */
2372     if (contain_agg_clause(qry->qual))
2373         elog(WARN, "parser: aggregates not allowed in WHERE clause");
2374
2375     /*
2376      * the target list can only contain aggregates, group columns and
2377      * functions thereof.
2378      */
2379     foreach (tl, qry->targetList) {
2380         TargetEntry *tle = lfirst(tl);
2381         if (!exprIsAggOrGroupCol(tle->expr, qry->groupClause))
2382             elog(WARN,
2383                  "parser: illegal use of aggregates or non-group column in target list");
2384     }
2385         
2386     /*
2387      * the expression specified in the HAVING clause has the same restriction
2388      * as those in the target list.
2389      */
2390     if (!exprIsAggOrGroupCol(qry->havingQual, qry->groupClause))
2391         elog(WARN,
2392              "parser: illegal use of aggregates or non-group column in HAVING clause");
2393     
2394     return;
2395 }