77 *
88 *
99 * IDENTIFICATION
10- * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.18 1996/11/30 18:06:20 momjian Exp $
10+ * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.18.2.1 1996/12/22 03:21:56 scrappy Exp $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
@@ -63,7 +63,8 @@ static TargetEntry *make_targetlist_expr(ParseState *pstate,
6363 char * colname , Node * expr ,
6464 List * arrayRef );
6565static Node * transformWhereClause (ParseState * pstate , Node * a_expr );
66- static List * transformGroupClause (ParseState * pstate , List * grouplist );
66+ static List * transformGroupClause (ParseState * pstate , List * grouplist ,
67+ List * targetlist );
6768static List * transformSortClause (ParseState * pstate ,
6869 List * orderlist , List * targetlist ,
6970 char * uniqueFlag );
@@ -422,13 +423,14 @@ transformSelectStmt(ParseState *pstate, RetrieveStmt *stmt)
422423
423424 /* fix order clause */
424425 qry -> sortClause = transformSortClause (pstate ,
425- stmt -> orderClause ,
426+ stmt -> sortClause ,
426427 qry -> targetList ,
427428 qry -> uniqueFlag );
428429
429430 /* fix group by clause */
430431 qry -> groupClause = transformGroupClause (pstate ,
431- stmt -> groupClause );
432+ stmt -> groupClause ,
433+ qry -> targetList );
432434 qry -> rtable = pstate -> p_rtable ;
433435
434436 if (pstate -> p_numAgg > 0 )
@@ -505,12 +507,13 @@ transformCursorStmt(ParseState *pstate, CursorStmt *stmt)
505507
506508 /* fix order clause */
507509 qry -> sortClause = transformSortClause (pstate ,
508- stmt -> orderClause ,
510+ stmt -> sortClause ,
509511 qry -> targetList ,
510512 qry -> uniqueFlag );
511513 /* fix group by clause */
512514 qry -> groupClause = transformGroupClause (pstate ,
513- stmt -> groupClause );
515+ stmt -> groupClause ,
516+ qry -> targetList );
514517
515518 qry -> rtable = pstate -> p_rtable ;
516519
@@ -1426,19 +1429,21 @@ transformWhereClause(ParseState *pstate, Node *a_expr)
14261429 *****************************************************************************/
14271430
14281431/*
1429- * find_tl_elt -
1432+ * find_targetlist_entry -
14301433 * returns the Resdom in the target list matching the specified varname
14311434 * and range
14321435 *
14331436 */
1434- static Resdom *
1435- find_tl_elt (ParseState * pstate , char * refname , char * colname , List * tlist )
1437+ static TargetEntry *
1438+ find_targetlist_entry (ParseState * pstate , SortGroupBy * sortgroupby , List * tlist )
14361439{
14371440 List * i ;
1438- int real_rtable_pos = 0 ;
1439-
1440- if (refname )
1441- real_rtable_pos = refnameRangeTablePosn (pstate -> p_rtable , refname );
1441+ int real_rtable_pos = 0 , target_pos = 0 ;
1442+ TargetEntry * target_result = NULL ;
1443+
1444+ if (sortgroupby -> range )
1445+ real_rtable_pos = refnameRangeTablePosn (pstate -> p_rtable ,
1446+ sortgroupby -> range );
14421447
14431448 foreach (i , tlist ) {
14441449 TargetEntry * target = (TargetEntry * )lfirst (i );
@@ -1447,17 +1452,30 @@ find_tl_elt(ParseState *pstate, char *refname, char *colname, List *tlist)
14471452 char * resname = resnode -> resname ;
14481453 int test_rtable_pos = var -> varno ;
14491454
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 );
1455+ if (!sortgroupby -> name ) {
1456+ if (sortgroupby -> resno == ++ target_pos ) {
1457+ target_result = target ;
1458+ break ;
1459+ }
1460+ }
1461+ else {
1462+ if (!strcmp (resname , sortgroupby -> name )) {
1463+ if (sortgroupby -> range ) {
1464+ if (real_rtable_pos == test_rtable_pos ) {
1465+ if (target_result != NULL )
1466+ elog (WARN , "Order/Group By %s is ambiguous" , sortgroupby -> name );
1467+ else target_result = target ;
1468+ }
1469+ }
1470+ else {
1471+ if (target_result != NULL )
1472+ elog (WARN , "Order/Group By %s is ambiguous" , sortgroupby -> name );
1473+ else target_result = target ;
1474+ }
14571475 }
14581476 }
14591477 }
1460- return (( Resdom * ) NULL ) ;
1478+ return target_result ;
14611479}
14621480
14631481static Oid
@@ -1478,22 +1496,27 @@ any_ordering_op(int restype)
14781496 *
14791497 */
14801498static List *
1481- transformGroupClause (ParseState * pstate , List * grouplist )
1499+ transformGroupClause (ParseState * pstate , List * grouplist , List * targetlist )
14821500{
14831501 List * glist = NIL , * gl = NIL ;
14841502
14851503 while (grouplist != NIL ) {
14861504 GroupClause * grpcl = makeNode (GroupClause );
1487- Var * groupAttr = ( Var * ) transformExpr ( pstate , ( Node * ) lfirst ( grouplist )) ;
1505+ TargetEntry * restarget ;
14881506
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 ) {
1507+ restarget = find_targetlist_entry (pstate , lfirst (grouplist ), targetlist );
1508+
1509+ if (restarget == NULL )
1510+ elog (WARN ,"The field being grouped by must appear in the target list" );
1511+ if (nodeTag (restarget -> expr ) != T_Var ) {
1512+ elog (WARN , "parser: can only specify attribute in group by" );
1513+ }
1514+
1515+ grpcl -> grpAttr = (Var * )restarget -> expr ;
1516+ grpcl -> grpOpoid = any_ordering_op (grpcl -> grpAttr -> vartype );
1517+ if (glist == NIL )
14951518 gl = glist = lcons (grpcl , NIL );
1496- } else {
1519+ else {
14971520 lnext (gl ) = lcons (grpcl , NIL );
14981521 gl = lnext (gl );
14991522 }
@@ -1517,15 +1540,16 @@ transformSortClause(ParseState *pstate,
15171540 List * s = NIL , * i ;
15181541
15191542 while (orderlist != NIL ) {
1520- SortBy * sortby = lfirst (orderlist );
1543+ SortGroupBy * sortby = lfirst (orderlist );
15211544 SortClause * sortcl = makeNode (SortClause );
1545+ TargetEntry * restarget ;
15221546 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 ;
1547+
1548+ restarget = find_targetlist_entry (pstate , sortby , targetlist );
1549+ if (restarget == NULL )
1550+ elog (WARN ,"The field being ordered by must appear in the target list" );
1551+
1552+ sortcl -> resdom = resdom = restarget -> resdom ;
15291553 sortcl -> opoid = oprid (oper (sortby -> useOp ,
15301554 resdom -> restype ,
15311555 resdom -> restype ));
0 commit comments