Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit502a653

Browse files
committed
This allows GROUP BY to use column aliases, and ORDER and GROUP BY can
use column numbers, like ANSI.Submitted by: Bruce Momjian <maillist@candle.pha.pa.us>
1 parentb1c7cba commit502a653

File tree

4 files changed

+110
-65
lines changed

4 files changed

+110
-65
lines changed

‎src/backend/parser/analyze.c

Lines changed: 61 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
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);
6565
staticNode*transformWhereClause(ParseState*pstate,Node*a_expr);
66-
staticList*transformGroupClause(ParseState*pstate,List*grouplist);
66+
staticList*transformGroupClause(ParseState*pstate,List*grouplist,
67+
List*targetlist);
6768
staticList*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-
staticResdom*
1435-
find_tl_elt(ParseState*pstate,char*refname,char*colname,List*tlist)
1437+
staticTargetEntry*
1438+
find_targetlist_entry(ParseState*pstate,SortGroupBy*sortgroupby,List*tlist)
14361439
{
14371440
List*i;
1438-
intreal_rtable_pos=0;
1439-
1440-
if(refname)
1441-
real_rtable_pos=refnameRangeTablePosn(pstate->p_rtable,refname);
1441+
intreal_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
inttest_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+
elsetarget_result=target;
1468+
}
1469+
}
1470+
else {
1471+
if (target_result!=NULL)
1472+
elog(WARN,"Order/Group By %s is ambiguous",sortgroupby->name);
1473+
elsetarget_result=target;
1474+
}
14571475
}
14581476
}
14591477
}
1460-
return((Resdom*)NULL);
1478+
returntarget_result;
14611479
}
14621480

14631481
staticOid
@@ -1478,22 +1496,27 @@ any_ordering_op(int restype)
14781496
*
14791497
*/
14801498
staticList*
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 beingsorted 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 beingordered 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));

‎src/backend/parser/gram.y

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.20.2.1 1996/12/11 23:06:40 momjian Exp $
13+
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.20.2.2 1996/12/22 03:21:58 scrappy Exp $
1414
*
1515
* HISTORY
1616
* AUTHORDATEMAJOR EVENT
@@ -82,7 +82,7 @@ static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
8282
TypeName*typnam;
8383
DefElem*defelt;
8484
ParamString*param;
85-
SortBy*sortby;
85+
SortGroupBy*sortgroupby;
8686
IndexElem*ielem;
8787
RangeVar*range;
8888
RelExpr*relexp;
@@ -146,10 +146,11 @@ static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
146146
%type <defelt>def_elem
147147
%type <node>def_arg, columnElem, where_clause,
148148
a_expr, AexprConst, in_expr_nodes, not_in_expr_nodes,
149-
having_clause, groupby
149+
having_clause
150150
%type <value>NumConst
151151
%type <attr>event_object, attr
152-
%type <sortby>sortby
152+
%type <sortgroupby>groupby
153+
%type <sortgroupby>sortby
153154
%type <ielem>index_elem, func_index
154155
%type <range>from_val
155156
%type <relexp>relation_expr
@@ -1359,7 +1360,7 @@ CursorStmt: DECLARE name opt_binary CURSOR FOR
13591360
n->fromClause = $9;
13601361
n->whereClause = $10;
13611362
n->groupClause = $11;
1362-
n->orderClause = $12;
1363+
n->sortClause = $12;
13631364
$$ = (Node *)n;
13641365
}
13651366
;
@@ -1385,7 +1386,7 @@ RetrieveStmt: SELECT opt_unique res_target_list2
13851386
n->whereClause = $6;
13861387
n->groupClause = $7;
13871388
n->havingClause = $8;
1388-
n->orderClause = $9;
1389+
n->sortClause = $9;
13891390
$$ = (Node *)n;
13901391
}
13911392
;
@@ -1413,22 +1414,28 @@ sortby_list: sortby
14131414

14141415
sortby: Id OptUseOp
14151416
{
1416-
$$ = makeNode(SortBy);
1417+
$$ = makeNode(SortGroupBy);
1418+
$$->resno = 0;
14171419
$$->range = NULL;
14181420
$$->name = $1;
14191421
$$->useOp = $2;
14201422
}
14211423
| Id '.' Id OptUseOp
14221424
{
1423-
$$ = makeNode(SortBy);
1425+
$$ = makeNode(SortGroupBy);
1426+
$$->resno = 0;
14241427
$$->range = $1;
14251428
$$->name = $3;
14261429
$$->useOp = $4;
14271430
}
1428-
| /*EMPTY*/
1429-
{
1430-
yyerror("parse error: use 'order by attribute_name'");
1431-
}
1431+
| Iconst OptUseOp
1432+
{
1433+
$$ = makeNode(SortGroupBy);
1434+
$$->resno = $1;
1435+
$$->range = NULL;
1436+
$$->name = NULL;
1437+
$$->useOp = $2;
1438+
}
14321439
;
14331440

14341441
OptUseOp: USING Op{ $$ = $2; }
@@ -1509,16 +1516,29 @@ groupby_list: groupby{ $$ = lcons($1, NIL); }
15091516
| groupby_list ',' groupby{ $$ = lappend($1, $3); }
15101517
;
15111518

1512-
groupby: Id
1513-
{
1514-
Ident *n = makeNode(Ident);
1515-
n->name = $1;
1516-
n->indirection = NULL;
1517-
$$ = (Node*)n;
1519+
groupby: Id
1520+
{
1521+
$$ = makeNode(SortGroupBy);
1522+
$$->resno = 0;
1523+
$$->range = NULL;
1524+
$$->name = $1;
1525+
$$->useOp = NULL;
15181526
}
1519-
|attr
1527+
|Id '.' Id
15201528
{
1521-
$$ = (Node*)$1;
1529+
$$ = makeNode(SortGroupBy);
1530+
$$->resno = 0;
1531+
$$->range = $1;
1532+
$$->name = $3;
1533+
$$->useOp = NULL;
1534+
}
1535+
| Iconst
1536+
{
1537+
$$ = makeNode(SortGroupBy);
1538+
$$->resno = $1;
1539+
$$->range = NULL;
1540+
$$->name = NULL;
1541+
$$->useOp = NULL;
15221542
}
15231543
;
15241544

‎src/include/nodes/nodes.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Id: nodes.h,v 1.3 1996/11/03 12:12:52 scrappy Exp $
9+
* $Id: nodes.h,v 1.3.2.1 1996/12/22 03:23:33 scrappy Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -190,7 +190,7 @@ typedef enum NodeTag {
190190
T_ParamString,
191191
T_TimeRange,
192192
T_RelExpr,
193-
T_SortBy,
193+
T_SortGroupBy,
194194
T_RangeVar,
195195
T_TypeName,
196196
T_IndexElem,

‎src/include/nodes/parsenodes.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Id: parsenodes.h,v 1.7 1996/11/13 20:56:15 scrappy Exp $
9+
* $Id: parsenodes.h,v 1.7.2.1 1996/12/22 03:23:35 scrappy Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -463,7 +463,7 @@ typedef struct CursorStmt {
463463
List*fromClause;/* the from clause */
464464
Node*whereClause;/* qualifications */
465465
List*groupClause;/* group by clause */
466-
List*orderClause;/* sort clause (a list ofSortBy's) */
466+
List*sortClause;/* sort clause (a list ofSortGroupBy's) */
467467
}CursorStmt;
468468

469469
/* ----------------------
@@ -480,7 +480,7 @@ typedef struct RetrieveStmt {
480480
Node*whereClause;/* qualifications */
481481
List*groupClause;/* group by clause */
482482
Node*havingClause;/* having conditional-expression */
483-
List*orderClause;/* sort clause (a list ofSortBy's) */
483+
List*sortClause;/* sort clause (a list ofSortGroupBy's) */
484484
}RetrieveStmt;
485485

486486

@@ -627,14 +627,15 @@ typedef struct RelExpr {
627627
}RelExpr;
628628

629629
/*
630-
*Sortby - for order by clause
630+
*SortGroupBy - for order by clause
631631
*/
632-
typedefstructSortBy {
632+
typedefstructSortGroupBy {
633633
NodeTagtype;
634+
intresno;/* target number */
634635
char*range;
635636
char*name;/* name of column to sort on */
636637
char*useOp;/* operator to use */
637-
}SortBy;
638+
}SortGroupBy;
638639

639640
/*
640641
* RangeVar - range variable, used in from clauses

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp