aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Wieck <JanWieck@Yahoo.com>1999-05-12 17:04:47 +0000
committerJan Wieck <JanWieck@Yahoo.com>1999-05-12 17:04:47 +0000
commitb7a86e4046ce480614a3adae0ddcc52d6673c020 (patch)
tree1a717b2ef2044f7d2aa95ff05a6d9c1f1c4c9c69
parent79c2576f775b962c67cac136722c5c7cc98201aa (diff)
downloadpostgresql-b7a86e4046ce480614a3adae0ddcc52d6673c020.tar.gz
postgresql-b7a86e4046ce480614a3adae0ddcc52d6673c020.zip
Fixed wrong hasAggs when aggregate columns of view aren't
selected. Disabled ability of defining DISTINCT or ORDER BY on views. Jan
-rw-r--r--src/backend/rewrite/rewriteDefine.c14
-rw-r--r--src/backend/rewrite/rewriteHandler.c136
2 files changed, 146 insertions, 4 deletions
diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c
index 1053df421ee..431006843f2 100644
--- a/src/backend/rewrite/rewriteDefine.c
+++ b/src/backend/rewrite/rewriteDefine.c
@@ -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 $
*
*-------------------------------------------------------------------------
*/
@@ -318,6 +318,18 @@ DefineQueryRewrite(RuleStmt *stmt)
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.
*/
sprintf(expected_name, "_RET%s", event_obj->relname);
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index 654f7310805..c5503a6f0b1 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -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;
}