KickJava   Java API By Example, From Geeks To Geeks.

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


1 package com.daffodilwoods.daffodildb.server.sql99.dql.plan.table;
2
3 import com.daffodilwoods.daffodildb.client.*;
4 import com.daffodilwoods.daffodildb.server.serversystem.*;
5 import com.daffodilwoods.daffodildb.server.sql99.common.*;
6 import com.daffodilwoods.daffodildb.server.sql99.dql.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.iterator.table.*;
10 import com.daffodilwoods.daffodildb.server.sql99.dql.plan.*;
11 import com.daffodilwoods.daffodildb.server.sql99.expression.booleanvalueexpression.*;
12 import com.daffodilwoods.daffodildb.server.sql99.utils.*;
13 import com.daffodilwoods.database.resource.*;
14 import com.daffodilwoods.database.sqlinitiator.*;
15
16 /**
17  *
18  * <p>Title: QualifiedLeftPlan</p>
19  * <p>Description:
20  * This class represents the plan for LOJ and ROJ. Resultset of LOJ contains
21  * atleast as many rows as present in left resultset. For those rows of left
22  * resulset, whose matching rows is not present in right resultset, Null values
23  * are used for the values of right side row. Roj is antisymmetric to Loj. In
24  * ROJ underlying plans are interchanged so as to give the feel of LOJ.
25  * </p>
26  * <p>Copyright: Copyright (c) 2003</p>
27  * <p>Company: Daffodil S/W Ltd.</p>
28  * @author SelectTeam
29  * @version 1.0
30  */

31
32 public class QualifiedLeftPlan extends JoinPlanAbstract implements _QualifiedPlan {
33
34    public QualifiedLeftPlan(_TablePlan tablePlanLeft, _TablePlan tablePlanRight, booleanvalueexpression onCondition) throws DException {
35       this.tablePlanLeft = tablePlanLeft;
36       this.tablePlanRight = tablePlanRight;
37       joinCondition = onCondition;
38       childPlans = new _TablePlan[] {tablePlanLeft, tablePlanRight};
39       initializeTableDetails();
40    }
41
42    /**
43     * Return the Type OF Plan
44     * @return
45     * @throws DException
46     */

47
48    public int getType() throws DException {
49       return QUALIFIEDLEFTPLAN;
50    }
51
52    /**
53     * This method is used to compute cost of this plan.
54     * Algo:
55     * a) First we check whether the joinCondition is seekable and the condition
56     * belongs to both plans then we try the options of left seeking right
57     * otherwise condition is non seekable and will be solved as
58     * remainingCondition.
59     * b)
60     * If joinCondition is Null, case arises only in Qualified Plans when conditions
61     * are shifted to single table level. The cost will be the cartesianing cost
62     * of the two plans.(ie multiplication of the cost of two tables).
63     * c)
64     * If no. of table invloved in table Plan is more than two, condition is non
65     * seekable and we have to solve the condition above the cartesioned rows
66     * of the Plans. So add the cost of solving condition as nonIndexed
67     * condition on the cartesianing cost of the two plans.
68     *
69     *
70     * Reason for Checking the JoinCondition is as follows
71     * A LOJ B on A.a1 = B.b1 on C on A.a2 = B.b2 // to do optimization
72     * on Condition can't shifted to lower levels as will lead to wrong result
73     * For eg
74     * A B c
75     * a1 a2 b1 b2 c1
76     * 1 2 1 3 10
77     * we can't shift the condition to lower level
78     * and this case arises for Qualified Left Plan
79     *
80     * D LOJ (A IJ B on A = B IJ C on A = B) on D = 1
81     * Here we are having a twoTableJOinPlan for A and C in which conditions belongs to
82     * A and C
83     * and this case arises for TwoTableJoinPlan
84     *
85     * @return
86     * @throws DException
87     */

88
89    public double getCost(_ServerSession session) throws DException {
90       if (joinCondition == null) {
91          executionPath = TableExpressionConstants.CONITION_NULL;
92          return getCostWhenConditionNull(session);
93       }
94       int seekType = isConditionBelongsToBothPlanAndSeekable(joinCondition);
95       switch (seekType) {
96         case TypeConstants.BOTHSIDESEEKABLE:
97           executionPath = TableExpressionConstants.WHENLEFTSEEKRIGHT;
98           return getCostWhenLeftSeekRight(session);
99         case TypeConstants.NOSEEK:
100           executionPath = TableExpressionConstants.NOSEEK;
101           return getCostWhenNoSeek(session);
102         default:
103           return getCostWhenOneSideIsSeekable(session);
104       }
105    }
106
107    private double getCostWhenOneSideIsSeekable(_ServerSession session) throws DException {
108      ColumnDetails cd[] = joinCondition.getColumnDetails();
109      for (int i = 0; i < cd.length; i++) {
110        if(cd[i].getReferenceType() != TypeConstants.REFERENCE)
111          continue;
112        if(tablePlanRight.ifExists(cd[i].getTable())) {
113          executionPath = TableExpressionConstants.WHENLEFTSEEKRIGHT;
114          return getCostWhenLeftSeekRight(session);
115        }
116      }
117      executionPath = TableExpressionConstants.NOSEEK;
118      return getCostWhenNoSeek(session);
119    }
120
121    public double getCost1(_ServerSession session) throws DException {
122       if (joinCondition == null) {
123          executionPath = TableExpressionConstants.CONITION_NULL;
124          return getCostWhenConditionNull(session);
125       }
126
127       if (isConditionBelongsToBothPlanAndSeekable(joinCondition)!= TypeConstants.NOSEEK) {
128          executionPath = TableExpressionConstants.WHENLEFTSEEKRIGHT;
129          return getCostWhenLeftSeekRight(session);
130       }
131       executionPath = TableExpressionConstants.NOSEEK;
132       return getCostWhenNoSeek(session);
133    }
134
135    public String JavaDoc toString() {
136       StringBuffer JavaDoc strbuffer = new StringBuffer JavaDoc();
137       strbuffer.append("QUALIFIEDLEFTPLAN");
138       strbuffer.append("[" + tablePlanLeft.toString() + "]");
139       strbuffer.append("[" + tablePlanRight.toString() + "]");
140       if (joinCondition != null) {
141          strbuffer.append("Condition[" + joinCondition + "]");
142       } else {
143          strbuffer.append("NONE[FALSE]");
144       }
145       return strbuffer.toString();
146    }
147
148    /**
149     * It allows user to obtain the resultset when left seek right option is
150     * opted. Algo -
151     * 1. Resultset for left plan is obtained.
152     * 2. Resultset for right plan is obtained on the basis of join condition.
153     * 3. Finally a Left join resultset is formed with the help of both resultsets
154     * obtained in step1 and step2.
155     * @param session
156     * @return
157     * @throws DException
158     */

159
160    private _Iterator executeLeftSeekRightL(_ServerSession session) throws DException {
161       _Iterator iter1 = tablePlanLeft.execute(session);
162       ColumnDetails[] references = joinCondition.getColumnDetails();
163       _Iterator iter2 = tablePlanRight.execute(session, joinCondition);
164       _Iterator iter= new SemiJoinIterator(iter1, iter2, getDesiredReferences(tablePlanLeft, references), iter1.getKeyColumnInformations(), iter2.getKeyColumnInformations(), hasRecordColumns);
165       iter.setSpecificUnderlyingReferences(getUnderLyingReferencesOfJoinCondition());
166       return iter;
167    }
168
169    /**
170     * It allows user to obtain the resultset when local join conditon is not
171     * seekable. Algo -
172     * 1. Resultset for left plan is obtained.
173     * 2. Resultset for rigth plan is obtained on the basis of join condition.
174     * 3. Finally a resultset for applying condition on both resultsets
175     * obtained in step1 and step2, is formed.
176     * @param session
177     * @return
178     * @throws DException
179     */

180
181    private _Iterator executeWhenNoSeekL(_ServerSession session) throws DException {
182       _Iterator iter1 = tablePlanLeft.execute(session);
183       _Iterator iter2 = null;
184       try {
185          iter2 = tablePlanRight.execute(session);
186       } catch (UnsupportedOperationException JavaDoc ex) {
187          throw ex;
188       }
189       _Iterator niter3 = new SemiJoinFilteredIterator(iter1, iter2, joinCondition, iter1.getKeyColumnInformations(), iter2.getKeyColumnInformations(), hasRecordColumns, session);
190       niter3.setSpecificUnderlyingReferences(getUnderLyingReferencesOfJoinCondition());
191       return niter3;
192    }
193
194    /**
195     * This method is used to obtain the resultset when local join condition is
196     * null. Algo -
197     * 1. Resultset of left plan is obtained.
198     * 2. Resultset of right plan is obtained.
199     * 3. Finally a cartesian resultset on the both resultsets is formed.
200     * @param session
201     * @return
202     * @throws DException
203     */

204
205    private _Iterator executeWhenConditionNullL(_ServerSession session) throws DException {
206       _Iterator iter1 = tablePlanLeft.execute(session);
207       _Iterator iter2 = tablePlanRight.execute(session);
208       return new SemiJoinIteratorWithoutCondition(iter1, iter2, iter1.getKeyColumnInformations(), iter2.getKeyColumnInformations(), hasRecordColumns);
209    }
210
211    /**
212     * This method returns the Iterator based on the way which is set in the
213     * corresponding getCost method. It can have following ways to execute -
214     * 1. LeftSeekRight
215     * 3. NoSeek
216     * 4. Join Condition is null
217     * @param session
218     * @return
219     * @throws DException
220     */

221
222    public _Iterator execute(_ServerSession session) throws DException {
223       switch (executionPath) {
224          case TableExpressionConstants.WHENLEFTSEEKRIGHT:
225             return executeLeftSeekRightL(session);
226          case TableExpressionConstants.NOSEEK:
227             return executeWhenNoSeekL(session);
228          case TableExpressionConstants.CONITION_NULL: // ADD IN QRP
229
return executeWhenConditionNullL(session);
230       }
231       throw new DException("DSE3531", null);
232    }
233
234    /**
235     * This method is needed when condition is solvable on both plans. So filtered
236     * resultset with passed condition is formed on underlying resultset.
237     * @param session
238     * @param conditionArg
239     * @return
240     * @throws DException
241     */

242
243    private _Iterator executeWhenConditionSolvableOnBothPlans(_ServerSession session, booleanvalueexpression conditionArg) throws DException {
244       _Iterator iter= getNonIndexedFilteredIterator(execute(session), session, conditionArg);
245       iter.setSpecificUnderlyingReferences(getUnderLyingReferencesOfJoinCondition());
246       return iter;
247    }
248
249    /**
250     * This method allows user to obtain resultset when condition is solvable on
251     * left plan and local join condition is seekable. Algo -
252     * 1. Resultset of left plan is obtained with passed condition.
253     * 2. Resultset of right plan is obtained with local join condition.
254     * 3. Finally a join resultset on the both resultsets is formed.
255     * @param session
256     * @param conditionArg
257     * @return
258     * @throws DException
259     */

260
261    private _Iterator executeWhenConditionSolvableOnLeftPlanAndConditionSeekable(_ServerSession session, booleanvalueexpression conditionArg) throws DException {
262       _Iterator iter1 = tablePlanLeft.execute(session, conditionArg);
263       _Iterator iter2 = tablePlanRight.execute(session, joinCondition);
264       _Iterator iter3=new SemiJoinIterator(iter1, iter2, getDesiredReferences(tablePlanLeft, joinCondition.getColumnDetails()), iter1.getKeyColumnInformations(), iter2.getKeyColumnInformations(), hasRecordColumns);
265       iter3.setSpecificUnderlyingReferences(getUnderLyingReferencesOfJoinCondition());
266       return iter3;
267    }
268
269    /**
270     * This method is used to obtain resultset when passed condition is solvable
271     * on left plan and local join condition can't be used for seek. So a
272     * filtered resultset is formed on cartesian of underlying resultsets.
273     * @param session
274     * @param conditionArg
275     * @return
276     * @throws DException
277     */

278
279    private _Iterator executeWhenConditionSolvableOnLeftPlanAndConditionNonSeekable(_ServerSession session, booleanvalueexpression conditionArg) throws DException {
280       _Iterator iter1 = tablePlanLeft.execute(session, conditionArg);
281       _Iterator iter2 = tablePlanRight.execute(session);
282       _Iterator iter3= new SemiJoinFilteredIterator(iter1, iter2, joinCondition, iter1.getKeyColumnInformations(), iter2.getKeyColumnInformations(), hasRecordColumns, session);
283       iter3.setSpecificUnderlyingReferences(getUnderLyingReferencesOfJoinCondition());
284       return iter3;
285    }
286
287    /**
288     * This method is used to obtain resultset when passed condition is solvable
289     * on right plan and local join condition is seekable. So the resultset of
290     * right plan is seeked into resultset of left plan. Since right seek left
291     * option is opted, order will be solved on the top, Thats why a sorted
292     * resultset is formed.
293     * @param session
294     * @param conditionArg
295     * @return
296     * @throws DException
297     */

298
299    private _Iterator executeWhenConditionSolvableOnRightPlanAndConditionSeekable(_ServerSession session, booleanvalueexpression conditionArg) throws DException {
300       _Iterator iter2 = tablePlanRight.executeWithOutOrder(session, conditionArg);
301       _Order ord = getOrder();
302       _Iterator iter1 = tablePlanLeft.executeWithOutOrder(session, joinCondition);
303       _Iterator iter = new JoinIterator(iter2, iter1, getDesiredReferences(tablePlanRight, joinCondition.getColumnDetails()), hasRecordColumns);
304       iter.setSpecificUnderlyingReferences(getUnderLyingReferencesOfJoinCondition());
305       if (ord != null) {
306          iter = GeneralPurposeStaticClass.getTemporaryIndexIterator(iter, this, session, ord);
307       }
308       return iter;
309
310    }
311
312    /**
313     * This method is used to obtain resultset when passed condition is solvable
314     * on right plan and local join condition can't be used for seek. So a
315     * filtered resultset is formed on cartesian of underlying resultsets. Since
316     * condition is shifted on right plan, order will be solved on the top,
317     * Thats why a sorted resultset is also formed.
318     * @param session
319     * @param conditionArg
320     * @return
321     * @throws DException
322     */

323
324    private _Iterator executeWhenConditionSolvableOnRightPlanAndConditionNonSeekable(_ServerSession session, booleanvalueexpression conditionArg) throws DException {
325       _Iterator iter2 = tablePlanRight.executeWithOutOrder(session, conditionArg);
326       _Order ord = getOrder();
327       _Iterator iter1 = tablePlanLeft.executeWithoutOrder(session);
328       _Iterator iter = new NestedLoopJoinIterator(new _Iterator[] {iter1, iter2}
329                                                   , hasRecordColumns);
330
331       _VariableValues variableValues = new VariableValues(joinCondition.getReferences(getTableDetails()), session);
332       variableValues.setIterator(iter);
333       iter = new NonIndexedFilterIterator(iter, new ConditionVariableValue(variableValues, joinCondition));
334       iter.setSpecificUnderlyingReferences(getUnderLyingReferencesOfJoinCondition());
335
336       ord = getOrder();
337       if (ord != null) {
338          iter = GeneralPurposeStaticClass.getTemporaryIndexIterator(iter, this, session, ord);
339       }
340      return iter;
341    }
342
343    /**
344     * This method is used to obtain resultset when passed condition is solvable
345     * on left plan and local join condition is null. So a resultset for
346     * cartesian of underlying resultsets is formed.
347     * @param session
348     * @param conditionArg
349     * @return
350     * @throws DException
351     */

352
353    private _Iterator executeWhenConditionSolvableOnLeftPlanAndJoinConditionIsNull(_ServerSession session, booleanvalueexpression conditionArg) throws DException {
354       _Iterator iter1 = tablePlanLeft.execute(session, conditionArg);
355       _Iterator iter2 = tablePlanRight.execute(session);
356       return new SemiJoinIteratorWithoutCondition(iter1, iter2, iter1.getKeyColumnInformations(), iter2.getKeyColumnInformations(), hasRecordColumns);
357    }
358
359    /**
360     * This method is used to obtain resultset when passed condition is solvable
361     * on right plan and local join condition is null. So a resultset for
362     * cartesian of underlying resultsets is formed. Since
363     * condition is shifted on right plan, order will be solved on the top,
364     * Thats why a sorted resultset is also formed.
365     * @param session
366     * @param conditionArg
367     * @return
368     * @throws DException
369     */

370
371    private _Iterator executeWhenConditionSolvableOnRightPlanAndJoinConditionIsNull(_ServerSession session, booleanvalueexpression conditionArg) throws DException {
372       _Iterator iter2 = tablePlanRight.executeWithOutOrder(session, conditionArg);
373       _Iterator iter1 = tablePlanLeft.executeWithoutOrder(session);
374       iter2 = new NestedLoopJoinIterator(new _Iterator[] {iter1, iter2}
375                                          , hasRecordColumns);
376       _Order ord = getOrder();
377       if (ord != null) {
378          iter2 = GeneralPurposeStaticClass.getTemporaryIndexIterator(iter2, this, session, ord);
379       }
380       return iter2;
381    }
382
383    /**
384     * This method returns the Iterator based on the way which is set in the
385     * corresponding getCost method. It can have following ways to execute -
386     * 1. Passed join Condition belongs to both plans
387     * i. Local Join Condition is Null
388     * ii. Local Join Condition is Non Null
389     * 2. Passed join Condition belongs to left plan
390     * i. Local Join Condition is Null
391     * ii. Local Join Condition is Seekable
392     * iii. Local Join Condition is NonSeekable
393     * 3. Passed join Condition belongs to right plan - In this case passed join
394     * condition will be solved at this level.
395     * i. Local Join Condition is Null
396     * ii. Local Join Condition is Seekable
397     * iii. Local Join Condition is NonSeekable
398     * @param session
399     * @param conditionArg
400     * @return
401     * @throws DException
402     */

403
404    public _Iterator execute(_ServerSession session, booleanvalueexpression conditionArg) throws DException {
405       _Iterator iter = null;
406       VariableValues variableValues;
407       switch (searchCostCaluledFrom(conditionArg, true)) {
408          case SOLVABLE_ON_BOTH:
409             return executeWhenConditionSolvableOnBothPlans(session, conditionArg);
410          case SOLVABLE_ON_TABLEPLAN1_AND_SEEKABLE:
411             return executeWhenConditionSolvableOnLeftPlanAndConditionSeekable(session, conditionArg);
412          case SOLVABLE_ON_TABLEPLAN1_AND_NONSEEKABLE:
413             return executeWhenConditionSolvableOnLeftPlanAndConditionNonSeekable(session, conditionArg);
414          /** @todo First Err */
415          case SOLVABLE_ON_TABLEPLAN2_AND_SEEKABLE: // Done because now it will act as TwoTableJoinPlan as joinCondition in right Side
416
return executeWhenConditionSolvableOnRightPlanAndConditionSeekable(session, conditionArg);
417          case SOLVABLE_ON_TABLEPLAN2_AND_NONSEEKABLE:
418             return executeWhenConditionSolvableOnRightPlanAndConditionNonSeekable(session, conditionArg);
419          case SOLVABLE_ON_TABLEPLAN1_AND_CONDITION_NULL:
420             return executeWhenConditionSolvableOnLeftPlanAndJoinConditionIsNull(session, conditionArg);
421          /** @todo Second Err */
422          case SOLVABLE_ON_TABLEPLAN2_AND_CONDITION_NULL: //QRP
423
return executeWhenConditionSolvableOnRightPlanAndJoinConditionIsNull(session, conditionArg);
424       }
425       throw new DException("DSE3527", new Object JavaDoc[] {conditionArg.toString()});
426    }
427
428    /**
429     * This method returns the Iterator based on the way which is set in the
430     * corresponding getCost method. It doesn't take care of Order.
431     * It can have following ways to execute -
432     * 1. Passed join Condition belongs to both plans
433     * i. Local Join Condition is Null
434     * ii. Local Join Condition is Non Null
435     * 2. Passed join Condition belongs to left plan
436     * i. Local Join Condition is Null
437     * ii. Local Join Condition is Seekable
438     * iii. Local Join Condition is NonSeekable
439     * 3. Passed join Condition belongs to right plan - In this case passed join
440     * condition will be solved at this level.
441     * i. Local Join Condition is Null
442     * ii. Local Join Condition is Seekable
443     * iii. Local Join Condition is NonSeekable
444     * @param session
445     * @param conditionArg
446     * @return
447     * @throws DException
448     */

449
450    public _Iterator executeWithOutOrder(_ServerSession session, booleanvalueexpression conditionArg) throws DException {
451       switch (searchCostCaluledFrom(conditionArg, false)) {
452          case SOLVABLE_ON_BOTH:
453             return executeWithOutOrderWhenConditionSolvaleOnBothPlans(session, conditionArg);
454          case SOLVABLE_ON_TABLEPLAN1_AND_SEEKABLE:
455             return executeWithOutOrderWhenConditionSolvableOnLeftPlanAndConditionSeekable(session, conditionArg);
456          case SOLVABLE_ON_TABLEPLAN1_AND_NONSEEKABLE:
457             return executeWithOutOrderWhenConditionSolvableOnLeftPlanAndConditionNonSeekable(session, conditionArg);
458          case SOLVABLE_ON_TABLEPLAN1_AND_CONDITION_NULL:
459             return executeWithOutOrderWhenConditionSolvableOnLeftPlanAndJoinConditionIsNull(session, conditionArg);
460          case SOLVABLE_ON_TABLEPLAN2_AND_SEEKABLE:
461
462             /** @todo ERR */
463             return executeWithOutOrderWhenConditionSolvableOnRightPlanAndConditionSeekable(session, conditionArg);
464          case SOLVABLE_ON_TABLEPLAN2_AND_NONSEEKABLE:
465             return executeWithOutOrderWhenConditionSolvableOnRightPlanAndConditionNonSeekable(session, conditionArg);
466          case SOLVABLE_ON_TABLEPLAN2_AND_CONDITION_NULL: //QRP
467
return executeWithoutOrderWhenConditionSolvableOnRightPlanAndJoinConditionIsNull(session, conditionArg);
468       }
469       throw new DException("DSE3527", new Object JavaDoc[] {conditionArg.toString()});
470    }
471
472    /**
473     * This method returns the Iterator based on the way which is set in the
474     * corresponding getCost method. It don't take care of Order.
475     * It can have following ways to execute -
476     * 1. LeftSeekRight
477     * 3. NoSeek
478     * 4. Join Condition is null
479     * @param session
480     * @return
481     * @throws DException
482     */

483
484    public _Iterator executeWithoutOrder(_ServerSession session) throws DException {
485       if (executionPath == -1) {
486          getCostWithoutOrder(session);
487       }
488       switch (executionPath) {
489          case TableExpressionConstants.WHENLEFTSEEKRIGHT:
490             return executeWithoutOrderWhenLeftSeekRight(session);
491          case TableExpressionConstants.NOSEEK:
492             return executeWithoutOrderWhenNoSeek(session);
493          case TableExpressionConstants.CONITION_NULL:
494             return executeWithOutOrderWhenConditionNull(session);
495       }
496       throw new DException("DSE3531", null);
497    }
498
499    /**
500     * GetCostWithOutOrder is called when Right Iterator is seeking into Left Iterator.
501     * It is same as getCost the only differnce is that Order is not considered
502     * in the Cost Calculation as order is solved above.
503     * @return
504     * @throws DException
505     */

506
507    public double getCostWithoutOrder(_ServerSession session) throws DException {
508       if (joinCondition == null) {
509          executionPath = TableExpressionConstants.CONITION_NULL;
510          return getCostWithoutOrderWhenConditionNull(session);
511       }
512
513       if (isConditionBelongsToBothPlanAndSeekable(joinCondition)!= TypeConstants.NOSEEK) {
514          double totalCost1 = getCostWhenLeftSeekRightWithoutOrder(session);
515          executionPath = TableExpressionConstants.WHENLEFTSEEKRIGHT;
516          return totalCost1;
517       }
518       executionPath = TableExpressionConstants.NOSEEK;
519       return getCostWhenNoSeekWithoutOrder(session);
520    }
521
522    /**
523     * Returns the estimated number of rows that results from this plan.
524     * @param conditionArg
525     * @param estimatedRowCount
526     * @param serverSession
527     * @return
528     * @throws DException
529     */

530
531    public long getEstimatedRows(booleanvalueexpression conditionArg, long estimatedRowCount, _ServerSession serverSession) throws DException {
532       return conditionArg.getEstimatedRows(getRowCount(serverSession));
533    }
534
535    public String JavaDoc getVerifier() throws DException {
536       StringBuffer JavaDoc strbuffer = new StringBuffer JavaDoc();
537       inc();
538       strbuffer.append(tabW("[ QUALIFIED_LEFT_PLAN ]"));
539       strbuffer.append("\n" + tablePlanLeft.getVerifier());
540       strbuffer.append("\n" + tablePlanRight.getVerifier());
541       inc();
542       strbuffer.append(tab("Condition = [" + joinCondition + "]"));
543       dec();
544       strbuffer.append(tab("[/ QUALIFIED_LEFT_PLAN ]"));
545       dec();
546       return strbuffer.toString();
547    }
548
549    /**
550     * Returns the query plan for left/right outer join.
551     * @return
552     * @throws DException
553     */

554
555    public _QueryPlan getQueryPlan() throws DException {
556       _QueryPlan[] cplans = new _QueryPlan[2];
557       cplans[0] = tablePlanLeft.getQueryPlan();
558       cplans[1] = tablePlanRight.getQueryPlan();
559       String JavaDoc cond = joinCondition == null ? null : ("" + joinCondition);
560       String JavaDoc ord = null;
561       return new QueryPlan("QualifiedLeftPlan", cplans, cond, ord);
562    }
563
564    /**
565     * Returns this plan
566     * @return
567     * @throws DException
568     */

569
570    public _TablePlan[] getChildTablePlans() throws DException {
571       return new _TablePlan[] {this};
572    }
573
574    /**
575     * The following methods are same as corresponding counterparts execute
576     * methods. In these method executeWithoutOrder is called instead of execute
577     * methods.
578     */

579
580    private _Iterator executeWithoutOrderWhenConditionSolvableOnRightPlanAndJoinConditionIsNull(_ServerSession session, booleanvalueexpression conditionArg) throws DException {
581       _Iterator iter2 = tablePlanRight.executeWithOutOrder(session, conditionArg);
582       _Iterator iter1 = tablePlanLeft.executeWithoutOrder(session);
583       iter2 = new NestedLoopJoinIterator(new _Iterator[] {iter1, iter2}
584                                          , hasRecordColumns);
585       return iter2;
586    }
587
588    private _Iterator executeWithOutOrderWhenConditionSolvableOnRightPlanAndConditionNonSeekable(_ServerSession session, booleanvalueexpression conditionArg) throws DException {
589       _Iterator iter2 = tablePlanRight.executeWithOutOrder(session, conditionArg);
590       _Iterator iter1 = tablePlanLeft.executeWithoutOrder(session);
591       _Iterator finalIterator = new NestedLoopJoinIterator(new _Iterator[] {iter1, iter2}
592           , hasRecordColumns);
593       finalIterator = getNonIndexedFilteredIterator(finalIterator, session, joinCondition);
594       finalIterator.setSpecificUnderlyingReferences(getUnderLyingReferencesOfJoinCondition());
595       return finalIterator;
596    }
597
598    private _Iterator executeWithOutOrderWhenConditionSolvableOnRightPlanAndConditionSeekable(_ServerSession session, booleanvalueexpression conditionArg) throws DException {
599       _Iterator iter2 = tablePlanRight.executeWithOutOrder(session, conditionArg);
600       _Iterator iter1 = tablePlanLeft.executeWithOutOrder(session, joinCondition);
601       _Iterator iter3=new JoinIterator(iter2, iter1, getDesiredReferences(tablePlanRight, joinCondition.getColumnDetails()), hasRecordColumns);
602       iter3.setSpecificUnderlyingReferences(getUnderLyingReferencesOfJoinCondition());
603       return iter3;
604    }
605
606    private _Iterator executeWithOutOrderWhenConditionSolvableOnLeftPlanAndJoinConditionIsNull(_ServerSession session, booleanvalueexpression conditionArg) throws DException {
607       _Iterator iter1 = tablePlanLeft.executeWithOutOrder(session, conditionArg);
608       _Iterator iter2 = tablePlanRight.executeWithoutOrder(session);
609       return new SemiJoinIteratorWithoutCondition(iter1, iter2, iter1.getKeyColumnInformations(), iter1.getKeyColumnInformations(), hasRecordColumns);
610    }
611
612    private _Iterator executeWithOutOrderWhenConditionSolvableOnLeftPlanAndConditionNonSeekable(_ServerSession session, booleanvalueexpression conditionArg) throws DException {
613       _Iterator iter1 = tablePlanLeft.executeWithOutOrder(session, conditionArg);
614       _Iterator iter2 = tablePlanRight.executeWithoutOrder(session);
615       _Iterator iter3=new SemiJoinFilteredIterator(iter1, iter2, joinCondition, iter1.getKeyColumnInformations(), iter2.getKeyColumnInformations(), hasRecordColumns, session);
616       iter3.setSpecificUnderlyingReferences(getUnderLyingReferencesOfJoinCondition());
617       return iter3;
618    }
619
620    private _Iterator executeWithOutOrderWhenConditionSolvableOnLeftPlanAndConditionSeekable(_ServerSession session, booleanvalueexpression conditionArg) throws DException {
621       _Iterator iter1 = tablePlanLeft.executeWithOutOrder(session, conditionArg);
622       _Iterator iter2 = tablePlanRight.executeWithOutOrder(session, joinCondition);
623       _Iterator iter3= new SemiJoinIterator(iter1, iter2, getDesiredReferences(tablePlanLeft, joinCondition.getColumnDetails()), iter1.getKeyColumnInformations(), iter2.getKeyColumnInformations(), hasRecordColumns);
624       iter3.setSpecificUnderlyingReferences(getUnderLyingReferencesOfJoinCondition());
625       return iter3;
626    }
627
628    private _Iterator executeWithOutOrderWhenConditionSolvaleOnBothPlans(_ServerSession session, booleanvalueexpression conditionArg) throws DException {
629       _Iterator iter = executeWithoutOrder(session);
630       VariableValues variableValues = new VariableValues( (_Reference[]) conditionArg.getReferences(getTableDetails()), session);
631       variableValues.setIterator(iter);
632       _Iterator iter2=new NonIndexedFilterIterator(iter, new ConditionVariableValue(variableValues, conditionArg));
633       iter2.setSpecificUnderlyingReferences(getUnderLyingReferencesOfJoinCondition());
634       return iter2;
635     }
636
637    private _Iterator executeWithOutOrderWhenConditionNull(_ServerSession session) throws DException {
638       _Iterator iter1 = tablePlanLeft.executeWithoutOrder(session);
639       _Iterator iter2 = tablePlanRight.executeWithoutOrder(session);
640       return new SemiJoinIteratorWithoutCondition(iter1, iter2, iter1.getKeyColumnInformations(), iter2.getKeyColumnInformations(), hasRecordColumns);
641    }
642
643    private _Iterator executeWithoutOrderWhenNoSeek(_ServerSession session) throws DException {
644       _Iterator iter1 = tablePlanLeft.executeWithoutOrder(session);
645       _Iterator iter2 = tablePlanRight.executeWithoutOrder(session);
646       _Iterator niter3 = new SemiJoinFilteredIterator(iter1, iter2, joinCondition, iter1.getKeyColumnInformations(), iter2.getKeyColumnInformations(), hasRecordColumns, session);
647       niter3.setSpecificUnderlyingReferences(getUnderLyingReferencesOfJoinCondition());
648       return niter3;
649    }
650
651    private _Iterator executeWithoutOrderWhenLeftSeekRight(_ServerSession session) throws DException {
652       _Iterator iter1 = tablePlanLeft.executeWithoutOrder(session);
653       ColumnDetails[] references = joinCondition.getColumnDetails();
654       _Iterator iter2 = tablePlanRight.executeWithOutOrder(session, joinCondition);
655       _Iterator iter3=new SemiJoinIterator(iter1, iter2, getDesiredReferences(tablePlanLeft, references), iter1.getKeyColumnInformations(), iter2.getKeyColumnInformations(), hasRecordColumns);
656       iter3.setSpecificUnderlyingReferences(getUnderLyingReferencesOfJoinCondition());
657       return iter3;
658    }
659
660
661
662
663 } //end of class
664
Popular Tags