Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
a1fbd470
Commit
a1fbd470
authored
Apr 29, 1997
by
Vadim B. Mikheev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix GroupBy: enable functions over aggregates and GroupBy-ed fields
in target list.
parent
f4279c46
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
87 additions
and
66 deletions
+87
-66
src/backend/optimizer/plan/planmain.c
src/backend/optimizer/plan/planmain.c
+45
-26
src/backend/parser/analyze.c
src/backend/parser/analyze.c
+40
-38
src/include/nodes/parsenodes.h
src/include/nodes/parsenodes.h
+2
-2
No files found.
src/backend/optimizer/plan/planmain.c
View file @
a1fbd470
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.
3 1997/04/05 06:37:37
vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.
4 1997/04/29 04:32:50
vadim Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -359,8 +359,9 @@ make_groupPlan(List **tlist,
List
*
sort_tlist
;
List
*
sl
,
*
gl
;
List
*
glc
=
listCopy
(
groupClause
);
List
*
aggvals
=
NIL
;
/* list of vars of aggregates */
int
aggvcnt
;
List
*
otles
=
NIL
;
/* list of removed non-GroupBy entries */
List
*
otlvars
=
NIL
;
/* list of var in them */
int
otlvcnt
;
Sort
*
sortplan
;
Group
*
grpplan
;
int
numCols
;
...
...
@@ -375,7 +376,8 @@ make_groupPlan(List **tlist,
/*
* Make template TL for subplan, Sort & Group:
* 1. Take away Aggregates and re-set resno-s accordantly.
* 1. If there are aggregates (tuplePerGroup is true) then take
* away non-GroupBy entries and re-set resno-s accordantly.
* 2. Make grpColIdx
*
* Note: we assume that TLEs in *tlist are ordered in accordance
...
...
@@ -390,7 +392,7 @@ make_groupPlan(List **tlist,
{
GroupClause
*
grpcl
=
(
GroupClause
*
)
lfirst
(
gl
);
if
(
grpcl
->
resdom
->
resno
==
te
->
resdom
->
resno
)
if
(
grpcl
->
entry
->
resdom
->
resno
==
te
->
resdom
->
resno
)
{
resdom
=
te
->
resdom
;
...
...
@@ -403,15 +405,20 @@ make_groupPlan(List **tlist,
break
;
}
}
if
(
resdom
==
NULL
)
/* Not GroupBy-ed entry: remove */
{
/* aggregate(s) from Group/Sort TL */
if
(
IsA
(
te
->
expr
,
Aggreg
)
)
{
/* save Aggregate' Vars */
aggvals
=
nconc
(
aggvals
,
pull_var_clause
(
te
->
expr
));
sort_tlist
=
lremove
(
lfirst
(
sl
),
sort_tlist
);
/*
* Non-GroupBy entry: remove it from Group/Sort TL if there are
* aggregates in query - it will be evaluated by Aggregate plan
*/
if
(
resdom
==
NULL
)
{
if
(
tuplePerGroup
)
{
otlvars
=
nconc
(
otlvars
,
pull_var_clause
(
te
->
expr
));
otles
=
lcons
(
te
,
otles
);
sort_tlist
=
lremove
(
te
,
sort_tlist
);
}
else
resdom
->
resno
=
last_resno
++
;
/* re-set */
te
->
resdom
->
resno
=
last_resno
++
;
}
}
...
...
@@ -421,12 +428,12 @@ make_groupPlan(List **tlist,
}
/*
*
Aggregates were removed from TL - we are to add Vars for them
* to the end of TL if there are no such Vars in TL already.
*
If non-GroupBy entries were removed from TL - we are to add Vars for
* t
hem t
o the end of TL if there are no such Vars in TL already.
*/
aggvcnt
=
length
(
aggval
s
);
foreach
(
gl
,
aggval
s
)
otlvcnt
=
length
(
otlvar
s
);
foreach
(
gl
,
otlvar
s
)
{
Var
*
v
=
(
Var
*
)
lfirst
(
gl
);
...
...
@@ -437,9 +444,9 @@ make_groupPlan(List **tlist,
last_resno
++
;
}
else
/* already in TL */
agg
vcnt
--
;
otl
vcnt
--
;
}
/* Now
aggvcnt is number of Vars added in TL for Aggregat
es */
/* Now
otlvcnt is number of Vars added in TL for non-GroupBy entri
es */
/* Make TL for subplan: substitute Vars from subplan TL into new TL */
sl
=
flatten_tlist_vars
(
sort_tlist
,
subplan
->
targetlist
);
...
...
@@ -489,17 +496,28 @@ make_groupPlan(List **tlist,
grpColIdx
,
sortplan
);
/*
* Make TL for parent: "restore"
Aggregates and
* resno-s of others accordantly.
* Make TL for parent: "restore"
non-GroupBy entries (if they
*
were removed) and set
resno-s of others accordantly.
*/
sl
=
sort_tlist
;
sort_tlist
=
NIL
;
/* to be new parent TL */
foreach
(
gl
,
*
tlist
)
{
List
*
temp
=
NIL
;
TargetEntry
*
te
=
(
TargetEntry
*
)
lfirst
(
gl
);
if
(
!
IsA
(
te
->
expr
,
Aggreg
)
)
/* It's "our" TLE - we're to return */
{
/* it from Sort/Group plans */
foreach
(
temp
,
otles
)
/* Is it removed non-GroupBy entry ? */
{
TargetEntry
*
ote
=
(
TargetEntry
*
)
lfirst
(
temp
);
if
(
ote
->
resdom
->
resno
==
te
->
resdom
->
resno
)
{
otles
=
lremove
(
ote
,
otles
);
break
;
}
}
if
(
temp
==
NIL
)
/* It's "our" TLE - we're to return */
{
/* it from Sort/Group plans */
TargetEntry
*
my
=
(
TargetEntry
*
)
lfirst
(
sl
);
/* get it */
sl
=
sl
->
next
;
/* prepare for the next "our" */
...
...
@@ -508,15 +526,16 @@ make_groupPlan(List **tlist,
sort_tlist
=
lappend
(
sort_tlist
,
my
);
continue
;
}
/*
TLE of an aggregate
*/
/*
else - it's TLE of an non-GroupBy entry
*/
sort_tlist
=
lappend
(
sort_tlist
,
copyObject
(
te
));
}
/*
* Pure
aggregat
es Vars were at the end of Group' TL.
* Pure
non-GroupBy entri
es Vars were at the end of Group' TL.
* They shouldn't appear in parent TL, all others shouldn't
* disappear.
*/
Assert
(
aggvcnt
==
length
(
sl
)
);
Assert
(
otlvcnt
==
length
(
sl
)
);
Assert
(
length
(
otles
)
==
0
);
*
tlist
=
sort_tlist
;
...
...
src/backend/parser/analyze.c
View file @
a1fbd470
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.2
6 1997/04/27 19:16:44 thomas
Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.2
7 1997/04/29 04:32:26 vadim
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -1552,7 +1552,8 @@ transformGroupClause(ParseState *pstate, List *grouplist, List *targetlist)
if
(
restarget
==
NULL
)
elog
(
WARN
,
"The field being grouped by must appear in the target list"
);
grpcl
->
resdom
=
resdom
=
restarget
->
resdom
;
grpcl
->
entry
=
restarget
;
resdom
=
restarget
->
resdom
;
grpcl
->
grpOpoid
=
oprid
(
oper
(
"<"
,
resdom
->
restype
,
resdom
->
restype
,
false
));
...
...
@@ -2359,6 +2360,39 @@ contain_agg_clause(Node *clause)
return
FALSE
;
}
/*
* exprIsAggOrGroupCol -
* returns true if the expression does not contain non-group columns.
*/
static
bool
exprIsAggOrGroupCol
(
Node
*
expr
,
List
*
groupClause
)
{
List
*
gl
;
if
(
expr
==
NULL
||
IsA
(
expr
,
Const
)
||
IsA
(
expr
,
Aggreg
)
)
return
TRUE
;
foreach
(
gl
,
groupClause
)
{
GroupClause
*
grpcl
=
lfirst
(
gl
);
if
(
equal
(
expr
,
grpcl
->
entry
->
expr
)
)
return
TRUE
;
}
if
(
IsA
(
expr
,
Expr
)
)
{
List
*
temp
;
foreach
(
temp
,
((
Expr
*
)
expr
)
->
args
)
if
(
!
exprIsAggOrGroupCol
(
lfirst
(
temp
),
groupClause
))
return
FALSE
;
return
TRUE
;
}
return
FALSE
;
}
/*
* tleIsAggOrGroupCol -
* returns true if the TargetEntry is Agg or GroupCol.
...
...
@@ -2376,9 +2410,9 @@ tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause)
{
GroupClause
*
grpcl
=
lfirst
(
gl
);
if
(
tle
->
resdom
->
resno
==
grpcl
->
resdom
->
resno
)
if
(
tle
->
resdom
->
resno
==
grpcl
->
entry
->
resdom
->
resno
)
{
if
(
IsA
(
expr
,
Aggreg
)
)
if
(
contain_agg_clause
((
Node
*
)
expr
)
)
elog
(
WARN
,
"parser: aggregates not allowed in GROUP BY clause"
);
return
TRUE
;
}
...
...
@@ -2387,39 +2421,8 @@ tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause)
if
(
IsA
(
expr
,
Aggreg
)
)
return
TRUE
;
return
FALSE
;
}
#if 0 /* Now GroupBy contains resdom to enable Group By func_results */
/*
* exprIsAggOrGroupCol -
* returns true if the expression does not contain non-group columns.
*/
static bool
exprIsAggOrGroupCol(Node *expr, List *groupClause)
{
if (expr==NULL)
return TRUE;
else if (IsA(expr,Const))
return TRUE;
else if (IsA(expr,Var)) {
List *gl;
Var *var = (Var*)expr;
/*
* only group columns are legal
*/
foreach (gl, groupClause) {
GroupClause *grpcl = lfirst(gl);
if ((grpcl->grpAttr->varno == var->varno) &&
(grpcl->grpAttr->varattno == var->varattno))
return TRUE;
}
return FALSE;
} else if (IsA(expr,Aggreg))
/* aggregates can take group column or non-group column as argument,
no further check necessary. */
return TRUE;
else if (IsA(expr,Expr)) {
if
(
IsA
(
expr
,
Expr
)
)
{
List
*
temp
;
foreach
(
temp
,
((
Expr
*
)
expr
)
->
args
)
...
...
@@ -2430,7 +2433,6 @@ exprIsAggOrGroupCol(Node *expr, List *groupClause)
return
FALSE
;
}
#endif
/*
* parseCheckAggregates -
...
...
src/include/nodes/parsenodes.h
View file @
a1fbd470
...
...
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: parsenodes.h,v 1.1
4 1997/04/23 05:58:06
vadim Exp $
* $Id: parsenodes.h,v 1.1
5 1997/04/29 04:28:59
vadim Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -774,7 +774,7 @@ typedef struct SortClause {
*/
typedef
struct
GroupClause
{
NodeTag
type
;
Resdom
*
resdom
;
/* attributes to group on */
TargetEntry
*
entry
;
/* attributes to group on */
Oid
grpOpoid
;
/* the sort operator to use */
}
GroupClause
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment