KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > sql > compile > VerifyAggregateExpressionsVisitor


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.compile.VerifyAggregateExpressionsVisitor
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.sql.compile;
23
24 import org.apache.derby.iapi.sql.compile.Visitable;
25 import org.apache.derby.iapi.sql.compile.Visitor;
26
27 import org.apache.derby.iapi.reference.SQLState;
28 import org.apache.derby.iapi.error.StandardException;
29
30 /**
31  * If a RCL (SELECT list) contains an aggregate, then we must verify
32  * that the RCL (SELECT list) is valid.
33  * For ungrouped queries,
34  * the RCL must be composed entirely of valid aggregate expressions -
35  * in this case, no column references outside of an aggregate.
36  * For grouped aggregates,
37  * the RCL must be composed of grouping columns or valid aggregate
38  * expressions - in this case, the only column references allowed outside of
39  * an aggregate are grouping columns.
40  *
41  * @author jamie, from code written by jerry
42  */

43 public class VerifyAggregateExpressionsVisitor implements Visitor
44 {
45     private GroupByList groupByList;
46
47     public VerifyAggregateExpressionsVisitor(GroupByList groupByList)
48     {
49         this.groupByList = groupByList;
50     }
51
52
53     ////////////////////////////////////////////////
54
//
55
// VISITOR INTERFACE
56
//
57
////////////////////////////////////////////////
58

59     /**
60      * Verify that this expression is ok
61      * for an aggregate query.
62      *
63      * @param node the node to process
64      *
65      * @return me
66      *
67      * @exception StandardException on ColumnReference not
68      * in group by list, ValueNode or
69      * JavaValueNode that isn't under an
70      * aggregate
71      */

72     public Visitable visit(Visitable node)
73         throws StandardException
74     {
75         if (node instanceof ColumnReference)
76         {
77             ColumnReference cr = (ColumnReference)node;
78         
79             if (groupByList == null)
80             {
81                 throw StandardException.newException(SQLState.LANG_INVALID_COL_REF_NON_GROUPED_SELECT_LIST, cr.getSQLColumnName());
82             }
83
84             if (groupByList.findGroupingColumn(cr) == null)
85             {
86                 throw StandardException.newException(SQLState.LANG_INVALID_GROUPED_SELECT_LIST);
87             }
88         }
89         
90         /*
91         ** Subqueries are only valid if they do not have
92         ** correlations and are expression subqueries. RESOLVE:
93         ** this permits VARIANT expressions in the subquery --
94         ** should this be allowed? may be confusing to
95         ** users to complain about:
96         **
97         ** select max(x), (select sum(y).toString() from y) from x
98         */

99         else if (node instanceof SubqueryNode)
100         {
101             SubqueryNode subq = (SubqueryNode)node;
102         
103             if ((subq.getSubqueryType() != SubqueryNode.EXPRESSION_SUBQUERY) ||
104                  subq.hasCorrelatedCRs())
105             {
106                 throw StandardException.newException( (groupByList == null) ?
107                             SQLState.LANG_INVALID_NON_GROUPED_SELECT_LIST :
108                             SQLState.LANG_INVALID_GROUPED_SELECT_LIST);
109             }
110
111             /*
112             ** TEMPORARY RESTRICTION: we cannot handle an aggregate
113             ** in the subquery
114             */

115             HasNodeVisitor visitor = new HasNodeVisitor(AggregateNode.class);
116             subq.accept(visitor);
117             if (visitor.hasNode())
118             {
119                 throw StandardException.newException( (groupByList == null) ?
120                             SQLState.LANG_INVALID_NON_GROUPED_SELECT_LIST :
121                             SQLState.LANG_INVALID_GROUPED_SELECT_LIST);
122             }
123         } else if (node instanceof JavaToSQLValueNode)
124         {
125             // disallow any expression which involves native java computation.
126
// Not possible to consider java expressions for equivalence.
127
throw StandardException.newException( (groupByList == null) ?
128                     SQLState.LANG_INVALID_NON_GROUPED_SELECT_LIST :
129                         SQLState.LANG_INVALID_GROUPED_SELECT_LIST);
130         }
131
132         return node;
133     }
134
135     /**
136      * Don't visit children under an aggregate, subquery or any node which
137      * is equivalent to any of the group by expressions.
138      *
139      * @param node the node to process
140      *
141      * @return true/false
142      * @throws StandardException
143      */

144     public boolean skipChildren(Visitable node) throws StandardException
145     {
146         return ((node instanceof AggregateNode) ||
147                 (node instanceof SubqueryNode) ||
148                 (node instanceof ValueNode &&
149                         groupByList != null
150                         && groupByList.findGroupingColumn((ValueNode)node) != null));
151     }
152     
153     public boolean stopTraversal()
154     {
155         return false;
156     }
157 }
158
Popular Tags