001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.compile.SubqueryList
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.sql.compile;
023:
024: import org.apache.derby.iapi.sql.dictionary.DataDictionary;
025:
026: import org.apache.derby.iapi.error.StandardException;
027:
028: import org.apache.derby.iapi.services.sanity.SanityManager;
029:
030: /**
031: * A SubqueryList represents a list of subquerys within a specific clause
032: * (select, where or having) in a DML statement. It extends QueryTreeNodeVector.
033: *
034: * @author Jerry Brenner
035: */
036:
037: public class SubqueryList extends QueryTreeNodeVector {
038:
039: /**
040: * Prints the sub-nodes of this object. See QueryTreeNode.java for
041: * how tree printing is supposed to work.
042: *
043: * @param depth The depth of this node in the tree
044: */
045:
046: public void printSubNodes(int depth) {
047: if (SanityManager.DEBUG) {
048: SubqueryNode subqueryNode;
049:
050: super .printSubNodes(depth);
051:
052: for (int index = 0; index < size(); index++) {
053: subqueryNode = (SubqueryNode) elementAt(index);
054: subqueryNode.treePrint(depth + 1);
055: }
056: }
057: }
058:
059: /**
060: * Add a subquery to the list.
061: *
062: * @param subqueryNode A SubqueryNode to add to the list
063: *
064: */
065:
066: public void addSubqueryNode(SubqueryNode subqueryNode)
067: throws StandardException {
068: addElement(subqueryNode);
069: }
070:
071: /**
072: * Preprocess a SubqueryList. For now, we just preprocess each SubqueryNode
073: * in the list.
074: *
075: * @param numTables Number of tables in the DML Statement
076: * @param outerFromList FromList from outer query block
077: * @param outerSubqueryList SubqueryList from outer query block
078: * @param outerPredicateList PredicateList from outer query block
079: *
080: * @exception StandardException Thrown on error
081: */
082: public void preprocess(int numTables, FromList outerFromList,
083: SubqueryList outerSubqueryList,
084: PredicateList outerPredicateList) throws StandardException {
085: SubqueryNode subqueryNode;
086:
087: int size = size();
088: for (int index = 0; index < size; index++) {
089: subqueryNode = (SubqueryNode) elementAt(index);
090: subqueryNode.preprocess(numTables, outerFromList,
091: outerSubqueryList, outerPredicateList);
092: }
093: }
094:
095: /**
096: * Optimize the subqueries in this list.
097: *
098: * @param dataDictionary The data dictionary to use for optimization
099: * @param outerRows The optimizer's estimate of the number of
100: * times this subquery will be executed.
101: *
102: * @exception StandardException Thrown on error
103: */
104:
105: public void optimize(DataDictionary dataDictionary, double outerRows)
106: throws StandardException {
107: int size = size();
108: for (int index = 0; index < size; index++) {
109: SubqueryNode subqueryNode;
110: subqueryNode = (SubqueryNode) elementAt(index);
111: subqueryNode.optimize(dataDictionary, outerRows);
112: }
113: }
114:
115: /**
116: * Modify the access paths for all subqueries in this list.
117: *
118: * @see ResultSetNode#modifyAccessPaths
119: *
120: * @exception StandardException Thrown on error
121: */
122: public void modifyAccessPaths() throws StandardException {
123: int size = size();
124: for (int index = 0; index < size; index++) {
125: SubqueryNode subqueryNode;
126: subqueryNode = (SubqueryNode) elementAt(index);
127: subqueryNode.modifyAccessPaths();
128: }
129: }
130:
131: /**
132: * Search to see if a query references the specifed table name.
133: *
134: * @param name Table name (String) to search for.
135: * @param baseTable Whether or not name is for a base table
136: *
137: * @return true if found, else false
138: *
139: * @exception StandardException Thrown on error
140: */
141: public boolean referencesTarget(String name, boolean baseTable)
142: throws StandardException {
143: int size = size();
144: for (int index = 0; index < size; index++) {
145: SubqueryNode subqueryNode;
146:
147: subqueryNode = (SubqueryNode) elementAt(index);
148: if (subqueryNode.isMaterializable()) {
149: continue;
150: }
151:
152: if (subqueryNode.getResultSet().referencesTarget(name,
153: baseTable)) {
154: return true;
155: }
156: }
157:
158: return false;
159: }
160:
161: /**
162: * Return true if the node references SESSION schema tables (temporary or permanent)
163: *
164: * @return true if references SESSION schema tables, else false
165: *
166: * @exception StandardException Thrown on error
167: */
168: public boolean referencesSessionSchema() throws StandardException {
169: int size = size();
170: for (int index = 0; index < size; index++) {
171: SubqueryNode subqueryNode;
172:
173: subqueryNode = (SubqueryNode) elementAt(index);
174:
175: if (subqueryNode.getResultSet().referencesSessionSchema()) {
176: return true;
177: }
178: }
179:
180: return false;
181: }
182:
183: /**
184: * Set the point of attachment in all subqueries in this list.
185: *
186: * @param pointOfAttachment The point of attachment
187: *
188: * @exception StandardException Thrown on error
189: */
190: public void setPointOfAttachment(int pointOfAttachment)
191: throws StandardException {
192: int size = size();
193:
194: for (int index = 0; index < size; index++) {
195: SubqueryNode subqueryNode;
196:
197: subqueryNode = (SubqueryNode) elementAt(index);
198: subqueryNode.setPointOfAttachment(pointOfAttachment);
199: }
200: }
201:
202: /**
203: * Decrement (query block) level (0-based) for
204: * all of the tables in this subquery list.
205: * This is useful when flattening a subquery.
206: *
207: * @param decrement The amount to decrement by.
208: */
209: void decrementLevel(int decrement) {
210: int size = size();
211:
212: for (int index = 0; index < size; index++) {
213: ((SubqueryNode) elementAt(index)).getResultSet()
214: .decrementLevel(decrement);
215: }
216: }
217: }
|