KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > daffodilwoods > daffodildb > server > sql99 > dql > plan > table > PlanAbstract


1 package com.daffodilwoods.daffodildb.server.sql99.dql.plan.table;
2
3 import java.util.*;
4
5 import com.daffodilwoods.daffodildb.server.serversystem.*;
6 import com.daffodilwoods.daffodildb.server.sql99.common.*;
7 import com.daffodilwoods.daffodildb.server.sql99.dql.iterator.*;
8 import com.daffodilwoods.daffodildb.server.sql99.dql.iterator.condition.*;
9 import com.daffodilwoods.daffodildb.server.sql99.dql.plan.*;
10 import com.daffodilwoods.daffodildb.server.sql99.expression.booleanvalueexpression.*;
11 import com.daffodilwoods.daffodildb.server.sql99.utils.*;
12 import com.daffodilwoods.database.resource.*;
13 import com.daffodilwoods.database.utility.*;
14 import com.daffodilwoods.daffodildb.server.sql99.dql.iterator.table.CounterIterator;
15
16 /**
17  * It represents the abstract plan which provides the common functionality of
18  * plans. It provides the functionality of obatining cost and number of rows.
19  * <p>Title: </p>
20  * <p>Description: </p>
21  * <p>Copyright: Copyright (c) 2003</p>
22  * <p>Company: </p>
23  * @author unascribed
24  * @version 1.0
25  */

26
27 public abstract class PlanAbstract extends JoinRelationAbstract implements _TablePlan {
28
29    /**
30     * Represents the condition which will be solved at the top of this plan.
31     */

32
33    protected booleanvalueexpression remainingCondition;
34
35    /**
36     * Represents the underlying plans.
37     */

38
39    protected _TablePlan[] childPlans;
40
41    /**
42     * Represents the tables of underlying plans.
43     */

44
45    protected TableDetails[] childTableDetails;
46
47    /**
48     * abstract function provides the functionality of getting underlying plans.
49     * @return
50     * @throws DException
51     */

52
53    public abstract _TablePlan[] getChildTablePlans() throws DException;
54
55    public PlanAbstract() {
56    }
57
58    /**
59     * The following variable and methods are used for displaying the plan with
60     * proper indentation.
61     */

62
63    private static int planDepth = 1;
64    public static void inc() {
65       planDepth++;
66    }
67
68    public static void dec() {
69       planDepth--;
70    }
71
72    public static StringBuffer JavaDoc tabW(String JavaDoc s) {
73       return tab(s, true);
74    }
75
76    public static StringBuffer JavaDoc tab(String JavaDoc s) {
77       return tab(s, false);
78    }
79
80    private static StringBuffer JavaDoc tab(String JavaDoc s, boolean withoutNewLine) {
81       StringBuffer JavaDoc sb = new StringBuffer JavaDoc(s);
82       for (int i = 0; i < planDepth; i++) {
83          sb.insert(0, " ");
84       }
85       if (!withoutNewLine) {
86          sb.insert(0, "\n");
87       }
88       return sb;
89    }
90
91    /**
92     * This method is used to initialize the tables of children plans.
93     * @throws DException
94     */

95
96    protected void initializeTableDetails() throws DException {
97       try {
98          for (int i = 0; i < childPlans.length; i++) {
99             childTableDetails = GeneralPurposeStaticClass.getJointTableDetails(
100                 childTableDetails, childPlans[i].getTableDetails());
101          }
102       } catch (NullPointerException JavaDoc ex) {
103          P.showArray(childPlans);
104          throw ex;
105       }
106    }
107
108    /**
109     * This method is used to obtain the estimated rows that results from this
110     * plan. If the r1,r2,..,rn are the rows for plan1,2,..,n. Then the total
111     * number of rows are r1*r2*..*rn. And if a condition is present then those
112     * many rows are returned which are estimated after applying the condition on
113     * the resultset.
114     * @param serverSession
115     * @return
116     * @throws DException
117     */

118
119    public long getRowCount(_ServerSession serverSession) throws DException {
120       long rowCount = 1;
121       for (int i = 0; i < childPlans.length; i++) {
122          rowCount *= childPlans[i].getRowCount(serverSession);
123       }
124       return remainingCondition == null ?
125           rowCount :
126           remainingCondition.getEstimatedRows(rowCount);
127    }
128
129    /**
130     * This method is used to obtain the estimated number of rows based on the
131     * passed condition and number of rows.
132     * @param conditionArg
133     * @param estimatedRowCount
134     * @param serverSession
135     * @return
136     * @throws DException
137     */

138
139    public long getEstimatedRows(booleanvalueexpression conditionArg,
140                                 long estimatedRowCount, _ServerSession serverSession) throws DException {
141       long rowCount = conditionArg.getEstimatedRows(getRowCount(serverSession));
142       return remainingCondition == null
143           ? rowCount
144           : remainingCondition.getEstimatedRows(rowCount);
145    }
146
147    /**
148     * This method is used to add the cost of condition to the passed cost.
149     * @param cost
150     * @param serverSession
151     * @return
152     * @throws DException
153     */

154
155    protected double addCostForCondition(double cost, _ServerSession serverSession) throws DException {
156       return remainingCondition == null
157           ? cost
158           : cost + remainingCondition.getCost(getRowCount(serverSession), false);
159    }
160
161    /**
162     * This method allows user to obtain the cost of this plan. The cost includes
163     * the cost of underlyingplan as well as cost of solving condition.
164     * @param session
165     * @return
166     * @throws DException
167     */

168
169    public double getCost(_ServerSession session) throws DException {
170       double cost = 1;
171       for (int i = 0; i < childPlans.length; i++) {
172          cost *= childPlans[i].getCost(session);
173       }
174       return addCostForCondition(cost, session);
175    }
176
177    /**
178     * This method allows user to obtain the cost of this plan based on the passed
179     * condition and number of rows. The cost includes the cost of underlyingplan
180     * as well as cost of solving condition.
181     * @param session
182     * @param condition
183     * @param estimatedRows
184     * @return
185     * @throws DException
186     */

187
188    public double getCost(_ServerSession session, booleanvalueexpression condition, long estimatedRows) throws
189        DException {
190       double cost = 1;
191       for (int i = 0; i < childPlans.length; i++) {
192          cost *= childPlans[i].getCost(session, condition, estimatedRows);
193       }
194       return addCostForCondition(cost, session);
195    }
196
197    /**
198     * This method is used to remove the cover of unExecutable plans like
199     * OrderSequencePlan and TemporaryMergePlan.
200     * @return
201     * @throws DException
202     */

203
204    public _TablePlan joinMissingLink() throws DException {
205       for (int i = 0, length = childPlans.length; i < length; i++) {
206          childPlans[i] = childPlans[i].joinMissingLink();
207       }
208       if (childPlans == null) {
209          Thread.dumpStack();
210       }
211
212       return this;
213    }
214
215    /**
216     * This method is used to obtain the plans of single table .
217     * @return
218     * @throws DException
219     */

220
221    public _SingleTablePlan[] getSingleTablePlans() throws DException {
222       ArrayList aList = new ArrayList();
223       for (int i = 0, length = childPlans.length; i < length; i++) {
224          aList.addAll(Arrays.asList(childPlans[i].getSingleTablePlans()));
225       }
226       return (_SingleTablePlan[]) aList.toArray(new _SingleTablePlan[aList.size()]);
227    }
228
229    /**
230     * This method allow user to obtain the tables of all children plans.
231     * @return
232     * @throws DException
233     */

234
235    public TableDetails[] getTableDetails() throws DException {
236       if(childPlans==null){
237         return new TableDetails[]{};
238       }
239       ArrayList list = new ArrayList();
240       for (int i = 0, length = childPlans.length; i < length; i++) {
241          list.addAll(Arrays.asList(childPlans[i].getTableDetails()));
242       }
243       return (TableDetails[]) list.toArray(new TableDetails[list.size()]);
244    }
245
246    /**
247     * This method allow user to obtain the tables of all children plans. It is
248     * different from getTableDetails for the case when view is present. It
249     * returns the view as table, whereas getTableDetails returns tables involved
250     * in view.
251     * @return
252     * @throws DException
253     */

254
255    public TableDetails[] getViewTableDetails() throws DException {
256       ArrayList list = new ArrayList();
257       for (int i = 0, length = childPlans.length; i < length; i++) {
258          list.addAll(Arrays.asList(childPlans[i].getViewTableDetails()));
259       }
260       return (TableDetails[]) list.toArray(new TableDetails[list.size()]);
261    }
262
263    /**
264     * This method is used to check whether passed table belongs to this plan or
265     * not.
266     * @param tableDetails0
267     * @return
268     * @throws DException
269     */

270
271    public boolean ifExists(TableDetails tableDetails0) throws DException {
272       for (int i = 0; i < childPlans.length; i++) {
273          if (childPlans[i].ifExists(tableDetails0)) {
274             return true;
275          }
276       }
277       return false;
278    }
279
280    /**
281     * This method is used to get Filtered resultset which solves the condition
282     * sequentially.
283     * @param iterator
284     * @param serverSession
285     * @param condition
286     * @return
287     * @throws DException
288     */

289
290    protected _Iterator getNonIndexedFilteredIterator(_Iterator iterator,
291        _ServerSession serverSession, booleanvalueexpression condition) throws DException {
292      return GeneralPurposeStaticClass.getNonIndexedFilterIterator(serverSession,condition,getTableDetails(),iterator); // done by kaushik
293
}
294
295    /**
296     * This method is used to obtain the filtered resultset which solves condition
297     * sequentially. It also take care of subquery present in condition.
298     * @param iterator
299     * @param session
300     * @param condition
301     * @return
302     * @throws DException
303     */

304
305    protected _Iterator getNonIndexedFilteredIteratorWithSubQuery(_Iterator iterator,
306        _ServerSession session, booleanvalueexpression condition) throws
307        DException {
308    /* done by vibha on 22-11-2004 to support rownum() in where calsue */
309      ColumnDetails[] cd = condition.getColumnDetails();
310     ArrayList list = new ArrayList();
311
312     if(cd != null)
313     for (int i = 0; i < cd.length; i++) {
314         if (cd[i].getType() == ColumnDetails.SCALARFUNCTION &&
315             cd[i].getOriginalColumn().equalsIgnoreCase("rownum")) {
316            list.add(cd[i]);
317         }
318      }
319      if (list.size() > 0) {
320       _Reference[] refs = (_Reference[]) list.toArray(new _Reference[list.size()]);
321         iterator = new CounterIterator(iterator, refs);
322       }
323       return GeneralPurposeStaticClass.getNonIndexedFilterIterator(session, condition, getTableDetails(), iterator);
324    }
325
326    /**
327     * This method is used to check whether there is any OrderSequencePlan is
328     * present in plan hierarchy. This is required when we've to merge join
329     * relation among different plan.
330     * @return
331     * @throws DException
332     */

333
334    public boolean containsOrderSequencePlan() throws DException {
335       for (int i = 0, length = childPlans.length; i < length; i++) {
336          if (childPlans[i].containsOrderSequencePlan()) {
337             return true;
338          }
339       }
340       return false;
341    }
342
343    /**
344     * The following methods are same as corresponding counterparts getCost
345     * methods. In these method getCostWithoutOrder is called instead of getCost
346     * methods.
347     */

348
349    public double getCostWithoutOrder(_ServerSession session) throws DException {
350       double cost = 1;
351       for (int i = 0; i < childPlans.length; i++) {
352          cost *= childPlans[i].getCostWithoutOrder(session);
353       }
354       return addCostForCondition(cost, session);
355    }
356
357    public double getCostWithoutOrder(_ServerSession session, booleanvalueexpression condition, long estimatedRowCount) throws DException {
358       double cost = 1;
359       for (int i = 0; i < childPlans.length; i++) {
360          cost *= childPlans[i].getCostWithoutOrder(session, condition, estimatedRowCount);
361       }
362       return addCostForCondition(cost, session);
363    }
364
365    /**
366     * The following methods are just the place holders for some plans. These
367     * methods are never called for these plans.
368     */

369
370    public void merge(_JoinRelation joinRelation) throws DException {
371       throw new DException("DSE565",
372                            new Object JavaDoc[] {"Method merge() Not Implemented"});
373    }
374
375    protected void updateMapping(int[] mappingPositions, _TablePlan tablePlan) throws DException {
376       throw new UnsupportedOperationException JavaDoc("Method not supported");
377    }
378
379    protected void updateTablePlans(_TablePlan tablePlan, _TablePlan tablePlan1, _TablePlan tablePlan2) throws DException {
380       throw new UnsupportedOperationException JavaDoc("Method not supported");
381    }
382
383    protected void mergeJoinRelationInOrderSequencePlan(_TablePlan tablePlan1, _JoinRelation joinRelation) throws DException {
384    }
385
386 }
387
Popular Tags