Commit b7a86e40 authored by Jan Wieck's avatar Jan Wieck

Fixed wrong hasAggs when aggregate columns of view aren't

selected.

Disabled ability of defining DISTINCT or ORDER BY on views.

Jan
parent 79c2576f
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.27 1999/05/10 00:45:30 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.28 1999/05/12 17:04:46 wieck Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -317,6 +317,18 @@ DefineQueryRewrite(RuleStmt *stmt)
if (query->limitOffset != NULL || query->limitCount != NULL)
elog(ERROR, "LIMIT clause not supported in views");
/*
* DISTINCT on view is not supported
*/
if (query->uniqueFlag != NULL)
elog(ERROR, "DISTINCT not supported in views");
/*
* ORDER BY in view is not supported
*/
if (query->sortClause != NIL)
elog(ERROR, "ORDER BY not supported in views");
/*
* ... and finally the rule must be named _RETviewname.
*/
......
......@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.39 1999/05/12 15:01:53 wieck Exp $
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.40 1999/05/12 17:04:47 wieck Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -59,6 +59,7 @@ static void modifyAggrefChangeVarnodes(Node **nodePtr, int rt_index, int new_ind
static void modifyAggrefDropQual(Node **nodePtr, Node *orignode, Expr *expr);
static SubLink *modifyAggrefMakeSublink(Expr *origexp, Query *parsetree);
static void modifyAggrefQual(Node **nodePtr, Query *parsetree);
static bool checkQueryHasAggs(Node *node);
static Query *fireRIRrules(Query *parsetree);
......@@ -1272,6 +1273,126 @@ modifyAggrefQual(Node **nodePtr, Query *parsetree)
}
/*
* checkQueryHasAggs -
* Queries marked hasAggs might not have them any longer after
* rewriting. Check it.
*/
static bool
checkQueryHasAggs(Node *node)
{
if (node == NULL)
return FALSE;
switch(nodeTag(node)) {
case T_TargetEntry:
{
TargetEntry *tle = (TargetEntry *)node;
return checkQueryHasAggs((Node *)(tle->expr));
}
break;
case T_Aggref:
return TRUE;
case T_Expr:
{
Expr *exp = (Expr *)node;
return checkQueryHasAggs((Node *)(exp->args));
}
break;
case T_Iter:
{
Iter *iter = (Iter *)node;
return checkQueryHasAggs((Node *)(iter->iterexpr));
}
break;
case T_ArrayRef:
{
ArrayRef *ref = (ArrayRef *)node;
if (checkQueryHasAggs((Node *)(ref->refupperindexpr)))
return TRUE;
if (checkQueryHasAggs((Node *)(ref->reflowerindexpr)))
return TRUE;
if (checkQueryHasAggs((Node *)(ref->refexpr)))
return TRUE;
if (checkQueryHasAggs((Node *)(ref->refassgnexpr)))
return TRUE;
return FALSE;
}
break;
case T_Var:
return FALSE;
case T_Param:
return FALSE;
case T_Const:
return FALSE;
case T_List:
{
List *l;
foreach (l, (List *)node) {
if (checkQueryHasAggs((Node *)lfirst(l)))
return TRUE;
}
return FALSE;
}
break;
case T_CaseExpr:
{
CaseExpr *exp = (CaseExpr *)node;
if (checkQueryHasAggs((Node *)(exp->args)))
return TRUE;
if (checkQueryHasAggs((Node *)(exp->defresult)))
return TRUE;
return FALSE;
}
break;
case T_CaseWhen:
{
CaseWhen *when = (CaseWhen *)node;
if (checkQueryHasAggs((Node *)(when->expr)))
return TRUE;
if (checkQueryHasAggs((Node *)(when->result)))
return TRUE;
return FALSE;
}
break;
default:
elog(NOTICE, "unknown node tag %d in checkQueryHasAggs()", nodeTag(node));
elog(NOTICE, "Node is: %s", nodeToString(node));
break;
}
return FALSE;
}
static Node *
FindMatchingTLEntry(List *tlist, char *e_attname)
{
......@@ -2574,8 +2695,17 @@ BasicQueryRewrite(Query *parsetree)
* Apply all the RIR rules on each query
*/
foreach (l, querylist) {
query = (Query *)lfirst(l);
results = lappend(results, fireRIRrules(query));
query = fireRIRrules((Query *)lfirst(l));
/*
* If the query was marked having aggregates, check if
* this is still true after rewriting. This check must get
* expanded when someday aggregates can appear somewhere
* else than in the targetlist or the having qual.
*/
if (query->hasAggs)
query->hasAggs = checkQueryHasAggs((Node *)(query->targetList))
| checkQueryHasAggs((Node *)(query->havingQual));
results = lappend(results, query);
}
return results;
}
......
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