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 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -487,8 +487,8 @@ _copyGroupClause(GroupClause *from)
{ {
GroupClause *newnode = makeNode(GroupClause); GroupClause *newnode = makeNode(GroupClause);
Node_Copy(from, newnode, entry);
newnode->grpOpoid = from->grpOpoid; newnode->grpOpoid = from->grpOpoid;
newnode->tleGroupref = from->tleGroupref;
return newnode; return newnode;
} }
...@@ -589,6 +589,7 @@ _copyResdom(Resdom *from) ...@@ -589,6 +589,7 @@ _copyResdom(Resdom *from)
newnode->resname = pstrdup(from->resname); newnode->resname = pstrdup(from->resname);
newnode->reskey = from->reskey; newnode->reskey = from->reskey;
newnode->reskeyop = from->reskeyop; newnode->reskeyop = from->reskeyop;
newnode->resgroupref = from->resgroupref;
newnode->resjunk = from->resjunk; newnode->resjunk = from->resjunk;
return newnode; return newnode;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -48,6 +48,8 @@ _equalResdom(Resdom *a, Resdom *b)
return false; return false;
if (a->reskey != b->reskey) if (a->reskey != b->reskey)
return false; return false;
if (a->resgroupref != b->resgroupref)
return false;
if (a->reskeyop != b->reskeyop) if (a->reskeyop != b->reskeyop)
return false; return false;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -396,8 +396,6 @@ _freeAgg(Agg *node)
static void static void
_freeGroupClause(GroupClause *node) _freeGroupClause(GroupClause *node)
{ {
freeObject(node->entry);
pfree(node); pfree(node);
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* Creator functions in POSTGRES 4.2 are generated automatically. Most of * Creator functions in POSTGRES 4.2 are generated automatically. Most of
...@@ -107,6 +107,7 @@ makeResdom(AttrNumber resno, ...@@ -107,6 +107,7 @@ makeResdom(AttrNumber resno,
resdom->resname = resname; resdom->resname = resname;
resdom->reskey = reskey; resdom->reskey = reskey;
resdom->reskeyop = reskeyop; resdom->reskeyop = reskeyop;
resdom->resgroupref = 0;
resdom->resjunk = resjunk; resdom->resjunk = resjunk;
return resdom; return resdom;
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which * Every (plan) node in POSTGRES has an associated "out" routine which
...@@ -255,10 +255,9 @@ _outSortClause(StringInfo str, SortClause *node) ...@@ -255,10 +255,9 @@ _outSortClause(StringInfo str, SortClause *node)
static void static void
_outGroupClause(StringInfo str, GroupClause *node) _outGroupClause(StringInfo str, GroupClause *node)
{ {
appendStringInfo(str, " GROUPCLAUSE :entry "); appendStringInfo(str, " GROUPCLAUSE :grpOpoid %u :tleGroupref %d",
_outNode(str, node->entry); node->grpOpoid,
node->tleGroupref);
appendStringInfo(str, " :grpOpoid %u ", node->grpOpoid);
} }
/* /*
...@@ -556,15 +555,18 @@ _outHash(StringInfo str, Hash *node) ...@@ -556,15 +555,18 @@ _outHash(StringInfo str, Hash *node)
static void static void
_outResdom(StringInfo str, Resdom *node) _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->resno,
node->restype, node->restype,
node->restypmod); node->restypmod);
appendStringInfo(str, " :resname \"%s\" :reskey %d :reskeyop %u :resjunk %d", appendStringInfo(str, " :resname \"%s\" :reskey %d :reskeyop %u",
stringStringInfo(node->resname), stringStringInfo(node->resname),
node->reskey, node->reskey,
node->reskeyop, node->reskeyop);
appendStringInfo(str, " :resgroupref %d :resjunk %d",
node->resgroupref,
node->resjunk); node->resjunk);
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* Most of the read functions for plan nodes are tested. (In fact, they * Most of the read functions for plan nodes are tested. (In fact, they
...@@ -221,13 +221,14 @@ _readGroupClause() ...@@ -221,13 +221,14 @@ _readGroupClause()
local_node = makeNode(GroupClause); 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); /* skip :grpOpoid */
token = lsptok(NULL, &length); /* get grpOpoid */ token = lsptok(NULL, &length); /* get grpOpoid */
local_node->grpOpoid = strtoul(token, NULL, 10); 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; return local_node;
} }
...@@ -744,6 +745,10 @@ _readResdom() ...@@ -744,6 +745,10 @@ _readResdom()
token = lsptok(NULL, &length); /* get reskeyop */ token = lsptok(NULL, &length); /* get reskeyop */
local_node->reskeyop = (Oid) atol(token); 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); /* eat :resjunk */
token = lsptok(NULL, &length); /* get resjunk */ token = lsptok(NULL, &length); /* get resjunk */
local_node->resjunk = atoi(token); local_node->resjunk = atoi(token);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -260,7 +260,8 @@ union_planner(Query *parse)
* belong to?) * belong to?)
*/ */
check_having_for_ungrouped_vars(parse->havingQual, check_having_for_ungrouped_vars(parse->havingQual,
parse->groupClause); parse->groupClause,
parse->targetList);
} }
/* Calculate the opfids from the opnos */ /* Calculate the opfids from the opnos */
...@@ -426,8 +427,7 @@ make_subplanTargetList(Query *parse, ...@@ -426,8 +427,7 @@ make_subplanTargetList(Query *parse,
GroupClause *grpcl = (GroupClause *) lfirst(gl); GroupClause *grpcl = (GroupClause *) lfirst(gl);
keyno++; /* sort key # for this GroupClause */ keyno++; /* sort key # for this GroupClause */
/* Is it safe to use just resno to match tlist and glist items?? */ if (grpcl->tleGroupref == resdom->resgroupref)
if (grpcl->entry->resdom->resno == resdom->resno)
{ {
/* Found a matching groupclause; record info for sorting */ /* Found a matching groupclause; record info for sorting */
foundGroupClause = true; foundGroupClause = true;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -961,7 +961,8 @@ del_agg_clause(Node *clause)
*/ */
void void
check_having_for_ungrouped_vars(Node *clause, List *groupClause) check_having_for_ungrouped_vars(Node *clause, List *groupClause,
List *targetList)
{ {
List *t; List *t;
...@@ -981,7 +982,7 @@ check_having_for_ungrouped_vars(Node *clause, List *groupClause) ...@@ -981,7 +982,7 @@ check_having_for_ungrouped_vars(Node *clause, List *groupClause)
else if (IsA(clause, Iter)) else if (IsA(clause, Iter))
{ {
check_having_for_ungrouped_vars(((Iter *) clause)->iterexpr, check_having_for_ungrouped_vars(((Iter *) clause)->iterexpr,
groupClause); groupClause, targetList);
} }
else if (is_subplan(clause)) else if (is_subplan(clause))
{ {
...@@ -997,7 +998,8 @@ check_having_for_ungrouped_vars(Node *clause, List *groupClause) ...@@ -997,7 +998,8 @@ check_having_for_ungrouped_vars(Node *clause, List *groupClause)
foreach(gl, groupClause) foreach(gl, groupClause)
{ {
if (var_equal(lfirst(t), if (var_equal(lfirst(t),
get_expr(((GroupClause *) lfirst(gl))->entry))) get_groupclause_expr((GroupClause *)
lfirst(gl), targetList)))
{ {
contained_in_group_clause = true; contained_in_group_clause = true;
break; break;
...@@ -1016,7 +1018,8 @@ check_having_for_ungrouped_vars(Node *clause, List *groupClause) ...@@ -1016,7 +1018,8 @@ check_having_for_ungrouped_vars(Node *clause, List *groupClause)
* subplan is a kind of Expr node. * subplan is a kind of Expr node.
*/ */
foreach(t, ((Expr *) clause)->args) 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)) else if (IsA(clause, List))
{ {
...@@ -1024,12 +1027,13 @@ check_having_for_ungrouped_vars(Node *clause, List *groupClause) ...@@ -1024,12 +1027,13 @@ check_having_for_ungrouped_vars(Node *clause, List *groupClause)
* Recursively scan AND subclauses (see NOTE above). * Recursively scan AND subclauses (see NOTE above).
*/ */
foreach(t, ((List *) clause)) 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)) else if (IsA(clause, Aggref))
{ {
check_having_for_ungrouped_vars(((Aggref *) clause)->target, check_having_for_ungrouped_vars(((Aggref *) clause)->target,
groupClause); groupClause, targetList);
} }
else if (IsA(clause, ArrayRef)) else if (IsA(clause, ArrayRef))
{ {
...@@ -1040,22 +1044,28 @@ check_having_for_ungrouped_vars(Node *clause, List *groupClause) ...@@ -1040,22 +1044,28 @@ check_having_for_ungrouped_vars(Node *clause, List *groupClause)
* expression and its index expression... * expression and its index expression...
*/ */
foreach(t, aref->refupperindexpr) 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) foreach(t, aref->reflowerindexpr)
check_having_for_ungrouped_vars(lfirst(t), groupClause); check_having_for_ungrouped_vars(lfirst(t), groupClause,
check_having_for_ungrouped_vars(aref->refexpr, groupClause); targetList);
check_having_for_ungrouped_vars(aref->refassgnexpr, groupClause); check_having_for_ungrouped_vars(aref->refexpr, groupClause,
targetList);
check_having_for_ungrouped_vars(aref->refassgnexpr, groupClause,
targetList);
} }
else if (case_clause(clause)) else if (case_clause(clause))
{ {
foreach(t, ((CaseExpr *) clause)->args) foreach(t, ((CaseExpr *) clause)->args)
{ {
CaseWhen *when = (CaseWhen *) lfirst(t); CaseWhen *when = (CaseWhen *) lfirst(t);
check_having_for_ungrouped_vars(when->expr, groupClause); check_having_for_ungrouped_vars(when->expr, groupClause,
check_having_for_ungrouped_vars(when->result, groupClause); targetList);
check_having_for_ungrouped_vars(when->result, groupClause,
targetList);
} }
check_having_for_ungrouped_vars(((CaseExpr *) clause)->defresult, check_having_for_ungrouped_vars(((CaseExpr *) clause)->defresult,
groupClause); groupClause, targetList);
} }
else else
{ {
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -229,6 +229,49 @@ replace_matching_resname(List *new_tlist, List *old_tlist)
new_tl = makeTargetEntry(newresno, old_tle->expr); new_tl = makeTargetEntry(newresno, old_tle->expr);
t_list = lappend(t_list, new_tl); 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; return t_list;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -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) ...@@ -528,6 +547,11 @@ get_expr(TargetEntry *tle)
* in there. * in there.
*/ */
#ifdef NOT_USED #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 void
AddGroupAttrToTlist(List *tlist, List *grpCl) AddGroupAttrToTlist(List *tlist, List *grpCl)
{ {
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 @@ ...@@ -32,8 +32,9 @@
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
static bool contain_agg_clause(Node *clause); static bool contain_agg_clause(Node *clause);
static bool exprIsAggOrGroupCol(Node *expr, List *groupClause); static bool exprIsAggOrGroupCol(Node *expr, List *groupClause, List *tlist);
static bool tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause); static bool tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause,
List *tlist);
/* /*
* contain_agg_clause * contain_agg_clause
...@@ -100,7 +101,7 @@ contain_agg_clause(Node *clause) ...@@ -100,7 +101,7 @@ contain_agg_clause(Node *clause)
* returns true if the expression does not contain non-group columns. * returns true if the expression does not contain non-group columns.
*/ */
static bool static bool
exprIsAggOrGroupCol(Node *expr, List *groupClause) exprIsAggOrGroupCol(Node *expr, List *groupClause, List *tlist)
{ {
List *gl; List *gl;
...@@ -113,7 +114,7 @@ exprIsAggOrGroupCol(Node *expr, List *groupClause) ...@@ -113,7 +114,7 @@ exprIsAggOrGroupCol(Node *expr, List *groupClause)
{ {
GroupClause *grpcl = lfirst(gl); GroupClause *grpcl = lfirst(gl);
if (equal(expr, grpcl->entry->expr)) if (equal(expr, get_groupclause_expr(grpcl, tlist)))
return TRUE; return TRUE;
} }
...@@ -122,7 +123,7 @@ exprIsAggOrGroupCol(Node *expr, List *groupClause) ...@@ -122,7 +123,7 @@ exprIsAggOrGroupCol(Node *expr, List *groupClause)
List *temp; List *temp;
foreach(temp, ((Expr *) expr)->args) foreach(temp, ((Expr *) expr)->args)
if (!exprIsAggOrGroupCol(lfirst(temp), groupClause)) if (!exprIsAggOrGroupCol(lfirst(temp), groupClause, tlist))
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
...@@ -135,7 +136,7 @@ exprIsAggOrGroupCol(Node *expr, List *groupClause) ...@@ -135,7 +136,7 @@ exprIsAggOrGroupCol(Node *expr, List *groupClause)
* returns true if the TargetEntry is Agg or GroupCol. * returns true if the TargetEntry is Agg or GroupCol.
*/ */
static bool static bool
tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause) tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause, List *tlist)
{ {
Node *expr = tle->expr; Node *expr = tle->expr;
List *gl; List *gl;
...@@ -147,7 +148,7 @@ tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause) ...@@ -147,7 +148,7 @@ tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause)
{ {
GroupClause *grpcl = lfirst(gl); GroupClause *grpcl = lfirst(gl);
if (tle->resdom->resno == grpcl->entry->resdom->resno) if (tle->resdom->resgroupref == grpcl->tleGroupref)
{ {
if (contain_agg_clause((Node *) expr)) if (contain_agg_clause((Node *) expr))
elog(ERROR, "Aggregates not allowed in GROUP BY clause"); elog(ERROR, "Aggregates not allowed in GROUP BY clause");
...@@ -163,7 +164,7 @@ tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause) ...@@ -163,7 +164,7 @@ tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause)
List *temp; List *temp;
foreach(temp, ((Expr *) expr)->args) foreach(temp, ((Expr *) expr)->args)
if (!exprIsAggOrGroupCol(lfirst(temp), groupClause)) if (!exprIsAggOrGroupCol(lfirst(temp), groupClause, tlist))
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
...@@ -200,7 +201,7 @@ parseCheckAggregates(ParseState *pstate, Query *qry) ...@@ -200,7 +201,7 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
{ {
TargetEntry *tle = lfirst(tl); TargetEntry *tle = lfirst(tl);
if (!tleIsAggOrGroupCol(tle, qry->groupClause)) if (!tleIsAggOrGroupCol(tle, qry->groupClause, qry->targetList))
elog(ERROR, elog(ERROR,
"Illegal use of aggregates or non-group column in target list"); "Illegal use of aggregates or non-group column in target list");
} }
...@@ -210,7 +211,7 @@ parseCheckAggregates(ParseState *pstate, Query *qry) ...@@ -210,7 +211,7 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
* restriction as those in the target list. * restriction as those in the target list.
*/ */
if (!exprIsAggOrGroupCol(qry->havingQual, qry->groupClause)) if (!exprIsAggOrGroupCol(qry->havingQual, qry->groupClause, qry->targetList))
elog(ERROR, elog(ERROR,
"Illegal use of aggregates or non-group column in HAVING clause"); "Illegal use of aggregates or non-group column in HAVING clause");
return; return;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -550,13 +550,19 @@ transformGroupClause(ParseState *pstate, List *grouplist, List *targetlist)
restarget = findTargetlistEntry(pstate, lfirst(grouplist), targetlist, GROUP_CLAUSE); restarget = findTargetlistEntry(pstate, lfirst(grouplist), targetlist, GROUP_CLAUSE);
grpcl->entry = restarget;
resdom = restarget->resdom; resdom = restarget->resdom;
grpcl->grpOpoid = oprid(oper("<", grpcl->grpOpoid = oprid(oper("<",
resdom->restype, resdom->restype,
resdom->restype, false)); resdom->restype, false));
if (glist == NIL) if (glist == NIL)
{
int groupref = length(glist) + 1;
restarget->resdom->resgroupref = groupref;
grpcl->tleGroupref = groupref;
gl = glist = lcons(grpcl, NIL); gl = glist = lcons(grpcl, NIL);
}
else else
{ {
List *i; List *i;
...@@ -565,11 +571,17 @@ transformGroupClause(ParseState *pstate, List *grouplist, List *targetlist) ...@@ -565,11 +571,17 @@ transformGroupClause(ParseState *pstate, List *grouplist, List *targetlist)
{ {
GroupClause *gcl = (GroupClause *) lfirst(i); GroupClause *gcl = (GroupClause *) lfirst(i);
if (gcl->entry == grpcl->entry) if (equal(get_groupclause_expr(gcl, targetlist),
restarget->expr))
break; break;
} }
if (i == NIL) /* not in grouplist already */ if (i == NIL) /* not in grouplist already */
{ {
int groupref = length(glist) + 1;
restarget->resdom->resgroupref = groupref;
grpcl->tleGroupref = groupref;
lnext(gl) = lcons(grpcl, NIL); lnext(gl) = lcons(grpcl, NIL);
gl = lnext(gl); gl = lnext(gl);
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -170,15 +170,7 @@ rangeTableEntry_used(Node *node, int rt_index, int sublevels_up)
break; break;
case T_GroupClause: case T_GroupClause:
{ return FALSE;
GroupClause *grp = (GroupClause *)node;
return rangeTableEntry_used(
(Node *)(grp->entry),
rt_index,
sublevels_up);
}
break;
case T_Expr: case T_Expr:
{ {
...@@ -348,12 +340,6 @@ rangeTableEntry_used(Node *node, int rt_index, int sublevels_up) ...@@ -348,12 +340,6 @@ rangeTableEntry_used(Node *node, int rt_index, int sublevels_up)
sublevels_up)) sublevels_up))
return TRUE; return TRUE;
if (rangeTableEntry_used(
(Node *)(qry->groupClause),
rt_index,
sublevels_up))
return TRUE;
return FALSE; return FALSE;
} }
break; break;
...@@ -407,16 +393,7 @@ attribute_used(Node *node, int rt_index, int attno, int sublevels_up) ...@@ -407,16 +393,7 @@ attribute_used(Node *node, int rt_index, int attno, int sublevels_up)
break; break;
case T_GroupClause: case T_GroupClause:
{ return FALSE;
GroupClause *grp = (GroupClause *)node;
return attribute_used(
(Node *)(grp->entry),
rt_index,
attno,
sublevels_up);
}
break;
case T_Expr: case T_Expr:
{ {
...@@ -558,13 +535,6 @@ attribute_used(Node *node, int rt_index, int attno, int sublevels_up) ...@@ -558,13 +535,6 @@ attribute_used(Node *node, int rt_index, int attno, int sublevels_up)
sublevels_up)) sublevels_up))
return TRUE; return TRUE;
if (attribute_used(
(Node *)(qry->groupClause),
rt_index,
attno,
sublevels_up))
return TRUE;
return FALSE; return FALSE;
} }
break; break;
...@@ -697,8 +667,6 @@ modifyAggrefUplevel(Node *node) ...@@ -697,8 +667,6 @@ modifyAggrefUplevel(Node *node)
modifyAggrefUplevel( modifyAggrefUplevel(
(Node *)(qry->havingQual)); (Node *)(qry->havingQual));
modifyAggrefUplevel(
(Node *)(qry->groupClause));
} }
break; break;
...@@ -752,15 +720,6 @@ modifyAggrefChangeVarnodes(Node **nodePtr, int rt_index, int new_index, int subl ...@@ -752,15 +720,6 @@ modifyAggrefChangeVarnodes(Node **nodePtr, int rt_index, int new_index, int subl
break; break;
case T_GroupClause: case T_GroupClause:
{
GroupClause *grp = (GroupClause *)node;
modifyAggrefChangeVarnodes(
(Node **)(&(grp->entry)),
rt_index,
new_index,
sublevels_up);
}
break; break;
case T_Expr: case T_Expr:
...@@ -894,12 +853,6 @@ modifyAggrefChangeVarnodes(Node **nodePtr, int rt_index, int new_index, int subl ...@@ -894,12 +853,6 @@ modifyAggrefChangeVarnodes(Node **nodePtr, int rt_index, int new_index, int subl
rt_index, rt_index,
new_index, new_index,
sublevels_up); sublevels_up);
modifyAggrefChangeVarnodes(
(Node **)(&(qry->groupClause)),
rt_index,
new_index,
sublevels_up);
} }
break; break;
...@@ -1186,13 +1139,6 @@ modifyAggrefQual(Node **nodePtr, Query *parsetree) ...@@ -1186,13 +1139,6 @@ modifyAggrefQual(Node **nodePtr, Query *parsetree)
break; break;
case T_GroupClause: case T_GroupClause:
{
GroupClause *grp = (GroupClause *)node;
modifyAggrefQual(
(Node **)(&(grp->entry)),
parsetree);
}
break; break;
case T_Expr: case T_Expr:
...@@ -1386,13 +1332,6 @@ apply_RIR_adjust_sublevel(Node *node, int sublevels_up) ...@@ -1386,13 +1332,6 @@ apply_RIR_adjust_sublevel(Node *node, int sublevels_up)
break; break;
case T_GroupClause: case T_GroupClause:
{
GroupClause *grp = (GroupClause *)node;
apply_RIR_adjust_sublevel(
(Node *)(grp->entry),
sublevels_up);
}
break; break;
case T_Expr: case T_Expr:
...@@ -1539,17 +1478,6 @@ apply_RIR_view(Node **nodePtr, int rt_index, RangeTblEntry *rte, List *tlist, in ...@@ -1539,17 +1478,6 @@ apply_RIR_view(Node **nodePtr, int rt_index, RangeTblEntry *rte, List *tlist, in
break; break;
case T_GroupClause: case T_GroupClause:
{
GroupClause *grp = (GroupClause *)node;
apply_RIR_view(
(Node **)(&(grp->entry)),
rt_index,
rte,
tlist,
modified,
sublevels_up);
}
break; break;
case T_Expr: case T_Expr:
...@@ -1724,14 +1652,6 @@ apply_RIR_view(Node **nodePtr, int rt_index, RangeTblEntry *rte, List *tlist, in ...@@ -1724,14 +1652,6 @@ apply_RIR_view(Node **nodePtr, int rt_index, RangeTblEntry *rte, List *tlist, in
tlist, tlist,
modified, modified,
sublevels_up); sublevels_up);
apply_RIR_view(
(Node **)(&(qry->groupClause)),
rt_index,
rte,
tlist,
modified,
sublevels_up);
} }
break; break;
...@@ -1898,10 +1818,8 @@ ApplyRetrieveRule(Query *parsetree, ...@@ -1898,10 +1818,8 @@ ApplyRetrieveRule(Query *parsetree,
} }
if (*modified && !badsql) { if (*modified && !badsql) {
AddQual(parsetree, rule_action->qual); AddQual(parsetree, rule_action->qual);
/* This will only work if the query made to the view defined by the following AddGroupClause(parsetree, rule_action->groupClause,
* groupClause groups by the same attributes or does not use group at all! */ rule_action->targetList);
if (parsetree->groupClause == NULL)
parsetree->groupClause=rule_action->groupClause;
AddHavingQual(parsetree, rule_action->havingQual); AddHavingQual(parsetree, rule_action->havingQual);
parsetree->hasAggs = (rule_action->hasAggs || parsetree->hasAggs); parsetree->hasAggs = (rule_action->hasAggs || parsetree->hasAggs);
parsetree->hasSubLinks = (rule_action->hasSubLinks || parsetree->hasSubLinks); parsetree->hasSubLinks = (rule_action->hasSubLinks || parsetree->hasSubLinks);
...@@ -1935,12 +1853,6 @@ fireRIRonSubselect(Node *node) ...@@ -1935,12 +1853,6 @@ fireRIRonSubselect(Node *node)
break; break;
case T_GroupClause: case T_GroupClause:
{
GroupClause *grp = (GroupClause *)node;
fireRIRonSubselect(
(Node *)(grp->entry));
}
break; break;
case T_Expr: case T_Expr:
...@@ -2048,9 +1960,6 @@ fireRIRonSubselect(Node *node) ...@@ -2048,9 +1960,6 @@ fireRIRonSubselect(Node *node)
fireRIRonSubselect( fireRIRonSubselect(
(Node *)(qry->havingQual)); (Node *)(qry->havingQual));
fireRIRonSubselect(
(Node *)(qry->groupClause));
} }
break; break;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -65,14 +65,6 @@ OffsetVarNodes(Node *node, int offset, int sublevels_up)
break; break;
case T_GroupClause: case T_GroupClause:
{
GroupClause *grp = (GroupClause *)node;
OffsetVarNodes(
(Node *)(grp->entry),
offset,
sublevels_up);
}
break; break;
case T_Expr: case T_Expr:
...@@ -199,11 +191,6 @@ OffsetVarNodes(Node *node, int offset, int sublevels_up) ...@@ -199,11 +191,6 @@ OffsetVarNodes(Node *node, int offset, int sublevels_up)
(Node *)(qry->havingQual), (Node *)(qry->havingQual),
offset, offset,
sublevels_up); sublevels_up);
OffsetVarNodes(
(Node *)(qry->groupClause),
offset,
sublevels_up);
} }
break; break;
...@@ -284,15 +271,6 @@ ChangeVarNodes(Node *node, int rt_index, int new_index, int sublevels_up) ...@@ -284,15 +271,6 @@ ChangeVarNodes(Node *node, int rt_index, int new_index, int sublevels_up)
break; break;
case T_GroupClause: case T_GroupClause:
{
GroupClause *grp = (GroupClause *)node;
ChangeVarNodes(
(Node *)(grp->entry),
rt_index,
new_index,
sublevels_up);
}
break; break;
case T_Expr: case T_Expr:
...@@ -430,12 +408,6 @@ ChangeVarNodes(Node *node, int rt_index, int new_index, int sublevels_up) ...@@ -430,12 +408,6 @@ ChangeVarNodes(Node *node, int rt_index, int new_index, int sublevels_up)
rt_index, rt_index,
new_index, new_index,
sublevels_up); sublevels_up);
ChangeVarNodes(
(Node *)(qry->groupClause),
rt_index,
new_index,
sublevels_up);
} }
break; break;
...@@ -562,6 +534,44 @@ AddNotQual(Query *parsetree, Node *qual) ...@@ -562,6 +534,44 @@ AddNotQual(Query *parsetree, Node *qual)
AddQual(parsetree, copy); 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 * static Node *
make_null(Oid type) make_null(Oid type)
{ {
...@@ -688,7 +698,10 @@ ResolveNew(RewriteInfo *info, List *targetlist, Node **nodePtr, ...@@ -688,7 +698,10 @@ ResolveNew(RewriteInfo *info, List *targetlist, Node **nodePtr,
*nodePtr = make_null(((Var *) node)->vartype); *nodePtr = make_null(((Var *) node)->vartype);
} }
else else
{
*nodePtr = copyObject(n); *nodePtr = copyObject(n);
((Var *) *nodePtr)->varlevelsup = this_varlevelsup;
}
} }
break; break;
} }
...@@ -709,6 +722,8 @@ ResolveNew(RewriteInfo *info, List *targetlist, Node **nodePtr, ...@@ -709,6 +722,8 @@ ResolveNew(RewriteInfo *info, List *targetlist, Node **nodePtr,
ResolveNew(info, targetlist, (Node **) &(query->qual), sublevels_up + 1); ResolveNew(info, targetlist, (Node **) &(query->qual), sublevels_up + 1);
} }
break; break;
case T_GroupClause:
break;
default: default:
/* ignore the others */ /* ignore the others */
break; break;
...@@ -720,7 +735,10 @@ FixNew(RewriteInfo *info, Query *parsetree) ...@@ -720,7 +735,10 @@ FixNew(RewriteInfo *info, Query *parsetree)
{ {
ResolveNew(info, parsetree->targetList, ResolveNew(info, parsetree->targetList,
(Node **) &(info->rule_action->targetList), 0); (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 static void
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* out of it's tuple * out of it's tuple
* *
* IDENTIFICATION * 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. * This software is copyrighted by Jan Wieck - Hamburg.
* *
...@@ -1263,9 +1263,23 @@ get_rule_expr(QryHier *qh, int rt_index, Node *node, bool varprefix) ...@@ -1263,9 +1263,23 @@ get_rule_expr(QryHier *qh, int rt_index, Node *node, bool varprefix)
case T_GroupClause: case T_GroupClause:
{ {
GroupClause *grp = (GroupClause *) node; GroupClause *grp = (GroupClause *) node;
List *l;
TargetEntry *tle = NULL;
return get_rule_expr(qh, rt_index, foreach(l, qh->query->targetList)
(Node *) (grp->entry), varprefix); {
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; break;
...@@ -1738,12 +1752,7 @@ check_if_rte_used(int rt_index, Node *node, int sup) ...@@ -1738,12 +1752,7 @@ check_if_rte_used(int rt_index, Node *node, int sup)
break; break;
case T_GroupClause: case T_GroupClause:
{ return FALSE;
GroupClause *grp = (GroupClause *) node;
return check_if_rte_used(rt_index,
(Node *) (grp->entry), sup);
}
break; break;
case T_Expr: case T_Expr:
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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 ...@@ -960,8 +960,8 @@ typedef struct SortClause
typedef struct GroupClause typedef struct GroupClause
{ {
NodeTag type; NodeTag type;
TargetEntry *entry; /* attributes to group on */
Oid grpOpoid; /* the sort operator to use */ Oid grpOpoid; /* the sort operator to use */
Index tleGroupref; /* reference into targetlist */
} GroupClause; } GroupClause;
#define ROW_MARK_FOR_UPDATE (1 << 0) #define ROW_MARK_FOR_UPDATE (1 << 0)
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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 @@ ...@@ -30,6 +30,7 @@
* resname - name of the resdom (could be NULL) * resname - name of the resdom (could be NULL)
* reskey - order of key in a sort (for those > 0) * reskey - order of key in a sort (for those > 0)
* reskeyop - sort operator Oid * reskeyop - sort operator Oid
* resgroupref - set to nonzero if referenced from a group by clause
* resjunk - set to nonzero to eliminate the attribute * resjunk - set to nonzero to eliminate the attribute
* from final target list e.g., ctid for replace * from final target list e.g., ctid for replace
* and delete * and delete
...@@ -45,6 +46,7 @@ typedef struct Resdom ...@@ -45,6 +46,7 @@ typedef struct Resdom
char *resname; char *resname;
Index reskey; Index reskey;
Oid reskeyop; Oid reskeyop;
Index resgroupref;
int resjunk; int resjunk;
} Resdom; } Resdom;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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 ...@@ -103,6 +103,7 @@ typedef struct RelOptInfo
} RelOptInfo; } RelOptInfo;
extern Var *get_expr(TargetEntry *foo); extern Var *get_expr(TargetEntry *foo);
extern Var *get_groupclause_expr(GroupClause *groupClause, List *targetList);
typedef struct MergeOrder typedef struct MergeOrder
{ {
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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, ...@@ -62,7 +62,9 @@ extern void replace_vars_with_subplan_refs(Node *clause,
List *subplanTargetList); List *subplanTargetList);
extern bool set_agg_tlist_references(Agg *aggNode); extern bool set_agg_tlist_references(Agg *aggNode);
extern void del_agg_tlist_references(List *tlist); 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); extern void transformKeySetQuery(Query *origNode);
#endif /* PLANMAIN_H */ #endif /* PLANMAIN_H */
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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); ...@@ -26,6 +26,7 @@ void AddHavingQual(Query *parsetree, Node *havingQual);
void AddNotQual(Query *parsetree, Node *qual); void AddNotQual(Query *parsetree, Node *qual);
void AddNotHavingQual(Query *parsetree, Node *havingQual); void AddNotHavingQual(Query *parsetree, Node *havingQual);
void AddGroupClause(Query *parsetree, List *group_by, List *tlist);
void FixNew(RewriteInfo *info, Query *parsetree); void FixNew(RewriteInfo *info, Query *parsetree);
......
QUERY: SELECT p1.oid, p1.proname QUERY: SELECT p1.oid, p1.proname
FROM pg_proc as p1 FROM pg_proc as p1
WHERE p1.prolang = 0 OR p1.prorettype = 0 OR WHERE (p1.prolang = 0 OR p1.prorettype = 0 OR
p1.pronargs < 0 OR p1.pronargs > 9; p1.pronargs < 0 OR p1.pronargs > 9)
AND p1.proname !~ '^pl[^_]+_call_handler$';
oid|proname oid|proname
---+------- ---+-------
(0 rows) (0 rows)
......
...@@ -25,8 +25,9 @@ ...@@ -25,8 +25,9 @@
SELECT p1.oid, p1.proname SELECT p1.oid, p1.proname
FROM pg_proc as p1 FROM pg_proc as p1
WHERE p1.prolang = 0 OR p1.prorettype = 0 OR WHERE (p1.prolang = 0 OR p1.prorettype = 0 OR
p1.pronargs < 0 OR p1.pronargs > 9; p1.pronargs < 0 OR p1.pronargs > 9)
AND p1.proname !~ '^pl[^_]+_call_handler$';
-- Look for conflicting proc definitions (same names and input datatypes). -- 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