7
7
*
8
8
*
9
9
* 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 $
11
11
*
12
12
*-------------------------------------------------------------------------
13
13
*/
@@ -63,7 +63,8 @@ static TargetEntry *make_targetlist_expr(ParseState *pstate,
63
63
char * colname , Node * expr ,
64
64
List * arrayRef );
65
65
static 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 );
67
68
static List * transformSortClause (ParseState * pstate ,
68
69
List * orderlist , List * targetlist ,
69
70
char * uniqueFlag );
@@ -422,13 +423,14 @@ transformSelectStmt(ParseState *pstate, RetrieveStmt *stmt)
422
423
423
424
/* fix order clause */
424
425
qry -> sortClause = transformSortClause (pstate ,
425
- stmt -> orderClause ,
426
+ stmt -> sortClause ,
426
427
qry -> targetList ,
427
428
qry -> uniqueFlag );
428
429
429
430
/* fix group by clause */
430
431
qry -> groupClause = transformGroupClause (pstate ,
431
- stmt -> groupClause );
432
+ stmt -> groupClause ,
433
+ qry -> targetList );
432
434
qry -> rtable = pstate -> p_rtable ;
433
435
434
436
if (pstate -> p_numAgg > 0 )
@@ -505,12 +507,13 @@ transformCursorStmt(ParseState *pstate, CursorStmt *stmt)
505
507
506
508
/* fix order clause */
507
509
qry -> sortClause = transformSortClause (pstate ,
508
- stmt -> orderClause ,
510
+ stmt -> sortClause ,
509
511
qry -> targetList ,
510
512
qry -> uniqueFlag );
511
513
/* fix group by clause */
512
514
qry -> groupClause = transformGroupClause (pstate ,
513
- stmt -> groupClause );
515
+ stmt -> groupClause ,
516
+ qry -> targetList );
514
517
515
518
qry -> rtable = pstate -> p_rtable ;
516
519
@@ -1426,19 +1429,21 @@ transformWhereClause(ParseState *pstate, Node *a_expr)
1426
1429
*****************************************************************************/
1427
1430
1428
1431
/*
1429
- * find_tl_elt -
1432
+ * find_targetlist_entry -
1430
1433
* returns the Resdom in the target list matching the specified varname
1431
1434
* and range
1432
1435
*
1433
1436
*/
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 )
1436
1439
{
1437
1440
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 );
1442
1447
1443
1448
foreach (i , tlist ) {
1444
1449
TargetEntry * target = (TargetEntry * )lfirst (i );
@@ -1447,17 +1452,30 @@ find_tl_elt(ParseState *pstate, char *refname, char *colname, List *tlist)
1447
1452
char * resname = resnode -> resname ;
1448
1453
int test_rtable_pos = var -> varno ;
1449
1454
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
+ }
1457
1475
}
1458
1476
}
1459
1477
}
1460
- return (( Resdom * ) NULL ) ;
1478
+ return target_result ;
1461
1479
}
1462
1480
1463
1481
static Oid
@@ -1478,22 +1496,27 @@ any_ordering_op(int restype)
1478
1496
*
1479
1497
*/
1480
1498
static List *
1481
- transformGroupClause (ParseState * pstate , List * grouplist )
1499
+ transformGroupClause (ParseState * pstate , List * grouplist , List * targetlist )
1482
1500
{
1483
1501
List * glist = NIL , * gl = NIL ;
1484
1502
1485
1503
while (grouplist != NIL ) {
1486
1504
GroupClause * grpcl = makeNode (GroupClause );
1487
- Var * groupAttr = ( Var * ) transformExpr ( pstate , ( Node * ) lfirst ( grouplist )) ;
1505
+ TargetEntry * restarget ;
1488
1506
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 )
1495
1518
gl = glist = lcons (grpcl , NIL );
1496
- } else {
1519
+ else {
1497
1520
lnext (gl ) = lcons (grpcl , NIL );
1498
1521
gl = lnext (gl );
1499
1522
}
@@ -1517,15 +1540,16 @@ transformSortClause(ParseState *pstate,
1517
1540
List * s = NIL , * i ;
1518
1541
1519
1542
while (orderlist != NIL ) {
1520
- SortBy * sortby = lfirst (orderlist );
1543
+ SortGroupBy * sortby = lfirst (orderlist );
1521
1544
SortClause * sortcl = makeNode (SortClause );
1545
+ TargetEntry * restarget ;
1522
1546
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 ;
1529
1553
sortcl -> opoid = oprid (oper (sortby -> useOp ,
1530
1554
resdom -> restype ,
1531
1555
resdom -> restype ));
0 commit comments