Commit 79c2576f authored by Jan Wieck's avatar Jan Wieck

Replaced targetlist entry in GroupClause by reference number

in Resdom and GroupClause so changing of resno's doesn't confuse
the grouping any more.

Jan
parent 1a87c14c
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.78 1999/04/27 09:49:36 ishii Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.79 1999/05/12 15:01:31 wieck Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -487,8 +487,8 @@ _copyGroupClause(GroupClause *from)
{
GroupClause *newnode = makeNode(GroupClause);
Node_Copy(from, newnode, entry);
newnode->grpOpoid = from->grpOpoid;
newnode->tleGroupref = from->tleGroupref;
return newnode;
}
......@@ -589,6 +589,7 @@ _copyResdom(Resdom *from)
newnode->resname = pstrdup(from->resname);
newnode->reskey = from->reskey;
newnode->reskeyop = from->reskeyop;
newnode->resgroupref = from->resgroupref;
newnode->resjunk = from->resjunk;
return newnode;
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.35 1999/02/18 00:49:14 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.36 1999/05/12 15:01:33 wieck Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -48,6 +48,8 @@ _equalResdom(Resdom *a, Resdom *b)
return false;
if (a->reskey != b->reskey)
return false;
if (a->resgroupref != b->resgroupref)
return false;
if (a->reskeyop != b->reskeyop)
return false;
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.15 1999/03/01 00:10:31 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.16 1999/05/12 15:01:33 wieck Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -396,8 +396,6 @@ _freeAgg(Agg *node)
static void
_freeGroupClause(GroupClause *node)
{
freeObject(node->entry);
pfree(node);
}
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.13 1999/02/13 23:15:58 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.14 1999/05/12 15:01:34 wieck Exp $
*
* NOTES
* Creator functions in POSTGRES 4.2 are generated automatically. Most of
......@@ -107,6 +107,7 @@ makeResdom(AttrNumber resno,
resdom->resname = resname;
resdom->reskey = reskey;
resdom->reskeyop = reskeyop;
resdom->resgroupref = 0;
resdom->resjunk = resjunk;
return resdom;
}
......
......@@ -5,7 +5,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: outfuncs.c,v 1.80 1999/05/10 00:45:10 momjian Exp $
* $Id: outfuncs.c,v 1.81 1999/05/12 15:01:34 wieck Exp $
*
* NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which
......@@ -255,10 +255,9 @@ _outSortClause(StringInfo str, SortClause *node)
static void
_outGroupClause(StringInfo str, GroupClause *node)
{
appendStringInfo(str, " GROUPCLAUSE :entry ");
_outNode(str, node->entry);
appendStringInfo(str, " :grpOpoid %u ", node->grpOpoid);
appendStringInfo(str, " GROUPCLAUSE :grpOpoid %u :tleGroupref %d",
node->grpOpoid,
node->tleGroupref);
}
/*
......@@ -556,15 +555,18 @@ _outHash(StringInfo str, Hash *node)
static void
_outResdom(StringInfo str, Resdom *node)
{
appendStringInfo(str, " RESDOM :resno %d :restype %u :restypmod %d ",
appendStringInfo(str, " RESDOM :resno %d :restype %u :restypmod %d",
node->resno,
node->restype,
node->restypmod);
appendStringInfo(str, " :resname \"%s\" :reskey %d :reskeyop %u :resjunk %d",
appendStringInfo(str, " :resname \"%s\" :reskey %d :reskeyop %u",
stringStringInfo(node->resname),
node->reskey,
node->reskeyop,
node->reskeyop);
appendStringInfo(str, " :resgroupref %d :resjunk %d",
node->resgroupref,
node->resjunk);
}
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.60 1999/03/01 00:10:31 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.61 1999/05/12 15:01:35 wieck Exp $
*
* NOTES
* Most of the read functions for plan nodes are tested. (In fact, they
......@@ -221,13 +221,14 @@ _readGroupClause()
local_node = makeNode(GroupClause);
token = lsptok(NULL, &length); /* skip the :entry */
local_node->entry = nodeRead(true);
token = lsptok(NULL, &length); /* skip :grpOpoid */
token = lsptok(NULL, &length); /* get grpOpoid */
local_node->grpOpoid = strtoul(token, NULL, 10);
token = lsptok(NULL, &length); /* skip :tleGroupref */
token = lsptok(NULL, &length); /* get tleGroupref */
local_node->tleGroupref = strtoul(token, NULL, 10);
return local_node;
}
......@@ -744,6 +745,10 @@ _readResdom()
token = lsptok(NULL, &length); /* get reskeyop */
local_node->reskeyop = (Oid) atol(token);
token = lsptok(NULL, &length); /* eat :resgroupref */
token = lsptok(NULL, &length); /* get resgroupref */
local_node->resgroupref = strtoul(token, NULL, 10);
token = lsptok(NULL, &length); /* eat :resjunk */
token = lsptok(NULL, &length); /* get resjunk */
local_node->resjunk = atoi(token);
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.50 1999/05/10 00:45:20 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.51 1999/05/12 15:01:37 wieck Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -260,7 +260,8 @@ union_planner(Query *parse)
* belong to?)
*/
check_having_for_ungrouped_vars(parse->havingQual,
parse->groupClause);
parse->groupClause,
parse->targetList);
}
/* Calculate the opfids from the opnos */
......@@ -426,8 +427,7 @@ make_subplanTargetList(Query *parse,
GroupClause *grpcl = (GroupClause *) lfirst(gl);
keyno++; /* sort key # for this GroupClause */
/* Is it safe to use just resno to match tlist and glist items?? */
if (grpcl->entry->resdom->resno == resdom->resno)
if (grpcl->tleGroupref == resdom->resgroupref)
{
/* Found a matching groupclause; record info for sorting */
foundGroupClause = true;
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.45 1999/05/06 23:07:33 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.46 1999/05/12 15:01:39 wieck Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -961,7 +961,8 @@ del_agg_clause(Node *clause)
*/
void
check_having_for_ungrouped_vars(Node *clause, List *groupClause)
check_having_for_ungrouped_vars(Node *clause, List *groupClause,
List *targetList)
{
List *t;
......@@ -981,7 +982,7 @@ check_having_for_ungrouped_vars(Node *clause, List *groupClause)
else if (IsA(clause, Iter))
{
check_having_for_ungrouped_vars(((Iter *) clause)->iterexpr,
groupClause);
groupClause, targetList);
}
else if (is_subplan(clause))
{
......@@ -997,7 +998,8 @@ check_having_for_ungrouped_vars(Node *clause, List *groupClause)
foreach(gl, groupClause)
{
if (var_equal(lfirst(t),
get_expr(((GroupClause *) lfirst(gl))->entry)))
get_groupclause_expr((GroupClause *)
lfirst(gl), targetList)))
{
contained_in_group_clause = true;
break;
......@@ -1016,7 +1018,8 @@ check_having_for_ungrouped_vars(Node *clause, List *groupClause)
* subplan is a kind of Expr node.
*/
foreach(t, ((Expr *) clause)->args)
check_having_for_ungrouped_vars(lfirst(t), groupClause);
check_having_for_ungrouped_vars(lfirst(t), groupClause,
targetList);
}
else if (IsA(clause, List))
{
......@@ -1024,12 +1027,13 @@ check_having_for_ungrouped_vars(Node *clause, List *groupClause)
* Recursively scan AND subclauses (see NOTE above).
*/
foreach(t, ((List *) clause))
check_having_for_ungrouped_vars(lfirst(t), groupClause);
check_having_for_ungrouped_vars(lfirst(t), groupClause,
targetList);
}
else if (IsA(clause, Aggref))
{
check_having_for_ungrouped_vars(((Aggref *) clause)->target,
groupClause);
groupClause, targetList);
}
else if (IsA(clause, ArrayRef))
{
......@@ -1040,22 +1044,28 @@ check_having_for_ungrouped_vars(Node *clause, List *groupClause)
* expression and its index expression...
*/
foreach(t, aref->refupperindexpr)
check_having_for_ungrouped_vars(lfirst(t), groupClause);
check_having_for_ungrouped_vars(lfirst(t), groupClause,
targetList);
foreach(t, aref->reflowerindexpr)
check_having_for_ungrouped_vars(lfirst(t), groupClause);
check_having_for_ungrouped_vars(aref->refexpr, groupClause);
check_having_for_ungrouped_vars(aref->refassgnexpr, groupClause);
check_having_for_ungrouped_vars(lfirst(t), groupClause,
targetList);
check_having_for_ungrouped_vars(aref->refexpr, groupClause,
targetList);
check_having_for_ungrouped_vars(aref->refassgnexpr, groupClause,
targetList);
}
else if (case_clause(clause))
{
foreach(t, ((CaseExpr *) clause)->args)
{
CaseWhen *when = (CaseWhen *) lfirst(t);
check_having_for_ungrouped_vars(when->expr, groupClause);
check_having_for_ungrouped_vars(when->result, groupClause);
check_having_for_ungrouped_vars(when->expr, groupClause,
targetList);
check_having_for_ungrouped_vars(when->result, groupClause,
targetList);
}
check_having_for_ungrouped_vars(((CaseExpr *) clause)->defresult,
groupClause);
groupClause, targetList);
}
else
{
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.18 1999/02/13 23:16:38 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.19 1999/05/12 15:01:41 wieck Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -229,6 +229,49 @@ replace_matching_resname(List *new_tlist, List *old_tlist)
new_tl = makeTargetEntry(newresno, old_tle->expr);
t_list = lappend(t_list, new_tl);
}
/*
* Also it is possible that the parser or rewriter added
* some junk attributes to hold GROUP BY expressions which
* are not part of the result attributes.
* We can simply identify them by looking at the resgroupref
* in the TLE's resdom, which is a unique number telling which
* TLE belongs to which GroupClause.
*/
if (old_tle->resdom->resgroupref > 0)
{
bool already_there = FALSE;
TargetEntry *new_tle;
Resdom *newresno;
/*
* Check if the tle is already in the new list
*/
foreach(i, t_list)
{
new_tle = (TargetEntry *)lfirst(i);
if (new_tle->resdom->resgroupref ==
old_tle->resdom->resgroupref)
{
already_there = TRUE;
break;
}
}
/*
* If not, add it and make sure it is now a junk attribute
*/
if (!already_there)
{
newresno = (Resdom *) copyObject((Node *) old_tle->resdom);
newresno->resno = length(t_list) + 1;
newresno->resjunk = 1;
new_tl = makeTargetEntry(newresno, old_tle->expr);
t_list = lappend(t_list, new_tl);
}
}
}
return t_list;
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/tlist.c,v 1.29 1999/05/06 23:07:33 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/tlist.c,v 1.30 1999/05/12 15:01:44 wieck Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -518,6 +518,25 @@ get_expr(TargetEntry *tle)
}
Var *
get_groupclause_expr(GroupClause *groupClause, List *targetList)
{
List *l;
TargetEntry *tle;
foreach(l, targetList)
{
tle = (TargetEntry *)lfirst(l);
if (tle->resdom->resgroupref == groupClause->tleGroupref)
return get_expr(tle);
}
elog(ERROR,
"get_groupclause_expr: GROUP BY expression not found in targetlist");
return NULL;
}
/*****************************************************************************
*
*****************************************************************************/
......@@ -528,6 +547,11 @@ get_expr(TargetEntry *tle)
* in there.
*/
#ifdef NOT_USED
/*
* WARNING!!! If this ever get's used again, the new reference
* mechanism from group clause to targetlist entry must be implemented
* here too. Jan
*/
void
AddGroupAttrToTlist(List *tlist, List *grpCl)
{
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.18 1999/04/29 01:13:13 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.19 1999/05/12 15:01:48 wieck Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -32,8 +32,9 @@
#include "utils/lsyscache.h"
static bool contain_agg_clause(Node *clause);
static bool exprIsAggOrGroupCol(Node *expr, List *groupClause);
static bool tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause);
static bool exprIsAggOrGroupCol(Node *expr, List *groupClause, List *tlist);
static bool tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause,
List *tlist);
/*
* contain_agg_clause
......@@ -100,7 +101,7 @@ contain_agg_clause(Node *clause)
* returns true if the expression does not contain non-group columns.
*/
static bool
exprIsAggOrGroupCol(Node *expr, List *groupClause)
exprIsAggOrGroupCol(Node *expr, List *groupClause, List *tlist)
{
List *gl;
......@@ -113,7 +114,7 @@ exprIsAggOrGroupCol(Node *expr, List *groupClause)
{
GroupClause *grpcl = lfirst(gl);
if (equal(expr, grpcl->entry->expr))
if (equal(expr, get_groupclause_expr(grpcl, tlist)))
return TRUE;
}
......@@ -122,7 +123,7 @@ exprIsAggOrGroupCol(Node *expr, List *groupClause)
List *temp;
foreach(temp, ((Expr *) expr)->args)
if (!exprIsAggOrGroupCol(lfirst(temp), groupClause))
if (!exprIsAggOrGroupCol(lfirst(temp), groupClause, tlist))
return FALSE;
return TRUE;
}
......@@ -135,7 +136,7 @@ exprIsAggOrGroupCol(Node *expr, List *groupClause)
* returns true if the TargetEntry is Agg or GroupCol.
*/
static bool
tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause)
tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause, List *tlist)
{
Node *expr = tle->expr;
List *gl;
......@@ -147,7 +148,7 @@ tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause)
{
GroupClause *grpcl = lfirst(gl);
if (tle->resdom->resno == grpcl->entry->resdom->resno)
if (tle->resdom->resgroupref == grpcl->tleGroupref)
{
if (contain_agg_clause((Node *) expr))
elog(ERROR, "Aggregates not allowed in GROUP BY clause");
......@@ -163,7 +164,7 @@ tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause)
List *temp;
foreach(temp, ((Expr *) expr)->args)
if (!exprIsAggOrGroupCol(lfirst(temp), groupClause))
if (!exprIsAggOrGroupCol(lfirst(temp), groupClause, tlist))
return FALSE;
return TRUE;
}
......@@ -200,7 +201,7 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
{
TargetEntry *tle = lfirst(tl);
if (!tleIsAggOrGroupCol(tle, qry->groupClause))
if (!tleIsAggOrGroupCol(tle, qry->groupClause, qry->targetList))
elog(ERROR,
"Illegal use of aggregates or non-group column in target list");
}
......@@ -210,7 +211,7 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
* restriction as those in the target list.
*/
if (!exprIsAggOrGroupCol(qry->havingQual, qry->groupClause))
if (!exprIsAggOrGroupCol(qry->havingQual, qry->groupClause, qry->targetList))
elog(ERROR,
"Illegal use of aggregates or non-group column in HAVING clause");
return;
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.29 1999/02/23 07:46:42 thomas Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.30 1999/05/12 15:01:50 wieck Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -550,13 +550,19 @@ transformGroupClause(ParseState *pstate, List *grouplist, List *targetlist)
restarget = findTargetlistEntry(pstate, lfirst(grouplist), targetlist, GROUP_CLAUSE);
grpcl->entry = restarget;
resdom = restarget->resdom;
grpcl->grpOpoid = oprid(oper("<",
resdom->restype,
resdom->restype, false));
if (glist == NIL)
{
int groupref = length(glist) + 1;
restarget->resdom->resgroupref = groupref;
grpcl->tleGroupref = groupref;
gl = glist = lcons(grpcl, NIL);
}
else
{
List *i;
......@@ -565,11 +571,17 @@ transformGroupClause(ParseState *pstate, List *grouplist, List *targetlist)
{
GroupClause *gcl = (GroupClause *) lfirst(i);
if (gcl->entry == grpcl->entry)
if (equal(get_groupclause_expr(gcl, targetlist),
restarget->expr))
break;
}
if (i == NIL) /* not in grouplist already */
{
int groupref = length(glist) + 1;
restarget->resdom->resgroupref = groupref;
grpcl->tleGroupref = groupref;
lnext(gl) = lcons(grpcl, NIL);
gl = lnext(gl);
}
......
......@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.38 1999/05/09 23:31:46 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.39 1999/05/12 15:01:53 wieck Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -170,15 +170,7 @@ rangeTableEntry_used(Node *node, int rt_index, int sublevels_up)
break;
case T_GroupClause:
{
GroupClause *grp = (GroupClause *)node;
return rangeTableEntry_used(
(Node *)(grp->entry),
rt_index,
sublevels_up);
}
break;
return FALSE;
case T_Expr:
{
......@@ -348,12 +340,6 @@ rangeTableEntry_used(Node *node, int rt_index, int sublevels_up)
sublevels_up))
return TRUE;
if (rangeTableEntry_used(
(Node *)(qry->groupClause),
rt_index,
sublevels_up))
return TRUE;
return FALSE;
}
break;
......@@ -407,16 +393,7 @@ attribute_used(Node *node, int rt_index, int attno, int sublevels_up)
break;
case T_GroupClause:
{
GroupClause *grp = (GroupClause *)node;
return attribute_used(
(Node *)(grp->entry),
rt_index,
attno,
sublevels_up);
}
break;
return FALSE;
case T_Expr:
{
......@@ -558,13 +535,6 @@ attribute_used(Node *node, int rt_index, int attno, int sublevels_up)
sublevels_up))
return TRUE;
if (attribute_used(
(Node *)(qry->groupClause),
rt_index,
attno,
sublevels_up))
return TRUE;
return FALSE;
}
break;
......@@ -697,8 +667,6 @@ modifyAggrefUplevel(Node *node)
modifyAggrefUplevel(
(Node *)(qry->havingQual));
modifyAggrefUplevel(
(Node *)(qry->groupClause));
}
break;
......@@ -752,15 +720,6 @@ modifyAggrefChangeVarnodes(Node **nodePtr, int rt_index, int new_index, int subl
break;
case T_GroupClause:
{
GroupClause *grp = (GroupClause *)node;
modifyAggrefChangeVarnodes(
(Node **)(&(grp->entry)),
rt_index,
new_index,
sublevels_up);
}
break;
case T_Expr:
......@@ -894,12 +853,6 @@ modifyAggrefChangeVarnodes(Node **nodePtr, int rt_index, int new_index, int subl
rt_index,
new_index,
sublevels_up);
modifyAggrefChangeVarnodes(
(Node **)(&(qry->groupClause)),
rt_index,
new_index,
sublevels_up);
}
break;
......@@ -1186,13 +1139,6 @@ modifyAggrefQual(Node **nodePtr, Query *parsetree)
break;
case T_GroupClause:
{
GroupClause *grp = (GroupClause *)node;
modifyAggrefQual(
(Node **)(&(grp->entry)),
parsetree);
}
break;
case T_Expr:
......@@ -1386,13 +1332,6 @@ apply_RIR_adjust_sublevel(Node *node, int sublevels_up)
break;
case T_GroupClause:
{
GroupClause *grp = (GroupClause *)node;
apply_RIR_adjust_sublevel(
(Node *)(grp->entry),
sublevels_up);
}
break;
case T_Expr:
......@@ -1539,17 +1478,6 @@ apply_RIR_view(Node **nodePtr, int rt_index, RangeTblEntry *rte, List *tlist, in
break;
case T_GroupClause:
{
GroupClause *grp = (GroupClause *)node;
apply_RIR_view(
(Node **)(&(grp->entry)),
rt_index,
rte,
tlist,
modified,
sublevels_up);
}
break;
case T_Expr:
......@@ -1724,14 +1652,6 @@ apply_RIR_view(Node **nodePtr, int rt_index, RangeTblEntry *rte, List *tlist, in
tlist,
modified,
sublevels_up);
apply_RIR_view(
(Node **)(&(qry->groupClause)),
rt_index,
rte,
tlist,
modified,
sublevels_up);
}
break;
......@@ -1898,10 +1818,8 @@ ApplyRetrieveRule(Query *parsetree,
}
if (*modified && !badsql) {
AddQual(parsetree, rule_action->qual);
/* This will only work if the query made to the view defined by the following
* groupClause groups by the same attributes or does not use group at all! */
if (parsetree->groupClause == NULL)
parsetree->groupClause=rule_action->groupClause;
AddGroupClause(parsetree, rule_action->groupClause,
rule_action->targetList);
AddHavingQual(parsetree, rule_action->havingQual);
parsetree->hasAggs = (rule_action->hasAggs || parsetree->hasAggs);
parsetree->hasSubLinks = (rule_action->hasSubLinks || parsetree->hasSubLinks);
......@@ -1935,12 +1853,6 @@ fireRIRonSubselect(Node *node)
break;
case T_GroupClause:
{
GroupClause *grp = (GroupClause *)node;
fireRIRonSubselect(
(Node *)(grp->entry));
}
break;
case T_Expr:
......@@ -2048,9 +1960,6 @@ fireRIRonSubselect(Node *node)
fireRIRonSubselect(
(Node *)(qry->havingQual));
fireRIRonSubselect(
(Node *)(qry->groupClause));
}
break;
......
......@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.29 1999/02/13 23:17:49 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.30 1999/05/12 15:01:55 wieck Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -65,14 +65,6 @@ OffsetVarNodes(Node *node, int offset, int sublevels_up)
break;
case T_GroupClause:
{
GroupClause *grp = (GroupClause *)node;
OffsetVarNodes(
(Node *)(grp->entry),
offset,
sublevels_up);
}
break;
case T_Expr:
......@@ -199,11 +191,6 @@ OffsetVarNodes(Node *node, int offset, int sublevels_up)
(Node *)(qry->havingQual),
offset,
sublevels_up);
OffsetVarNodes(
(Node *)(qry->groupClause),
offset,
sublevels_up);
}
break;
......@@ -284,15 +271,6 @@ ChangeVarNodes(Node *node, int rt_index, int new_index, int sublevels_up)
break;
case T_GroupClause:
{
GroupClause *grp = (GroupClause *)node;
ChangeVarNodes(
(Node *)(grp->entry),
rt_index,
new_index,
sublevels_up);
}
break;
case T_Expr:
......@@ -430,12 +408,6 @@ ChangeVarNodes(Node *node, int rt_index, int new_index, int sublevels_up)
rt_index,
new_index,
sublevels_up);
ChangeVarNodes(
(Node *)(qry->groupClause),
rt_index,
new_index,
sublevels_up);
}
break;
......@@ -562,6 +534,44 @@ AddNotQual(Query *parsetree, Node *qual)
AddQual(parsetree, copy);
}
void
AddGroupClause(Query *parsetree, List *group_by, List *tlist)
{
List *l;
List *tl;
GroupClause *groupclause;
TargetEntry *tle;
int new_resno;
new_resno = length(parsetree->targetList);
foreach (l, group_by)
{
groupclause = (GroupClause *)copyObject(lfirst(l));
tle = NULL;
foreach(tl, tlist)
{
if (((TargetEntry *)lfirst(tl))->resdom->resgroupref ==
groupclause->tleGroupref)
{
tle = (TargetEntry *)copyObject(lfirst(tl));
break;
}
}
if (tle == NULL)
elog(ERROR, "AddGroupClause(): GROUP BY entry not found in rules targetlist");
tle->resdom->resno = ++new_resno;
tle->resdom->resjunk = true;
tle->resdom->resgroupref = length(parsetree->groupClause) + 1;
groupclause->tleGroupref = tle->resdom->resgroupref;
parsetree->targetList = lappend(parsetree->targetList, tle);
parsetree->groupClause = lappend(parsetree->groupClause, groupclause);
}
}
static Node *
make_null(Oid type)
{
......@@ -688,7 +698,10 @@ ResolveNew(RewriteInfo *info, List *targetlist, Node **nodePtr,
*nodePtr = make_null(((Var *) node)->vartype);
}
else
{
*nodePtr = copyObject(n);
((Var *) *nodePtr)->varlevelsup = this_varlevelsup;
}
}
break;
}
......@@ -709,6 +722,8 @@ ResolveNew(RewriteInfo *info, List *targetlist, Node **nodePtr,
ResolveNew(info, targetlist, (Node **) &(query->qual), sublevels_up + 1);
}
break;
case T_GroupClause:
break;
default:
/* ignore the others */
break;
......@@ -720,7 +735,10 @@ FixNew(RewriteInfo *info, Query *parsetree)
{
ResolveNew(info, parsetree->targetList,
(Node **) &(info->rule_action->targetList), 0);
ResolveNew(info, parsetree->targetList, &info->rule_action->qual, 0);
ResolveNew(info, parsetree->targetList,
(Node **) &info->rule_action->qual, 0);
ResolveNew(info, parsetree->targetList,
(Node **) &(info->rule_action->groupClause), 0);
}
static void
......
......@@ -3,7 +3,7 @@
* out of it's tuple
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.11 1999/05/10 00:45:59 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.12 1999/05/12 15:01:58 wieck Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
......@@ -1263,9 +1263,23 @@ get_rule_expr(QryHier *qh, int rt_index, Node *node, bool varprefix)
case T_GroupClause:
{
GroupClause *grp = (GroupClause *) node;
List *l;
TargetEntry *tle = NULL;
return get_rule_expr(qh, rt_index,
(Node *) (grp->entry), varprefix);
foreach(l, qh->query->targetList)
{
if (((TargetEntry *)lfirst(l))->resdom->resgroupref ==
grp->tleGroupref)
{
tle = (TargetEntry *)lfirst(l);
break;
}
}
if (tle == NULL)
elog(ERROR, "GROUP BY expression not found in targetlist");
return get_rule_expr(qh, rt_index, (Node *)tle, varprefix);
}
break;
......@@ -1738,12 +1752,7 @@ check_if_rte_used(int rt_index, Node *node, int sup)
break;
case T_GroupClause:
{
GroupClause *grp = (GroupClause *) node;
return check_if_rte_used(rt_index,
(Node *) (grp->entry), sup);
}
return FALSE;
break;
case T_Expr:
......
......@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: parsenodes.h,v 1.71 1999/02/23 07:55:24 thomas Exp $
* $Id: parsenodes.h,v 1.72 1999/05/12 15:02:04 wieck Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -960,8 +960,8 @@ typedef struct SortClause
typedef struct GroupClause
{
NodeTag type;
TargetEntry *entry; /* attributes to group on */
Oid grpOpoid; /* the sort operator to use */
Index tleGroupref; /* reference into targetlist */
} GroupClause;
#define ROW_MARK_FOR_UPDATE (1 << 0)
......
......@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: primnodes.h,v 1.25 1999/02/13 23:21:40 momjian Exp $
* $Id: primnodes.h,v 1.26 1999/05/12 15:02:07 wieck Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -30,6 +30,7 @@
* resname - name of the resdom (could be NULL)
* reskey - order of key in a sort (for those > 0)
* reskeyop - sort operator Oid
* resgroupref - set to nonzero if referenced from a group by clause
* resjunk - set to nonzero to eliminate the attribute
* from final target list e.g., ctid for replace
* and delete
......@@ -45,6 +46,7 @@ typedef struct Resdom
char *resname;
Index reskey;
Oid reskeyop;
Index resgroupref;
int resjunk;
} Resdom;
......
......@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: relation.h,v 1.29 1999/02/22 19:55:44 momjian Exp $
* $Id: relation.h,v 1.30 1999/05/12 15:02:08 wieck Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -103,6 +103,7 @@ typedef struct RelOptInfo
} RelOptInfo;
extern Var *get_expr(TargetEntry *foo);
extern Var *get_groupclause_expr(GroupClause *groupClause, List *targetList);
typedef struct MergeOrder
{
......
......@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: planmain.h,v 1.24 1999/05/03 00:38:42 tgl Exp $
* $Id: planmain.h,v 1.25 1999/05/12 15:02:22 wieck Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -62,7 +62,9 @@ extern void replace_vars_with_subplan_refs(Node *clause,
List *subplanTargetList);
extern bool set_agg_tlist_references(Agg *aggNode);
extern void del_agg_tlist_references(List *tlist);
extern void check_having_for_ungrouped_vars(Node *clause, List *groupClause);
extern void check_having_for_ungrouped_vars(Node *clause,
List *groupClause,
List *targetList);
extern void transformKeySetQuery(Query *origNode);
#endif /* PLANMAIN_H */
......@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: rewriteManip.h,v 1.13 1999/02/13 23:22:00 momjian Exp $
* $Id: rewriteManip.h,v 1.14 1999/05/12 15:02:28 wieck Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -26,6 +26,7 @@ void AddHavingQual(Query *parsetree, Node *havingQual);
void AddNotQual(Query *parsetree, Node *qual);
void AddNotHavingQual(Query *parsetree, Node *havingQual);
void AddGroupClause(Query *parsetree, List *group_by, List *tlist);
void FixNew(RewriteInfo *info, Query *parsetree);
......
QUERY: SELECT p1.oid, p1.proname
FROM pg_proc as p1
WHERE p1.prolang = 0 OR p1.prorettype = 0 OR
p1.pronargs < 0 OR p1.pronargs > 9;
WHERE (p1.prolang = 0 OR p1.prorettype = 0 OR
p1.pronargs < 0 OR p1.pronargs > 9)
AND p1.proname !~ '^pl[^_]+_call_handler$';
oid|proname
---+-------
(0 rows)
......
......@@ -25,8 +25,9 @@
SELECT p1.oid, p1.proname
FROM pg_proc as p1
WHERE p1.prolang = 0 OR p1.prorettype = 0 OR
p1.pronargs < 0 OR p1.pronargs > 9;
WHERE (p1.prolang = 0 OR p1.prorettype = 0 OR
p1.pronargs < 0 OR p1.pronargs > 9)
AND p1.proname !~ '^pl[^_]+_call_handler$';
-- Look for conflicting proc definitions (same names and input datatypes).
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment