KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > daffodilwoods > daffodildb > server > sql99 > dql > tableexpression > fromclause > qualifiedjoin


1 package com.daffodilwoods.daffodildb.server.sql99.dql.tableexpression.fromclause;
2
3 import java.util.*;
4
5 import com.daffodilwoods.daffodildb.server.datadictionarysystem.*;
6 import com.daffodilwoods.daffodildb.server.serversystem.*;
7 import com.daffodilwoods.daffodildb.server.sql99.common.*;
8 import com.daffodilwoods.daffodildb.server.sql99.dql.common.*;
9 import com.daffodilwoods.daffodildb.server.sql99.dql.execution.*;
10 import com.daffodilwoods.daffodildb.server.sql99.dql.listenerevents.*;
11 import com.daffodilwoods.daffodildb.server.sql99.dql.plan.*;
12 import com.daffodilwoods.daffodildb.server.sql99.dql.plan.condition.*;
13 import com.daffodilwoods.daffodildb.server.sql99.dql.plan.order.*;
14 import com.daffodilwoods.daffodildb.server.sql99.dql.plan.table.*;
15 import com.daffodilwoods.daffodildb.server.sql99.dql.queryexpression.*;
16 import com.daffodilwoods.daffodildb.server.sql99.dql.semanticchecker.*;
17 import com.daffodilwoods.daffodildb.server.sql99.expression.booleanvalueexpression.*;
18 import com.daffodilwoods.daffodildb.server.sql99.token.*;
19 import com.daffodilwoods.daffodildb.server.sql99.utils.*;
20 import com.daffodilwoods.daffodildb.utils.parser.*;
21 import com.daffodilwoods.database.resource.*;
22 import com.daffodilwoods.database.sqlinitiator.*;
23 import com.daffodilwoods.database.utility.P;
24 import com.daffodilwoods.daffodildb.server.sql99.expression.expressionprimary.subquery;
25 import com.daffodilwoods.daffodildb.server.sql99.common.ColumnDetails;
26 import com.daffodilwoods.daffodildb.server.sql99.dql.resultsetmetadata.*;
27
28 /**
29  * Qualified join represents any one of the following
30  * <br>INNER JOIN</br>
31  * <br>LEFT OUTER JOIN</br>
32  * <br>RIGHT OUTER JOIN</br>
33  * <br>FULL OUTER JOIN</br>
34  * <br> <table reference> [<join type>] JOIN < table reference> < join specification> </br>
35  * e.g A InnerJoin B on A.id = B.id ,its resultset gives those record which satisfied
36  * condtion. A leftouterjoin B on A.id = B.id ,its resultset gives all records of
37  * left table whether or not there is matching row on right table.
38  * A rightouterjoin B on a.id=b.id ,its resultset gives all records of righttable
39  * whether or not there is matching row in lefttable.
40  * A FullOuterJoin B on a.id =b.id ,its resultset gives atleaset all record of
41  * both table.
42  * It provides the functionality of obtaining plan which in turn helps in obtaining
43  * resultset.
44  * <p>Description: </p>
45  * <p>Copyright: Copyright (c) 2003</p>
46  * <p>Company: Daffodil S/W Ltd. </p>
47  * @author Select Team
48  * @version 1.0
49  */

50 public class qualifiedjoin implements com.daffodilwoods.daffodildb.utils.parser.StatementExecuter, joinedtable, Datatypes, TypeConstants, queryexpressionbody, non_joinqueryterm, tablereference {
51
52    /**
53     * joinspecification specifies the conditions on which the join is to be performed
54     */

55    public joinspecification _joinspecification0;
56
57    /**
58     * _Tablereference1 represets the table reference on the right of the join
59     */

60    public tablereference _tablereference1;
61
62    /**
63     * this is the reserved word =JOIN
64     */

65    public SRESERVEDWORD1206543922 _SRESERVEDWORD12065439222;
66
67    /**
68     * Join type specifies the type of join i.e.
69     * INNER ,
70     * LEFT OUTER
71     * RIGHT OUTER
72     * FULL OUTER JOIN
73     */

74    public jointype _Optjointype3;
75
76    /**
77     * _Tablereference4 represents the table reference on the left of the join
78     */

79    public tablereference _tablereference4;
80
81    /**
82     * List of the all table inolved in both the table references
83     */

84    private TableDetails[] tableDetails;
85
86    /**
87     * List of the all table inolved in right side table reference
88     */

89    private TableDetails[] table2;
90
91    /**
92     * List of the all table inolved in left side table reference
93     */

94    private TableDetails[] table1;
95
96    /**
97     * List of all TableDetails in left table Reference
98     * It also includes tables involved in view if present
99     */

100
101    private TableDetails[] allTableDetailsLeft;
102
103    /**
104     * List of all TableDetails in right table Reference
105     * It also includes details of tables involved in view if present
106     */

107
108    private TableDetails[] allTableDetailsRight;
109
110    /**
111     * List of all TableDetails in both the table References
112     * It also includes tables involved in view if present
113     */

114    private TableDetails[] ALLTABLEDETAILS;
115
116    /**
117     * References not solvable at current Level scope of tables involved.
118     */

119    private _Reference[] thisQueryReferences;
120
121    private _Reference[] underlyingRef;
122
123    private _Reference[] refs_Condition;
124
125    /**
126     * JoinType can be INNERJOIN, FULL_OUTER_JOIN, LEFT_OUTER_JOIN and RIGHT_OUTER_JOIN
127     */

128
129    private int joinType = -1;
130
131    public qualifiedjoin() {
132    }
133
134    public qualifiedjoin(joinspecification joinCondition,
135                         tablereference tableReference1,
136                         tablereference tableReference2, jointype joinType0,
137                         TableDetails[] table10, TableDetails[] table20, int type) throws
138        DException {
139       _joinspecification0 = joinCondition;
140       _tablereference4 = tableReference1;
141       _tablereference1 = tableReference2;
142       _Optjointype3 = joinType0;
143       _SRESERVEDWORD12065439222 = new SRESERVEDWORD1206543922();
144       _SRESERVEDWORD12065439222._SRESERVEDWORD12065439220 = " JOIN ";
145       table1 = table10;
146       table2 = table20;
147       tableDetails=GeneralPurposeStaticClass.getJointTableDetails(table1,table2);
148       joinType = type;
149       getColumnDetails();
150    }
151
152    /**
153     * <br>Adds the joinCondition of the QualifedPlan in ConditionArray</br>
154     * <br>We first ask for the Plans of the Condition , so that we can add the
155     * condition splited at lowest level</br>
156     * <br>For eg condition like A.id =1 and B.id = 2</br>
157     * <br>will be added separtely</br>
158     * <br>as A.id = 1</br>
159     * <br>B.id = 2</br>
160     * @param conditionArray
161     * @throws DException
162     */

163    private void addJoinCondition(ConditionArray conditionArray) throws DException {
164       _BVEPlan bvePlan = _joinspecification0.getBveExecutionPlan();
165       addJoinCondition(conditionArray, bvePlan);
166    }
167
168    /**
169     * Conditions Involved in the OnCondition BVE Exceution Plan are added into
170     * the condition array passed.SingleTableLevel Condition and Join Relations
171     * are also added into the condition array.
172     * @param conditionArray
173     * @param onConditionPlan
174     * @throws DException
175     */

176    private void addJoinCondition(ConditionArray conditionArray, _BVEPlan onConditionPlan) throws DException {
177       _BVESingleTablePlan[] bveSingleTablePlans = onConditionPlan.getBVESingleTablePlans();
178       if (bveSingleTablePlans != null) {
179          for (int i = 0; i < bveSingleTablePlans.length; i++) {
180             conditionArray.addCondition(bveSingleTablePlans[i].getCondition());
181          }
182       }
183       _AllTablesJoinRelation allTablesJoinRelation = onConditionPlan.getAllTableJoinRelation();
184       if (allTablesJoinRelation != null) {
185          _JoinRelation[] joinRelations = allTablesJoinRelation.getRelations();
186          for (int i = 0; i < joinRelations.length; i++) {
187             conditionArray.addCondition(joinRelations[i].getCondition());
188
189          }
190       }
191    }
192
193    /**
194     * This method is used to obtain the plan of qualified join with the help of
195     * passed condition plan and order plan. It firstly checks for Loj and Roj
196     * whether they are redundant or not. They are redundant when passed condition
197     * belongs to right side for Loj and passed condition belongs to left side
198     * for Roj. In this case type of join is converted to Inner Join.
199     * 1. If inner join is present, then array of underlying plans are returned
200     * and join condition is added into passed BvePlan as well as in ConditionArray.
201     * It is done so as to merge join condition at top level. At top level, all
202     * join conditions are present and it is decided there which join condition
203     * to use first.
204     * 2. If Loj or Roj is present, then plan of qualified bve is obtained to
205     * check which condition will be solved at single level and which will be
206     * solved at join level. If single table condition containing 'null predicate'
207     * are present on right side of Loj or left side of Roj then it will be solved
208     * at join level and also in this case qualified join will not be converted
209     * into inner join. Now the underlying plans are obtained and a resultant
210     * qualified plan is formed and returned.
211     * 3. If Foj is present, then QualifiedFullPlan is formed with the help
212     * of qualified plan representing Loj and with the help of underlying plans.
213     * This qualified plan and underlying plans are formed using the steps given
214     * above.
215     * @param serverSession
216     * @param datedFrameWork
217     * @param bvePlan0
218     * @param orderPlan0
219     * @param queryColumns0
220     * @param conditionArray
221     * @return _TablePlan[]
222     * @throws DException
223     */

224    public _TablePlan[] getTablePlans(_ServerSession serverSession, _DatedFramework datedFrameWork, _BVEPlan bvePlan0, _OrderPlan orderPlan0, _QueryColumns queryColumns0, ConditionArray conditionArray) throws DException {
225       initializeAppropriateJoinType(conditionArray, serverSession);
226       if (joinType == INNERJOIN || joinType == JOIN) {
227          return getTablePlansInSimpleJoin(serverSession, datedFrameWork, bvePlan0, orderPlan0, queryColumns0, conditionArray);
228       }
229       if (joinType == FULL_OUTER_JOIN) {
230          return getTablePLanForFOJ(serverSession, datedFrameWork, bvePlan0, orderPlan0, queryColumns0, conditionArray);
231       }
232  return getTablePlanForLOJOrROJModified(serverSession, datedFrameWork, bvePlan0, orderPlan0, queryColumns0, conditionArray);
233    }
234
235    /**
236     * <br>Returns the QualifiedFullPlan if type is FullOuterJoin</br>
237     * <br>It first checks whether the Type can be changed because of ConditionArray Passed.</br>
238     * <br>QualifiedFullPlan Created will also contain An Qualified Left Plan because most of the time FullOuter join is</br>
239     * <br>solved by the union of Qualified Left Plan and Qualified Right Plan</br>
240     * <br>If the plans length from the underLying refernces are greater than one then we create the NestedLoopJoinPlan</br>
241     * <br>for that.</br>
242     * <br>We need to create the Clone of the ConditinArray and bvePlan so as QualifiedLeftPlan can do their Optimization.</br>
243     * <br>For eg</br>
244     * <br>for A FOJ B on B.id = 1, B.id = 1 condition will be Placed on QualifiedFullPlan.</br>
245     * <br>But for QualifiedLeftPlan will be as follows QualifiedLeftPlan[STP[A] , STP[B , Condition B.id =1]]</br>
246     * <br>ie condition can be shifted to singleLevel</br>
247     * <br>ConditionArray clone is cloned beacuse we are asking for the tablePlans twice. ie</br>
248     * <br>When plans are asked from the underLyingReferences we need not to add the condition of FullOuterJoin</br>
249     * <br>[When creating QualifiedFullPlan or acting as FullJoin]</br>
250     * <br>But Condition needs to be added when plans are created for the underLyingReferences when we are creating</br>
251     * <br>the QualifiedLeftPlan[When creating QualifiedLeftPlan or acting as LOJ]</br>
252     *
253     * @param serverSession
254     * @param datedFramWork
255     * @param bvePlan0
256     * @param orderPlan0
257     * @param queryColumns0
258     * @param conditionArray
259     * @return _TablePlan
260     * @throws DException
261     */

262    private _TablePlan[] getTablePLanForFOJ(_ServerSession serverSession, _DatedFramework datedFrameWork, _BVEPlan bvePlan0, _OrderPlan orderPlan0, _QueryColumns queryColumns0, ConditionArray conditionArray) throws DException {
263      ConditionArray condArray = getClonedConditionArray(conditionArray);
264       _BVEPlan bvePlanClone = (_BVEPlan) ( (BVEAllTablePlan) bvePlan0).clone();
265       adjustNullPredicateForFullOuterJoinModified(bvePlan0);
266
267       _TablePlan tablePlans1[] = _tablereference4.getTablePlan(serverSession, datedFrameWork, bvePlan0, orderPlan0, queryColumns0, conditionArray);
268       _TablePlan tablePlans2[] = _tablereference1.getTablePlan(serverSession, datedFrameWork, bvePlan0, orderPlan0, queryColumns0, conditionArray);
269       _TablePlan tPlans[] = initializeNestedLoopJoinPlanIfAny(tablePlans1, tablePlans2);
270       joinType = LEFT_OUTER_JOIN;
271
272       _QualifiedPlan qualifiedLeftPlan = (_QualifiedPlan) getTablePlanForLOJOrROJModified(serverSession, datedFrameWork, bvePlanClone, orderPlan0, queryColumns0, condArray)[0];
273       joinType = FULL_OUTER_JOIN;
274       QualifiedFullPlan qpa=new QualifiedFullPlan(tPlans[0], tPlans[1], _joinspecification0.getWholeCondition(), qualifiedLeftPlan, serverSession);
275
276       /* Done on 1/06/2004 by Kaushik dest */
277       _QualifiedBVE qualifiedBVE= _joinspecification0.getQualifiedBVE(GeneralPurposeStaticClass.getJointTableDetails(_tablereference1.getTableDetails(serverSession, null),_tablereference4.getTableDetails(serverSession, null)));
278       booleanvalueexpression bve1=qualifiedBVE.getOnCondition();
279       if(bve1!=null){
280          underlyingRef=GeneralPurposeStaticClass.getUnderLyingReferencesOnly(GeneralPurposeStaticClass.getAllReferences(bve1.getReferences(tableDetails)),tableDetails );
281       }
282
283       /* Done by Kaushik on 13/08/2004 for solving FOJ(subquery in join condition ) problem */
284       underlyingRef=GeneralPurposeStaticClass.getJointReferences(underlyingRef,refs_Condition);
285
286       /*dend*/
287
288       if(underlyingRef!=null){
289         qpa.setUnderLyingRefernce(underlyingRef);
290       }
291       return new _TablePlan[]{qpa};
292    }
293
294    /**
295     * This method is used to adjust null predicates for full outer join. It
296     * checks whether there is any condition containing 'null predicate' is
297     * present on any underlying tables.
298     * @param bvePlan0
299     * @throws DException
300     */

301
302    private void adjustNullPredicateForFullOuterJoinModified(_BVEPlan bvePlan0) throws DException {
303       adjustNullPredicateModified(bvePlan0, table2);
304       adjustNullPredicateModified(bvePlan0, table1);
305    }
306
307    /**
308     * <br>This method will Create Either QualifiedLeft Plan if type is LeftOuterJoin</br>
309     * <br>And in case of RightOuterJoin QualifiedLeftPlan is created with special
310     * handling of exchange of tablePlans to behave it like LeftOuterJoin</br>
311     * <br>It first gets the condition which can be shifted to singleTable level</br>
312     * <br>in LOJ the we can shift the singleLevel conditon of Right Table's to</br>
313     * <br>Single Level(Only null predicates are not shifted )</br>
314     * <br>It merges the bvePlan</br>
315     * <br>It fist gets the table details according to the type of the join</br>
316     * <br>LEFTOUTERJOIN then left table details</br>
317     * <br>RIGHTOUTERJOIN then right table details</br>
318     * <br>it then gets QualifiedBVE from the joinspecification</br>
319     * <br>It then adjusts the null predicate : This is the case in the following</br>
320     * <br>query</br>
321     * <br>Select * from A LOJ B on A.id=B.id where B.id is NULL</br>
322     * <br>In this case we cannot convert the outer join into simple join</br>
323     * <br>Then we merge the single table plans of the QualifiedBVE created at this level</br>
324     * <br>and the bveplan of the level above.</br>
325     * <br>Then the type of the join is checked if it is the RIGHTOUTERJOIN then the table plans from the right table reference</br>
326     * <br>are got then the conditions of this level are joined with the conditions passed from the level then this combined array is</br>
327     * <br>passed to the gettableplan method of the left table this is done so that if a condition on the left table is present</br>
328     * <br>at the above level then the ROJ can become a simple join.</br>
329     * <br>E.g.</br>
330     * <br>select * from A Loj B on A.id=B.id where B=1;</br>
331     * <br>select * from A loj B loj C on B.id =C.id on C.id=1 ;</br>
332     * <br>In both these case the Loj can be treated as simple joins.</br>
333     * <br>Then the same process is executed for LEFTOUTERJOIN only the order of the tables is reversed</br>
334     * <br>Then the initializeplans Creates the NestedLoopJoinPlan if the underlyingRefernce gives the TablePlan Array</br>
335     * <br>Finally creats and returns the Qualified LeftPlan</br>
336     * @param serverSession
337     * @param datedFramWork
338     * @param bvePlan0
339     * @param orderPlan0
340     * @param queryColumns0
341     * @param conditionArray
342     * @return _TablePlan
343     * @throws DException
344     */

345    private _TablePlan[] getTablePlanForLOJOrROJModified(_ServerSession serverSession, _DatedFramework datedFrameWork, _BVEPlan bvePlan0, _OrderPlan orderPlan0, _QueryColumns queryColumns0, ConditionArray conditionArray) throws DException {
346      tablereference tableReferenceLeft = _tablereference4;
347       tablereference tableReferenceRight = _tablereference1;
348       if (joinType == RIGHT_OUTER_JOIN) {
349          tableReferenceLeft = _tablereference1;
350          tableReferenceRight = _tablereference4;
351       }
352       TableDetails[] table = tableReferenceRight.getTableDetails(serverSession, null);
353       _QualifiedBVE qualifiedBVE = null;
354         qualifiedBVE = _joinspecification0.getQualifiedBVE(table);
355
356       adjustNullPredicateModified(bvePlan0, table);
357       mergeSingleTableLevelCOnditionsOfQualified(qualifiedBVE, bvePlan0);
358       _TablePlan[] tablePlansLeft = tableReferenceLeft.getTablePlan(serverSession, datedFrameWork, bvePlan0, orderPlan0, queryColumns0, conditionArray);
359       addJoinCondition(conditionArray);
360       _TablePlan[] tablePlansRight = tableReferenceRight.getTablePlan(serverSession, datedFrameWork, bvePlan0, orderPlan0, queryColumns0, conditionArray);
361       _TablePlan[] newPlans = initializeNestedLoopJoinPlanIfAny(tablePlansLeft, tablePlansRight);
362
363       QualifiedLeftPlan qla=new QualifiedLeftPlan(newPlans[0], newPlans[1], qualifiedBVE.getOnCondition());
364
365       /* Done on 1/06/2004 dest*/
366       booleanvalueexpression bve=qualifiedBVE.getOnCondition();
367       if(bve!=null){
368          underlyingRef=GeneralPurposeStaticClass.getUnderLyingReferencesOnly(GeneralPurposeStaticClass.getAllReferences(bve.getReferences(tableDetails)),tableDetails );
369       }
370
371       /* Done by Kaushik on 13/08/2004 for solving FOJ(subquery in join condition ) problem */
372       underlyingRef=GeneralPurposeStaticClass.getJointReferences(underlyingRef,refs_Condition);
373
374       /*dend*/
375
376       if(underlyingRef!=null){
377         qla.setUnderLyingRefernce(underlyingRef);
378       }
379       return new _TablePlan[] {qla};
380
381    }
382
383    /**
384     * This method is used to merge single table condition of QualifiedCondition
385     * plan into passed BvePlan.
386     * @param qualifiedBVE
387     * @param bvePlan0
388     * @throws DException
389     */

390
391    private void mergeSingleTableLevelCOnditionsOfQualified(_QualifiedBVE qualifiedBVE, _BVEPlan bvePlan0) throws DException {
392       _BVESingleTablePlan bveSingleTablePlans[] = qualifiedBVE.getBVESingleTablePlans();
393       if (bveSingleTablePlans != null) {
394          for (int i = 0; i < bveSingleTablePlans.length; i++) {
395             BVEPlanMerger.mergeTablePlansWithAnd(bvePlan0, (_BVEPlan) bveSingleTablePlans[i]);
396          }
397       }
398    }
399
400    /**
401     * Extracts Null Predicate from the single Table Level Conditions and adjust
402     * it into the remaining condition level. Because this condition can't be
403     * solved at single table level.
404     * @param bvePlan0
405     * @param table
406     * @throws DException
407     */

408    private void adjustNullPredicateModified(_BVEPlan bvePlan0, TableDetails[] table) throws DException {
409       if (bvePlan0 == null) {
410          return;
411       }
412       _BVESingleTablePlan[] bvePlans = bvePlan0.getBVESingleTablePlans();
413       if (bvePlans == null) {
414          return;
415       }
416       ArrayList bveStp = new ArrayList();
417       for (int i = 0; i < bvePlans.length; i++) {
418          booleanvalueexpression condition = bvePlans[i].getCondition();
419          if (condition.isNullPredicate()) {
420             TableDetails bveTD = bvePlans[i].getTableDetails()[0];
421             if (checkIfExistinTableDetails(bveTD, table)) {
422                bvePlan0.setRemainingCondition(condition);
423             } else {
424                bveStp.add(bvePlans[i]);
425             }
426          } else {
427             bveStp.add(bvePlans[i]);
428          }
429
430       }
431       ( (BVEAllTablePlan) bvePlan0).setBVESingleTablePlans( (_BVESingleTablePlan[]) bveStp.toArray(new _BVESingleTablePlan[bveStp.size()]));
432    }
433    /**
434     * This method is used to get NestedLoopJoinplan if exist.Nested loop join plan
435     * is made if length of tableplan is greater than 1.
436     * Algo:-
437     * Firstly make tableplan of length 2.At firstposition place tableplan of
438     * left and second position contain righttableplan.if lefttableplan length is
439     * greater than one we make nestedloopjoinplan and place it at firstposition.
440     * then check for righttableplan ,if righttableplan length is greater than 1
441     * then make nestedloopjoinplan for right and place it at secondposition of
442     * resultanttableplan created.
443     *
444     * @param tablePlansLeft
445     * @param tablePlansRight
446     * @return
447     * @throws DException
448     */

449    private _TablePlan[] initializeNestedLoopJoinPlanIfAny(_TablePlan[] tablePlansLeft, _TablePlan[] tablePlansRight) throws DException {
450       _TablePlan[] newPlans = new _TablePlan[2];
451       newPlans[0] = tablePlansLeft.length == 1 ? tablePlansLeft[0] : new NestedLoopJoinPlan(tablePlansLeft);
452       newPlans[1] = tablePlansRight.length == 1 ? tablePlansRight[0] : new NestedLoopJoinPlan(tablePlansRight);
453       return newPlans;
454    }
455
456    /**
457     * This method returns concatenated array of tablePlans from two tableReferences
458     * involved. It also adds this level onCondition to the ConditionArray to
459     * check the redundancy of qualified plan(Loj/Roj).
460     * @param serverSession
461     * @param datedFrameWork
462     * @param bvePlan0
463     * @param orderPlan0
464     * @param queryColumns0
465     * @param conditionArray
466     * @return
467     * @throws DException
468     */

469    private _TablePlan[] getTablePlansInSimpleJoin(_ServerSession serverSession, _DatedFramework datedFrameWork, _BVEPlan bvePlan0, _OrderPlan orderPlan0, _QueryColumns queryColumns0, ConditionArray conditionArray) throws DException {
470       _BVEPlan onConditionPlan = _joinspecification0.getBveExecutionPlan();
471       addJoinCondition(conditionArray, onConditionPlan); // A IJ B LOJ C on B = C on A = C
472

473       /** @todo
474        * check whether onCondition type is BVEAllTablePlan or not
475        * if yes then get remaininig condition of this onCOndition and set remainig cond to null(if we have underlying ref).
476        * */

477       booleanvalueexpression bve=null;
478       if(onConditionPlan.getType()==BVEConstants.BVEALLTABLEPLAN){
479          /* Done on 1/06/2004 by Kaushik dest */
480          _QualifiedBVE qualifiedBVE= _joinspecification0.getQualifiedBVE(GeneralPurposeStaticClass.getJointTableDetails(_tablereference1.getTableDetails(serverSession, null),_tablereference4.getTableDetails(serverSession, null)));
481          booleanvalueexpression bve1=qualifiedBVE.getOnCondition();
482          if(bve1!=null){
483             underlyingRef=GeneralPurposeStaticClass.getUnderLyingReferencesOnly(GeneralPurposeStaticClass.getAllReferences(bve1.getReferences(tableDetails)),tableDetails );
484          }
485
486          /* Done by Kaushik on 13/08/2004 for solving FOJ(subquery in join condition ) problem */
487          underlyingRef=GeneralPurposeStaticClass.getJointReferences(underlyingRef,refs_Condition);
488
489          /* dend*/
490
491         if(underlyingRef!=null ){
492           bve=onConditionPlan.getRemainingCondition();
493           onConditionPlan.setRemainingCondition(null);
494         }
495       }
496
497       BVEPlanMerger.mergeTablePlansWithAnd(bvePlan0, onConditionPlan);
498       _TablePlan tablePlan1[] = _tablereference4.getTablePlans(serverSession, datedFrameWork, bvePlan0, orderPlan0, queryColumns0, conditionArray);
499       _TablePlan tablePlan2[] = _tablereference1.getTablePlans(serverSession, datedFrameWork, bvePlan0, orderPlan0, queryColumns0, conditionArray);
500
501       _TablePlan[] tp=concatTablePlans(tablePlan1, tablePlan2);
502       return underlyingRef == null ? tp : new _TablePlan[]{new NestedLoopJoinPlan(tp,bve,underlyingRef)};
503     }
504
505    /**
506     * Returns the concatenated tablePlans array of two arrays of table plan.
507     * @param tablePlan1
508     * @param tablePlan2
509     * @return
510     * @throws DException
511     */

512    private _TablePlan[] concatTablePlans(_TablePlan[] tablePlan1, _TablePlan[] tablePlan2) throws DException {
513       int tablePlan1Length = tablePlan1.length;
514       int tablePlan2Length = tablePlan2.length;
515       _TablePlan[] tPlans = new _TablePlan[tablePlan1Length + tablePlan2Length];
516       System.arraycopy(tablePlan1, 0, tPlans, 0, tablePlan1Length);
517       System.arraycopy(tablePlan2, 0, tPlans, tablePlan1Length, tablePlan2Length);
518       return tPlans;
519    }
520
521    /**
522     * Returns the clone of passed ConditionArray. It is required in case of Foj.
523     * @param conditionArray
524     * @return
525     * @throws DException
526     */

527
528    private ConditionArray getClonedConditionArray(ConditionArray conditionArray) throws DException {
529       try {
530          return (ConditionArray) conditionArray.clone();
531       } catch (CloneNotSupportedException JavaDoc ex) {
532       }
533       throw new DException("DSE0", new Object JavaDoc[] {"Clone of ConditionArray is Not Successfull"});
534    }
535
536    /**
537     * This method is similar to getTablePlans.
538     * @param serverSession
539     * @param datedFramWork
540     * @param bvePlan0
541     * @param orderPlan0
542     * @param queryColumns0
543     * @param conditionArray
544     * @return _TablePlan[]
545     * @throws DException
546     */

547    public _TablePlan[] getTablePlan(_ServerSession serverSession, _DatedFramework datedFramWork, _BVEPlan bvePlan0, _OrderPlan orderPlan0, _QueryColumns queryColumns0, ConditionArray conditionArray) throws DException {
548       return getTablePlans(serverSession, datedFramWork, bvePlan0, orderPlan0, queryColumns0, conditionArray);
549    }
550
551    /**
552     * checks is there any common tabledetails between two tableDetails passed
553     * @param source
554     * @param target
555     * @return boolean
556     * @throws DException
557     */

558
559    private boolean containsTD(TableDetails[] source, TableDetails[] target) throws DException {
560       if (source == null || target == null) {
561          return false;
562       }
563       for (int i = 0; i < source.length; i++) {
564          for (int j = 0; j < target.length; j++) {
565             if (target[j] == source[i]) {
566                return true;
567             }
568          }
569       }
570       return false;
571    }
572
573    /**
574     * Checks whether passed table is present in the TableDetails Array.
575     * @param bveTable
576     * @param table
577     * @return boolean
578     */

579    private boolean checkIfExistinTableDetails(TableDetails bveTable, TableDetails table[]) {
580       for (int i = 0; i < table.length; i++) {
581          if (bveTable == table[i]) {
582             return true;
583          }
584       }
585       return false;
586    }
587
588    /**
589     * <br>Performs the semantic checking of the qualified join condition.</br>
590     * <br>The 'on columns' specified in the join specification should follow the
591     * scope management rule. Scope management rule is avoided when columns
592     * of condition don't belong to underlying tables</br>
593     * <br>E.g.</br>
594     * <br>Select * from A loj B loj C on B.id=C.id on A.id=C.id;</br>
595     * <br>Is Ok</br>
596     * <br>However</br>
597     * <br>Select * from A loj B loj C on B.id=A.id on A.id=B.id</br>
598     * <br>Is not as in the fisrt condition the A.id is not within scope</br>
599     * <br>first the column details are got from the joinspecification</br>
600     * <br>then unknown references from the left and right tablerefereneces are got</br>
601     * <br>then the join specifications semantic checking is done,</br>
602     * <br>any unknown reference are returned</br>
603     * @param parent
604     * @return _Reference[]
605     * @throws DException
606     */

607    public _Reference[] checkSemantic(com.daffodilwoods.daffodildb.server.serversystem._ServerSession parent, ColumnDetails[] queryColumns, boolean checkUserRight) throws DException {
608      ColumnDetails[] result = _joinspecification0.getColumnDetails();
609
610      /* Done by Kaushik on 13/08/2004 for solving FOJ(subquery in join condition ) problem */
611      TableDetails td[]=getTableDetails(parent,null);
612      refs_Condition=_joinspecification0.getWholeCondition().getReferences(td);
613      refs_Condition = getReferencesRelatedtoJoin(td,parent);
614
615
616       ArrayList list = new ArrayList();
617       _Reference[] reference1 = _tablereference4.checkSemantic(parent, queryColumns, checkUserRight);
618       _Reference[] reference2 = _tablereference1.checkSemantic(parent, queryColumns, checkUserRight);
619       _Reference[] reference3 = GeneralPurposeStaticClass.getJointReferences(reference1, reference2);
620       SetColumnProperties.setTableNamesAndDatatypesOfAllColumns(parent, result, tableDetails, list, new ArrayList()); // checking for Condition columns used belonging to Table References
621
if (!list.isEmpty()) {
622          thisQueryReferences = (_Reference[]) list.toArray(new _Reference[list.size()]);
623          initializingTypeOfUnKnownReferencesAsConstant(thisQueryReferences);
624       }
625       reference3 = GeneralPurposeStaticClass.getJointReferences(reference3, _joinspecification0.checkSemantic(parent, checkUserRight));
626
627       return reference3;
628    }
629
630    /**
631     * <br>Initializing Passed UnKnownReferences as Constant</br>
632     * <br>This method initializes an unknownreference as a constant. This is the case</br>
633     * <br>when an outer query column is present and treated as a constant in the inner query.</br>
634     * <br>Select * from orders as o where o.orderid > ( select max(productid)
635     * from products where o.orderid < 1234)</br><br>In this case the column
636     * o.orderid in the inner query is treated as a constant.</br>
637     * @param unKnownReferences
638     * @throws DException
639     */

640    private void initializingTypeOfUnKnownReferencesAsConstant(_Reference[] unKnownReferences) throws DException {
641       for (int i = 0, length = unKnownReferences.length; i < length; ++i) {
642          if ( ( (ColumnDetails) unKnownReferences[i]).getType() == REFERENCE) {
643             ( (ColumnDetails) unKnownReferences[i]).setUnderLyingReference(true);
644             ( (ColumnDetails) unKnownReferences[i]).setType(CONSTANT);
645          }
646       }
647    }
648
649    /**
650     * It is never called.
651     */

652
653    public Object JavaDoc run(Object JavaDoc object) throws com.daffodilwoods.database.resource.DException {
654       throw new DException("DSE16", new Object JavaDoc[] {"run"});
655    }
656
657    /**
658     * <br>Returns the type of the plan</br>
659     * <br>e.g.</br>
660     * <br>INNERJOIN</br>
661     * <br>LEFTOUTERJOIN</br>
662     * <br>RIGHTOUTERJOIN</br>
663     * @return int
664     * @throws DException
665     */

666
667    private int getMyType() throws DException {
668       if (this.joinType == -1) {
669          String JavaDoc joinType = "";
670          if (_Optjointype3 != null) {
671             joinType = (String JavaDoc) _Optjointype3.run(null);
672          }
673          joinType += SqlKeywords.JOIN;
674          joinType = joinType.trim();
675          if (joinType.equalsIgnoreCase(SqlKeywords.INNERJOIN)) {
676             this.joinType = INNERJOIN;
677          } else if (joinType.equalsIgnoreCase(SqlKeywords.LEFTOUTERJOIN)) {
678             this.joinType = LEFT_OUTER_JOIN;
679          } else if (joinType.equalsIgnoreCase(SqlKeywords.LEFTJOIN)) {
680             this.joinType = LEFT_OUTER_JOIN;
681          } else if (joinType.equalsIgnoreCase(SqlKeywords.RIGHTOUTERJOIN)) {
682             this.joinType = RIGHT_OUTER_JOIN;
683          } else if (joinType.equalsIgnoreCase(SqlKeywords.RIGHTJOIN)) {
684             this.joinType = RIGHT_OUTER_JOIN;
685          } else if (joinType.equalsIgnoreCase(SqlKeywords.FULLOUTERJOIN)) {
686             this.joinType = FULL_OUTER_JOIN;
687          } else if (joinType.equalsIgnoreCase(SqlKeywords.FULLJOIN)) {
688             this.joinType = FULL_OUTER_JOIN;
689          } else if (joinType.equalsIgnoreCase(SqlKeywords.JOIN)) {
690             this.joinType = INNERJOIN;
691          } else {
692             this.joinType = INNERJOIN;
693          }
694
695       }
696       return this.joinType;
697    }
698
699    /**
700     * For the purpose of following methods, refer to documentation of cross join.
701     */

702
703
704
705    /**
706     * <br>Returns an array of table details</br>
707     * <br>first it gets the join type</br>
708     * <br>Then it gets the table details from the first table reference</br>
709     * <br>Then it gets the table details from the second table reference</br>
710     * <br>then adds these two arrays to get a single table details reference</br>
711     * @param serverSession
712     * @return TableDetails[]
713     * @throws DException
714     */

715    public TableDetails[] getTableDetails(com.daffodilwoods.daffodildb.server.serversystem._ServerSession serverSession, ColumnDetails[] queryColumns) throws DException {
716       if (tableDetails == null) {
717          getMyType();
718          table1 = _tablereference4.getTableDetails(serverSession, queryColumns);
719          table2 = _tablereference1.getTableDetails(serverSession, queryColumns);
720
721          TableDetails[] result = new TableDetails[table1.length + table2.length];
722          if (joinType == LEFT_OUTER_JOIN) {
723             table2[0].setHasRecord(true);
724          } else if (joinType == RIGHT_OUTER_JOIN) {
725             table1[0].setHasRecord(true);
726          }
727          int i;
728          for (i = 0; i < table1.length; i++) {
729             result[i] = table1[i];
730          }
731          for (int j = 0; j < table2.length; j++, i++) {
732             result[i] = table2[j];
733          }
734          tableDetails = result;
735       }
736       return tableDetails;
737    }
738
739    /**
740     * <br>This method gets the column details from the two table references and
741     * from the join specification</br><br>Then concatenates all the three to
742     * from a single array of column details that it returns</br>
743     * @return ColumnDetails[]
744     * @throws DException
745     */

746    public ColumnDetails[] getColumnDetails() throws DException {
747       ColumnDetails[] columnDetails1 = _tablereference4.getColumnDetails();
748       ColumnDetails[] columnDetails2 = _tablereference1.getColumnDetails();
749       columnDetails1 = SemanticChecker.addColumnDetails(columnDetails1, columnDetails2);
750       return SemanticChecker.addColumnDetails(columnDetails1, _joinspecification0.getColumnDetails());
751    }
752
753    /**
754     * Note:-For documentation of following method please refers to documentation in
755     * queryexpressionbody.
756     * @param aList
757     * @throws DException
758     */

759    public void getColumnsIncluded(ArrayList aList) throws DException {
760       _tablereference1.getColumnsIncluded(aList);
761       _tablereference4.getColumnsIncluded(aList);
762       _joinspecification0.getColumnsIncluded(aList);
763    }
764
765    public void getTablesIncluded(ArrayList aList) throws DException {
766       _tablereference1.getTablesIncluded(aList);
767       _tablereference4.getTablesIncluded(aList);
768       _joinspecification0.getTablesIncluded(aList);
769    }
770
771    /**
772     * Gets the parameter info from the table references and the join specification
773     * Then merges them to get a single arraylist which it returns
774     * @return
775     * @throws DException
776     */

777    public ParameterInfo[] getParameterInfo() throws DException {
778       ParameterInfo[] parameterInfo1 = _tablereference4.getParameterInfo();
779       ParameterInfo[] parameterInfo2 = _tablereference1.getParameterInfo();
780       ParameterInfo[] parameterInfo3 = _joinspecification0.getParameterInfo();
781       ArrayList result = new ArrayList();
782       if (parameterInfo1 != null) {
783          result.addAll(Arrays.asList(parameterInfo1));
784       }
785       if (parameterInfo2 != null) {
786          result.addAll(Arrays.asList(parameterInfo2));
787       }
788       if (parameterInfo3 != null) {
789          result.addAll(Arrays.asList(parameterInfo3));
790
791       }
792       return (ParameterInfo[]) result.toArray(new ParameterInfo[result.size()]);
793    }
794
795    /**
796     * Gets the parameters from the table references and the join specification
797     * Adds them and returns the merged arraylist
798     * @param object
799     * @return
800     * @throws DException
801     */

802    public Object JavaDoc[] getParameters(Object JavaDoc object) throws DException {
803       ArrayList aList = new ArrayList();
804       Object JavaDoc[] obj = _tablereference4.getParameters(object);
805       if (obj != null) {
806          aList.addAll(Arrays.asList(obj));
807       }
808       obj = _tablereference1.getParameters(object);
809       if (obj != null) {
810          aList.addAll(Arrays.asList(obj));
811       }
812       obj = _joinspecification0.getParameters(object);
813       if (obj != null) {
814          aList.addAll(Arrays.asList(obj));
815       }
816       int size = aList.size();
817       return size == 0 ? null : aList.toArray(new Object JavaDoc[size]);
818    }
819
820    /**
821     * This method is used to obtain those columns of join condition which avoids
822     * the scope management rule. Scope management rule is avoided when columns
823     * of condition don't belong to underlying tables.
824     * @return
825     * @throws DException
826     */

827
828    public _Reference[] getUnderlyingReferences() throws DException {
829       _Reference[] references = GeneralPurposeStaticClass.getJointReferences(
830           _tablereference4.getUnderlyingReferences(),
831           _tablereference1.getUnderlyingReferences());
832       return GeneralPurposeStaticClass.getJointReferences(thisQueryReferences,
833           references);
834    }
835
836    /**
837     * This method is used to identify the tables that are required
838     * to complete the minimum requirements of the insert,update and delete
839     * in a select query with qualified joins chain.
840     * <ol>
841     * <li> Inserts a blank row in table A for QJ i.e. A LOJ B </li>
842     * <li> Inserts a blank row in table B for QJ i.e. A ROJ B </li>
843     * <li> Inserts a blank row in table A and B both for QJ i.e. A INNER JOIN B </li>
844     * </ol>
845     */

846
847    public TableDetails[] getTablesForBlankInsert() throws DException {
848       if (joinType == LEFT_OUTER_JOIN) {
849          return _tablereference4.getTablesForBlankInsert();
850       } else if (joinType == RIGHT_OUTER_JOIN) {
851          return _tablereference1.getTablesForBlankInsert();
852       } else if (joinType == FULL_OUTER_JOIN || joinType == INNERJOIN) {
853          ArrayList arr = new ArrayList();
854          arr.addAll(Arrays.asList(_tablereference4.getTablesForBlankInsert()));
855          arr.addAll(Arrays.asList(_tablereference1.getTablesForBlankInsert()));
856          return (TableDetails[]) arr.toArray(new TableDetails[0]);
857       }
858       return null;
859    }
860
861    /**
862     * <br>In this method columnMappingHandler is passed as parameter which maintains</br>
863     * <br>a list of the tables in which insertion will be made for a insert operation</br>
864     * <br>in select query with qualified join chain. This method adds the tables if there</br>
865     * <br>exists one or more tables for insert operation according to the values specified by the user.</br>
866     * <br>Before adding the table, it checks if it already exists in the mapping.</br>
867     * <br>It checks whether the HasRecord Property is true or false. If it is true, the corresponding</br>
868     * <br>tables name is added to the mapping. otherwise table is added to the list maintained</br>
869     * <br>for deletion.</br>
870     */

871    public void setTablesForInsertion(ColumnMappingHandler columnMapping, _VariableValueOperations vv) throws com.daffodilwoods.database.resource.DException {
872       getAllTableDetails();
873       if (joinType == LEFT_OUTER_JOIN) {
874          if (insertInMapping(allTableDetailsRight, columnMapping, allTableDetailsLeft)) {
875             if (!addTablesForDeletion(columnMapping, allTableDetailsRight[0], _tablereference1)) {
876                _tablereference1.setTablesForInsertion(columnMapping, vv);
877             }
878          }
879          _tablereference4.setTablesForInsertion(columnMapping, vv); // correct it later -Rohit
880
} else if (joinType == RIGHT_OUTER_JOIN) {
881          if (insertInMapping(allTableDetailsLeft, columnMapping, allTableDetailsRight)) {
882             if (!addTablesForDeletion(columnMapping, allTableDetailsLeft[0], _tablereference4)) {
883                _tablereference4.setTablesForInsertion(columnMapping, vv);
884             }
885          }
886          _tablereference1.setTablesForInsertion(columnMapping, vv);
887       } else if (joinType == INNERJOIN || joinType == JOIN) {
888          if (!addTablesForDeletion(columnMapping, allTableDetailsRight[0], _tablereference1)) {
889             _tablereference1.setTablesForInsertion(columnMapping, vv);
890          }
891          if (!addTablesForDeletion(columnMapping, allTableDetailsLeft[0], _tablereference4)) {
892             _tablereference4.setTablesForInsertion(columnMapping, vv);
893          }
894       }
895    }
896
897    /**
898     * <br>If selected columnlist contains the column of HASRECORD type</br>
899     * <br>with value true, the matching tables are added to the list</br>
900     * <br>of table selected for insertion. Table name is set to</br>
901     * <br>columnhandler passed.</br>
902     * @param cmpHandler
903     * @param td
904     * @param tableReference
905     * @return boolean
906     * @throws DException
907     */

908
909    private boolean addTablesForDeletion(ColumnMappingHandler cmpHandler, TableDetails td, tablereference tableReference) throws DException {
910       int hasRecordValue = cmpHandler.isHasRecord_False(td);
911       boolean toRet = false;
912       if (hasRecordValue == 0) {
913          toRet = true;
914          TableDetails[] tdd = tableReference.getTablesForBlankInsert();
915          if (tdd != null) {
916             cmpHandler.addTableForDeletion(tdd);
917          }
918       }
919       return toRet;
920    }
921
922    /**
923     * Adds the table name in the tableMapping if it does not already exists,
924     * table names are got from the join specification given in the from clause.
925     * @param tDetails
926     * @param columnMapping
927     * @param tdToSendFurther
928     * @return
929     * @throws DException
930     */

931    private boolean insertInMapping(TableDetails[] tDetails, ColumnMappingHandler columnMapping, TableDetails[] tdToSendFurther) throws DException {
932       boolean inserted = false;
933       if (columnMapping.isTableInUserTableMapping(tDetails)) {
934          TableDetails[] td = ( (joincondition) _joinspecification0).getJoinCorrespondingTables(tdToSendFurther);
935          if (td != null) {
936             inserted = true;
937             for (int i = 0; i < td.length; i++) {
938                if (!columnMapping.tableAlreadyInsertedForInsert(td[i])) {
939                   columnMapping.addTableForInsertion(td[i]);
940                }
941             }
942          }
943       }
944
945       return inserted;
946    }
947
948    /**
949     * This method returns the merged bve execution plans from both the table References
950     * involved in case when they are View.Method returns Conditions involved in
951     * View when View is Optimizable, so that conditions belonging to view can be
952     * merged efficiently.
953     * @return BVEPlan
954     * @throws DException
955     */

956    public _BVEPlan getBveExecutionPlan() throws DException {
957       _BVEPlan bvePlan1 = _tablereference4.getBveExecutionPlan();
958       _BVEPlan bvePlan2 = _tablereference1.getBveExecutionPlan();
959       bvePlan1 = BVEPlanMerger.mergeTablePlansWithAnd(bvePlan1, bvePlan2);
960       return bvePlan1;
961    }
962
963    /**
964     * Returns all the tables included in the qualified-join chain.
965     * Calls the getAllTableDetails method for left and right side
966     * tablereference specified.
967     * @return TableDetails[]
968     * @throws DException
969     */

970    public TableDetails[] getAllTableDetails() throws DException {
971       if (ALLTABLEDETAILS == null) {
972          if (allTableDetailsLeft == null) {
973             allTableDetailsLeft = _tablereference4.getAllTableDetails();
974          }
975          if (allTableDetailsRight == null) {
976             allTableDetailsRight = _tablereference1.getAllTableDetails();
977          }
978          ALLTABLEDETAILS = GeneralPurposeStaticClass.getJointTableDetails(allTableDetailsLeft, allTableDetailsRight);
979       }
980       return ALLTABLEDETAILS;
981    }
982
983    /**
984     * Gets the table details from the view
985     * It gets the view table details from both the table references then gets the
986     * joint table details and returns that
987     * @return TableDetails[]
988     * @throws DException
989     */

990    public TableDetails[] getViewTableDetails() throws DException {
991       TableDetails[] td1 = _tablereference4.getViewTableDetails();
992       TableDetails[] td2 = _tablereference1.getViewTableDetails();
993       return GeneralPurposeStaticClass.getJointTableDetails(td1, td2);
994    }
995    /**
996     * Note:-For documentation of following method please referes to documentation
997     * of queryexpressionbody.
998     * @return
999     * @throws com.daffodilwoods.database.resource.DException
1000    */

1001   public QueryProperty getStrings() throws com.daffodilwoods.database.resource.DException {
1002      /**@todo: Implement this com.daffodilwoods.daffodildb.server.sql99.dql.queryexpression.queryexpressionbody method*/
1003      throw new java.lang.UnsupportedOperationException JavaDoc("Method getStrings() not yet implemented.");
1004   }
1005
1006   public _TablePlan getExecutionPlan(_ServerSession session, booleanvalueexpression bve, _DatedFramework datedCondition, _Order order, ColumnDetails[] cdsWithActualTableDetails, ConditionArray conditionArray) throws DException {
1007      /**@todo Implement this com.daffodilwoods.daffodildb.server.sql99.dql.queryexpression.queryexpressionbody method*/
1008      throw new java.lang.UnsupportedOperationException JavaDoc("Method getExecutionPlan() not yet implemented.");
1009   }
1010
1011   public void setFKeyColumnDetails(ColumnDetails[] parm1) throws com.daffodilwoods.database.resource.DException {
1012      /**@todo Implement this com.daffodilwoods.daffodildb.server.sql99.dql.queryexpression.queryexpressionbody method*/
1013      throw new java.lang.UnsupportedOperationException JavaDoc("Method setFKeyColumnDetails() not yet implemented.");
1014   }
1015
1016   public ColumnDetails[] getSelectedColumns() throws com.daffodilwoods.database.resource.DException {
1017      /**@todo Implement this com.daffodilwoods.daffodildb.server.sql99.dql.queryexpression.queryexpressionbody method*/
1018      throw new java.lang.UnsupportedOperationException JavaDoc("Method getSelectedColumns() not yet implemented.");
1019   }
1020
1021   public _TablePlan getExecutionPlan(_ServerSession parm1) throws com.daffodilwoods.database.resource.DException {
1022      /**@todo Implement this com.daffodilwoods.daffodildb.server.sql99.dql.queryexpression.queryexpressionbody method*/
1023      throw new java.lang.UnsupportedOperationException JavaDoc("Method getExecutionPlan() not yet implemented.");
1024   }
1025
1026   public _ColumnCharacteristics getColumnCharacteristics(Object JavaDoc parm1) throws com.daffodilwoods.database.resource.DException {
1027      /**@todo Implement this com.daffodilwoods.daffodildb.server.sql99.dql.queryexpression.queryexpressionbody method*/
1028      throw new java.lang.UnsupportedOperationException JavaDoc("Method getColumnCharacteristics() not yet implemented.");
1029   }
1030
1031   /**
1032    * Converts the class into a string
1033    * @return String
1034    */

1035   public String JavaDoc toString() {
1036      StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
1037      sb.append(" ");
1038      sb.append(_tablereference4);
1039      sb.append(" ");
1040      if (_Optjointype3 != null) {
1041         sb.append(_Optjointype3);
1042      }
1043      sb.append(" ");
1044      sb.append(_SRESERVEDWORD12065439222);
1045      sb.append(" ");
1046      sb.append(_tablereference1);
1047      sb.append(" ");
1048      sb.append(_joinspecification0);
1049      return sb.toString();
1050   }
1051
1052   public _Reference[] getReferences(TableDetails[] tableDetails) throws DException {
1053      throw new java.lang.UnsupportedOperationException JavaDoc("Method getReferences( TableDetails[] ) not yet implemented.");
1054   }
1055
1056   /**
1057    *
1058    * @return Object
1059    * @throws CloneNotSupportedException
1060    */

1061   public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc {
1062      qualifiedjoin tempClass = new qualifiedjoin();
1063      tempClass._joinspecification0 = (joinspecification) _joinspecification0.clone();
1064      tempClass._tablereference1 = (tablereference) _tablereference1.clone();
1065      tempClass._SRESERVEDWORD12065439222 = (SRESERVEDWORD1206543922) _SRESERVEDWORD12065439222.clone();
1066      if (_Optjointype3 != null) {
1067         tempClass._Optjointype3 = (jointype) _Optjointype3.clone();
1068      }
1069      tempClass._tablereference4 = (tablereference) _tablereference4.clone();
1070      return tempClass;
1071   }
1072
1073   public boolean isViewOptimizationPossible() throws DException {
1074      throw new UnsupportedOperationException JavaDoc("Method isViewOptimizationPossible is not supported.");
1075   }
1076
1077   /**
1078    * Get Order Mapping In Simple Join --------
1079    * In the first step the join condition is added to the condition array.
1080    * then the check for order sequence plan is called for the left and right
1081    * Table references.
1082    * Finally the getJoinOrderMapping method is called this method merges the two
1083    * Order Mpapings obtained from the left and right table references.
1084    * @param session
1085    * @param orderPlan
1086    * @param conditionArray
1087    * @param queryColumns
1088    * @param isUnderLoj
1089    * @return
1090    * @throws DException
1091    */

1092
1093   private OrderMappingWithTableRefernces[] getOrderMappingInSimpleJoin(_ServerSession session, _OrderPlan orderPlan, _BVEPlan bvePlan, ConditionArray conditionArray, _QueryColumns queryColumns, boolean isUnderLoj) throws DException {
1094      addJoinCondition(conditionArray);
1095      OrderMappingWithTableRefernces[] leftMapping = _tablereference4.checkForOrderSequencePlan(session, orderPlan, bvePlan, queryColumns, conditionArray, isUnderLoj);
1096      OrderMappingWithTableRefernces[] rightMapping = _tablereference1.checkForOrderSequencePlan(session, orderPlan, bvePlan, queryColumns, conditionArray, isUnderLoj);
1097      return getJoinOrderMappingWithTableRefernces(leftMapping, rightMapping, isUnderLoj);
1098   }
1099
1100   /**
1101    * This method checks For the Order Sequence plan in the Qualifed joins
1102    * In the case of LOJ Or Roj this function returns a single object
1103    * Of Order Mapping that contains an array of singleTableOrderPlans and a match type
1104    * In the case of Inner join however we need to check if it is under a loj or not
1105    * If it is we return a single object of the Order Mapping
1106    * Else we return an array of OrderMappings
1107    *
1108    * ALGO::::
1109    * InitializeAppropriate Join Type this method initializes the type of join.
1110    * If the join Type is INNER JOIN
1111    * it calls the getOrderMAppingInSimpleJoin method.
1112    * else it calls the getMappingInQualified method.
1113    *
1114    * @param session
1115    * @param orderPlan
1116    * @param bvePlan
1117    * @param queryColumns
1118    * @param conditionArray
1119    * @param isUnderLoj
1120    * @return
1121    * @throws DException
1122    */

1123   public OrderMappingWithTableRefernces[] checkForOrderSequencePlan(_ServerSession session, _OrderPlan orderPlan, _BVEPlan bvePlan, _QueryColumns queryColumns, ConditionArray conditionArray, boolean isUnderLoj) throws DException {
1124      initializeAppropriateJoinType(conditionArray, session);
1125      if (joinType == INNERJOIN || joinType == JOIN) {
1126         return getOrderMappingInSimpleJoin(session, orderPlan, bvePlan, conditionArray, queryColumns, isUnderLoj);
1127      }
1128      return getMappingInQualified(session, orderPlan, bvePlan, conditionArray, queryColumns, isUnderLoj);
1129   }
1130
1131   /**
1132    * Checks Order Solvability in case of LOJ/ROJ
1133    * We need to check whether single Table Level Orders are completely shifted to single Table Level or not, This is because order
1134    * of execution of qualified is fixed means, In LOJ, for each row of left table, right table all rows are scanned, if found then
1135    * right table rows are returned otherwise null is appended for corresponding.
1136    * As order of execution is fixed, so single Table Level Orders should also be in order of execution of tables,
1137    * otherwise result will not be ordered.
1138    *
1139    * Possible Cases are:
1140    * a) Select * from A LOJ B order by A1
1141    * Here we can shift Order to single Table Level, we say it is Fully Matched.
1142    * b) Select * from A LOJ B order by A1,B1
1143    * Here we can shift Orders to single Table Level, we say it is Fully Matched.
1144    * c) Select * from A LOJ B LOJ C order by A1,C1
1145    * Here we can not shift Orders to single Table Level, as Order of execution
1146    * of tables involved in qualified does not match Order of execution of
1147    * Orders Involved.
1148    * d) Select * from A LOJ B order by B1
1149    * Here we can not shift Orders to single Table Level, as Order of execution
1150    * of tables involved in qualified does not match Order of execution of
1151    * Orders Involved.
1152    * e) Select * from A LOJ View1 order by A1, V1
1153    * Here we can shift Orders to single Table Level A, but we are not sure
1154    * about the status of order on view V1, so we say it is partially matched.
1155    * As In View Order can be on table which is other than first table in
1156    * table List in from clause.
1157    * Means
1158    * View Def: create view View1 as select B.b1 as V1 from A LOJ B.
1159    * Now the order View V1 shifted to view level belongs to table B.
1160    * Algo:
1161    * 1) In the first step we check for Order Sequence Plan Possibility in qualified.
1162    * 2) From the above step we have match Type whether Order is fully solved,
1163    * Partially solved or not solved at all.
1164    * 3) If Not Solved then, then null is returned indicatiing no OrderSequencePlan can be formed.
1165    * 4) ROJ is simply reverse of LOJ so simple reverse the tableReferences.
1166    * 5) We check for left table Reference possibility of solving Order.
1167    * 6) We add this Level OnCondition in conditionArray passed, so as to convert below right hand sides Qualifieds if any
1168    * to Simple Join, the reason for this being.
1169    * Qualified Join Holds no significance, when we have condition passed to it from above level belongs to right table as output
1170    * of qualified LOJ will have appended right side nulls, and if condition passed belongs to right side then Null cannot be there
1171    * in result so qualified presence is negated and it is treated as simple join.
1172    * For Example:
1173    * Select * from A LOJ B where B.b1 = 1
1174    * Now Priority of solving where condition is above from join, so output result of this query only holds b1 = 1
1175    * result, so qualified is neglected
1176    *
1177    * Select * from A LOJ B LOJ C on B = C on A = C
1178    * now condition A = C involves columns of right side table C so B LOJ C on B = C is converted to B IJ C on B = C
1179    * 7) We check for right table Reference possibility of solving Order.
1180    * 8) we return combined mapping from two childs.
1181    */

1182   /**
1183    * This method returns the an Array Of Order Mapping in the case of qualifed join i.e. LOJ , ROJ
1184    * Algo ::::::
1185    * IsUnderLoj is initialized to true --- this is for the case where an IJ is under LOJ.
1186    * This method gets the Order Mapping from the left table reference's check for order sequence.
1187    * Then it adds the join condition to the conditionArray
1188    * Then it gets the Order Mapping from the right table reference 's check for order sequence.
1189    * Finally it calls the getOrderMappingInLoJ... method this method returns an
1190    * Object of OrderMapping which contains an array of STOPS of both the mappings
1191    * and a match value.
1192    * e.g.
1193    * select * from A Loj B order By A.id , B.id
1194    * This would return OrderMapping[[STOP -- A][STOP -- B] , FullMatched]
1195    * select * from A Loj B order by A.id
1196    * This would return OrderMapping[[STOP --A],PARTIALLYMATCHED]
1197    * select * from A Loj B order by B.id
1198    * This would return OrderMapping[null, NOTMATCHED]
1199    * @param session
1200    * @param orderPlan
1201    * @param conditionArray
1202    * @param queryColumns
1203    * @param isUnderLoj
1204    * @return
1205    * @throws DException
1206    */

1207   private OrderMappingWithTableRefernces[] getMappingInQualified(_ServerSession session, _OrderPlan orderPlan, _BVEPlan bvePlan, ConditionArray conditionArray, _QueryColumns queryColumns, boolean isUnderLoj) throws DException {
1208      int match = TableExpressionConstants.FULLYMATCHED;
1209      isUnderLoj = true;
1210      tablereference tableReferenceLeft = _tablereference4;
1211      tablereference tableReferenceRight = _tablereference1;
1212      if (joinType == RIGHT_OUTER_JOIN) {
1213         tableReferenceLeft = _tablereference1;
1214         tableReferenceRight = _tablereference4;
1215      }
1216      OrderMappingWithTableRefernces[] leftMapping = tableReferenceLeft.checkForOrderSequencePlan(session, orderPlan, bvePlan, queryColumns, conditionArray, isUnderLoj);
1217      addJoinCondition(conditionArray);
1218      OrderMappingWithTableRefernces[] rightMapping = tableReferenceRight.checkForOrderSequencePlan(session, orderPlan, bvePlan, queryColumns, conditionArray, isUnderLoj);
1219      return getOrderMappingInLOJAndROJ(leftMapping, rightMapping, match, orderPlan);
1220   }
1221
1222
1223
1224   /**
1225    * We return Order Mapping with this level tableReference.
1226    * If Left side Mapping is Null then exception is thrown, indicating Order is solvable at join Level
1227    * For Example:
1228    * Select * from A LOJ B LOJ C on B = C on A = 1 order by B1
1229    * Now B LOJ C qualified will return mapping of B1 order solvable at B table Level, but this should not be allowed as output result
1230    * will not be ordered on column B1.
1231    * @param leftMapping
1232    * @param rightMapping
1233    * @param match
1234    * @return
1235    * @throws DException
1236    */

1237   private OrderMappingWithTableRefernces[] getOrderMappingInLOJAndROJ(OrderMappingWithTableRefernces[] leftMapping, OrderMappingWithTableRefernces[] rightMapping, int match, _OrderPlan orderPlan) throws DException {
1238      OrderMappingWithTableRefernces belowOrderMapping = getOrderMappingInQualifiedJoin(leftMapping, rightMapping, orderPlan);
1239      return belowOrderMapping == null ? null : new OrderMappingWithTableRefernces[] {belowOrderMapping};
1240   }
1241
1242   /**
1243    * FULLYMATCHED Means that so far orderSequence is possible
1244    * PARTIALLYMATCHED Means that if the Any more Order Plans are present then
1245    * the Order Sequence Plan is not possible else it is
1246    * NOTMATCHED Means that no more checking is required and orderSequenceplan is not possible
1247    * This method returns an object Of OrderMapping--containing an array of
1248    * Singletableorderplan and a match value.
1249    * The following cases arise-----------------------
1250    * IF The left Mapping is null
1251    * IF The Right Mapping is also null
1252    * return null;
1253    * -- e.g. select * from ( A inner join B ) Loj C order By C.id
1254    * else--- right mapping is not null
1255    * in this case we return an OrderMapping[null,NOTMATCHED] i.e. an orderSequence is not possible.
1256    * e.g select * from A Loj B,C Order By B.id,C.id
1257    * ------ left mapping is not null
1258    * if the right mapping is null
1259    * we return an OrderMapping containing the Singleableorderplan of the left
1260    * mapping and its match value
1261    * else
1262    * we concatenate the Singletableorderplan of the left and right mapping and
1263    * caluculate a resultant match value.
1264    * and return the OrderMapping object.
1265    * @param leftMapping
1266    * @param rightMapping
1267    * @return
1268    * @throws DException
1269    */

1270   public OrderMappingWithTableRefernces getOrderMappingInQualifiedJoin(OrderMappingWithTableRefernces[] leftMapping, OrderMappingWithTableRefernces[] rightMapping, _OrderPlan orderPlan) throws DException {
1271      if (leftMapping == null) {
1272         if (rightMapping == null) {
1273            return null;
1274         } else {
1275            return new OrderMappingWithTableRefernces(null, TableExpressionConstants.NOTMATCHED, null);
1276         }
1277      }
1278      if (rightMapping == null) {
1279         return new OrderMappingWithTableRefernces(leftMapping[0].getStops(), leftMapping[0].getMatch(), leftMapping[0].getTableDetails());
1280      }
1281      int leftMatch = leftMapping[0].getMatch();
1282      int rightMatch = rightMapping[0].getMatch();
1283      int resultMatch = getResultantMatchInQualifiedJoin(leftMatch, rightMatch);
1284
1285      _SingleTableOrderPlan[] leftStops = leftMapping[0].getStops();
1286      _SingleTableOrderPlan[] rightStops = rightMapping[0].getStops();
1287      _SingleTableOrderPlan[] resultStops = getJoinedSingleTableOrderPlans(leftStops, rightStops);
1288      _SingleTableOrderPlan[] orderStops = orderPlan.getSingleTableOrderPlans();
1289      if (!isSequenceMatched(resultStops, orderStops)) {
1290         return new OrderMappingWithTableRefernces(null, TableExpressionConstants.NOTMATCHED, null);
1291      }
1292      OrderMappingWithTableRefernces result = new OrderMappingWithTableRefernces(resultStops, resultMatch, GeneralPurposeStaticClass.getJointTableDetails(leftMapping[0].getTableDetails(), rightMapping[0].getTableDetails()));
1293      return result;
1294   }
1295
1296   /**
1297    * This method checks if the table plans are in the same order as the single
1298    * table order plan
1299    * this is done to prevent cases such as:
1300    * select * from A loj B order by B.id, A.id
1301    * @param resultStops
1302    * @param orderStops
1303    * @return
1304    * @throws DException
1305    */

1306   private boolean isSequenceMatched(_SingleTableOrderPlan[] resultStops, _SingleTableOrderPlan[] orderStops) throws DException {
1307      ArrayList found = new ArrayList(5);
1308      for (int i = 0, j = 0; j < orderStops.length && i < resultStops.length; ) {
1309         if (resultStops[i].equals(orderStops[j])) {
1310            found.add(resultStops[i]);
1311            i++;
1312            j++;
1313         } else {
1314            j++;
1315         }
1316      }
1317      if (found.size() == resultStops.length) {
1318         return true;
1319      } else {
1320         return false;
1321      }
1322   }
1323   /**
1324    * This method merges two passed array of singletableorderplan.
1325    * @param leftPlans
1326    * @param rightPlans
1327    * @return
1328    * @throws DException
1329    */

1330   private _SingleTableOrderPlan[] getJoinedSingleTableOrderPlans(_SingleTableOrderPlan[] leftPlans, _SingleTableOrderPlan[] rightPlans) throws DException {
1331      _SingleTableOrderPlan[] resultStops = new _SingleTableOrderPlan[leftPlans.length + rightPlans.length];
1332      System.arraycopy(leftPlans, 0, resultStops, 0, leftPlans.length);
1333      System.arraycopy(rightPlans, 0, resultStops, leftPlans.length, rightPlans.length);
1334      return resultStops;
1335   }
1336
1337   /**
1338    * This method returns the resultant match value-------
1339    * The following cases arise ------
1340    * leftmatch == PARTIALLYMATCHED -- e.g. select * from ( A LOJ B) Loj C order by A.id,C.id
1341    * resultant match is NOTMATCHED
1342    * leftmatch == NOTMATCHED -- e.g. select * from ( A LOJ B) LOJ C order by B.id ,C.id
1343    * resultant match is NOTMATCHED
1344    * rightmatch == PARTIALLMATCHED -- e.g. select * from A LOJ ( B LOJ C ) order by A.id, B.id
1345    * resultant match is PARTIALLYMATCHED
1346    * rightmatch == NOTMATCHED -- e.g select * from A LOJ ( B LOJ C ) order By A.id , C.id
1347    * resutant match is NOTMATCHED
1348    * @param leftMatch
1349    * @param rightMatch
1350    * @return
1351    * @throws DException
1352    */

1353   private int getResultantMatchInQualifiedJoin(int leftMatch, int rightMatch) throws
1354       DException {
1355      if (leftMatch == TableExpressionConstants.PARTIALLYMATCHED) {
1356         return TableExpressionConstants.NOTMATCHED;
1357      }
1358      if (leftMatch == TableExpressionConstants.NOTMATCHED) {
1359         return TableExpressionConstants.NOTMATCHED;
1360      }
1361      if (rightMatch == TableExpressionConstants.NOTMATCHED) {
1362         return TableExpressionConstants.NOTMATCHED;
1363      }
1364      if (rightMatch == TableExpressionConstants.PARTIALLYMATCHED) {
1365         return TableExpressionConstants.PARTIALLYMATCHED;
1366      }
1367      return TableExpressionConstants.FULLYMATCHED;
1368   }
1369
1370   /**
1371    * This method returns the joint OrderMapping of the Order Mappings obtained
1372    * From The left and right Table References.
1373    * There are two case ---
1374    * 1. If the inner join is under LOJ Or ROJ
1375    * e.g. select * from ( A inner join B ) LOJ C
1376    * in such cases we need to return just one object of Order Mapping.
1377    * also we can return something if and only if both sides return something.
1378    * e.g. select * from ( A inner join B) LOJ C order by A.id , B.id
1379    * in this case we return a single object of Order Mapping containg
1380    * STOPs of A.id and B.id and a match value = FULLYMATCHED
1381    * ---------------------------------------------------------------
1382    * while in the case
1383    * e.g. select * from ( A inner join B) LOJ C order by A.id , C.id
1384    * In this case we return null.
1385    * 2. If it is not under any LOJ or ROJ then we simply concatenate the two
1386    * mappings and return the array of Order Mapping.
1387    * @param source1
1388    * @param source2
1389    * @param isUnderLoj
1390    * @return
1391    * @throws DException
1392    */

1393   private OrderMappingWithTableRefernces[]
1394       getJoinOrderMappingWithTableRefernces(OrderMappingWithTableRefernces[]
1395                                             source1,
1396                                             OrderMappingWithTableRefernces[]
1397                                             source2, boolean isUnderLoj) throws
1398       DException {
1399      ArrayList array = new ArrayList();
1400      if (isUnderLoj) {
1401         if (source1 == null || source2 == null) {
1402            return null;
1403         }
1404         for (int i = 0; i < source1.length; i++) {
1405            _SingleTableOrderPlan[] source1Stops = source1[i].getStops();
1406            array.addAll(Arrays.asList(source1Stops));
1407         }
1408         for (int j = 0; j < source2.length; j++) {
1409            _SingleTableOrderPlan[] source2Stops = source2[j].getStops();
1410            array.addAll(Arrays.asList(source2Stops));
1411         }
1412         _SingleTableOrderPlan[] resultStops = (_SingleTableOrderPlan[]) array.toArray(new _SingleTableOrderPlan[array.size()]);
1413         int resultMatch = resultantMatchOfInnerJoin(source1, source2);
1414         return new OrderMappingWithTableRefernces[] {new OrderMappingWithTableRefernces(resultStops, resultMatch, getResultantTableDetails(source1, source2))};
1415      } else {
1416         if (source1 == null) {
1417            return source2;
1418         }
1419         if (source2 == null) {
1420            return source1;
1421         }
1422         OrderMappingWithTableRefernces buffered[] = new
1423             OrderMappingWithTableRefernces[source1.length + source2.length];
1424         System.arraycopy(source1, 0, buffered, 0, source1.length);
1425         System.arraycopy(source2, 0, buffered, source1.length, source2.length);
1426         return buffered;
1427      }
1428   }
1429
1430   /**
1431    * this method is used to get all tabledetails presents in passed two mapping.
1432    * @param mapping1
1433    * @param mapping2
1434    * @return
1435    * @throws DException
1436    */

1437   private TableDetails[] getResultantTableDetails(OrderMappingWithTableRefernces[] mapping1, OrderMappingWithTableRefernces[] mapping2) throws DException {
1438      ArrayList list = new ArrayList();
1439      for (int i = 0; i < mapping1.length; i++) {
1440         list.addAll(Arrays.asList(mapping1[i].getTableDetails()));
1441      }
1442      for (int i = 0; i < mapping2.length; i++) {
1443         list.addAll(Arrays.asList(mapping2[i].getTableDetails()));
1444      }
1445      return (TableDetails[]) list.toArray(new TableDetails[list.size()]);
1446   }
1447
1448   /**
1449    * This method returns the resultant match of the two matchs passed to it.
1450    * The lowest match is the resultant match.
1451    * @param source1
1452    * @param source2
1453    * @return
1454    * @throws DException
1455    */

1456   private int resultantMatchOfInnerJoin(OrderMappingWithTableRefernces[]
1457                                         source1,
1458                                         OrderMappingWithTableRefernces[] source2) throws
1459       DException {
1460      int resultMatch = TableExpressionConstants.FULLYMATCHED;
1461      int match;
1462
1463      for (int i = 0; i < source1.length; i++) {
1464         match = source1[i].getMatch();
1465         if (match < resultMatch) {
1466            resultMatch = match;
1467         }
1468      }
1469      for (int j = 0; j < source2.length; j++) {
1470         match = source2[j].getMatch();
1471         if (match < resultMatch) {
1472            resultMatch = match;
1473         }
1474      }
1475      return resultMatch;
1476   }
1477
1478   /**
1479    * Proper Join Type is initialized with help of ConditionArray.
1480    * ConditionArray holds condition belonging to where clause, and above level
1481    * qualified joins and natural joins conditions.
1482    *
1483    * Join Type LOJ can be written as IJ, if we have condition on right side tables
1484    * other than null Predicate, as in case of null Predicate some null might
1485    * have been added in the output result after solving LOJ.
1486    *
1487    * Join Type ROJ can be written as IJ, if we have condition on left side tables
1488    * other than null Predicate, as in case of null Predicate some null might
1489    * have been added in the output result after solving ROJ.
1490    *
1491    * Join Type FOJ can be written as LOJ, if we have condition on right side
1492    * tables other than null Predicate, as in case of null Predicate some null
1493    * might have been added in the output result after solving FOJ.
1494    *
1495    * Join Type FOJ can be written as ROJ, if we have condition on left side tables
1496    * other than null Predicate, as in case of null Predicate some null might
1497    * have been added in the output result after solving FOJ.
1498    *
1499    * Join Type FOJ can be written as IJ, if we have condition on left side tables
1500    * as well as on right side tables other than null Predicate,as in case of
1501    * null Predicate some null might have been added in the output result after
1502    * solving FOJ.
1503    *
1504    * Method initializeAppropriateJoinTypeInFOJ is dued to initialize joinType
1505    * in case of FOJ.
1506    * Method containsTD(TD1[], TD2[]) checks whether Any table from TD1 is part of TD2
1507    * ConditionArray method getTableDetails(TD) returns table involved in condition leaving out null predicate in search.
1508    *
1509    * @param conditionArray, it is used to convert Qualified Join to simple Inner Join.
1510    * @param serverSession
1511    * @throws DException
1512    */

1513
1514   private void initializeAppropriateJoinType(ConditionArray conditionArray, _ServerSession serverSession) throws DException {
1515      if (joinType == INNERJOIN || joinType == JOIN) {
1516         return;
1517      }
1518      if (joinType == FULL_OUTER_JOIN) {
1519         initializeAppropriateJoinTypeInFOJ(conditionArray, serverSession);
1520         return;
1521      }
1522      TableDetails[] tableDetails = null;
1523      if (joinType == RIGHT_OUTER_JOIN) {
1524         tableDetails = table1;
1525      } else { // LOJ
1526
tableDetails = table2;
1527      }
1528      if (containsTD(conditionArray.getTableDetails(tableDetails), tableDetails)) {
1529         joinType = INNERJOIN;
1530         return;
1531      }
1532   }
1533
1534   /**
1535    * Proper JoinType is initialized in case of FOJ.
1536    * @param conditionArray
1537    * @param serverSession
1538    * @throws DException
1539    */

1540
1541   private void initializeAppropriateJoinTypeInFOJ(ConditionArray conditionArray, _ServerSession serverSession) throws DException {
1542      boolean containsTDRight = containsTD(conditionArray.getTableDetails(_tablereference1.getTableDetails(serverSession, null)), _tablereference1.getTableDetails(serverSession, null));
1543      boolean containsTDLeft = containsTD(conditionArray.getTableDetails(_tablereference4.getTableDetails(serverSession, null)), _tablereference4.getTableDetails(serverSession, null));
1544      if (containsTDRight && containsTDLeft) {
1545         joinType = INNERJOIN;
1546         return;
1547      } else if (containsTDRight) {
1548         joinType = RIGHT_OUTER_JOIN;
1549      } else if (containsTDLeft) {
1550         joinType = LEFT_OUTER_JOIN;
1551      }
1552   }
1553
1554   /**
1555    * Depending upon the type of the join, appropriate table details are returned
1556    * @return TableDetails[]
1557    * @throws DException
1558    */

1559   private TableDetails[] getAppropriateTableDetails() throws DException {
1560      if (joinType == RIGHT_OUTER_JOIN) {
1561         return GeneralPurposeStaticClass.getJointTableDetails(table2, table1);
1562      }
1563      return tableDetails;
1564   }
1565
1566   /**
1567    * Returns true if the query does not have where, orderby, groupby, having
1568    * and union clause otherwise returns false. Its invoked only from
1569    * SelectColumnIterator boolean
1570    * @throws DException
1571    */

1572
1573   public boolean isSimpleQuery(_ServerSession serverSession) throws DException {
1574     return getMyType() == INNERJOIN && isUpdatableResultsetCompliance(serverSession);
1575   }
1576
1577   final private boolean isUpdatableResultsetCompliance(_ServerSession serverSession) throws DException {
1578     ColumnDetails cds[] = _joinspecification0.getColumnDetails();
1579try{
1580    int firstConditionType = cds[0].getQuestion() ? CONSTANT : cds[0].getType();
1581    int secoundConditionType = cds[1].getQuestion() ? CONSTANT : cds[1].getType();
1582
1583    TableDetails tableDetails[] = this.getTableDetails(serverSession, cds);
1584    /* When type of conditional columns is CONSTANT
1585     * i.e select * from post inner join classes on 2=2
1586     */

1587    if (firstConditionType == CONSTANT && secoundConditionType == CONSTANT) {
1588        return false;
1589    }
1590    /*Table subquery is not supported.*/
1591    if (tableDetails[0].getColumnCharacteristics() instanceof
1592        SelectColumnCharacteristics ||
1593        tableDetails[1].getColumnCharacteristics() instanceof SelectColumnCharacteristics)
1594        return false;
1595    /* When left condition column type is REFERENCE type and right condition column is of CONSTANT type
1596     * i.e select * from post inner join classes on postid=2
1597     */

1598    else if (firstConditionType == REFERENCE &&
1599             secoundConditionType == CONSTANT) {
1600        if (P.indexOfIgnoreCase(tableDetails[0].getColumnCharacteristics().
1601                                getPrimaryKeys(), cds[0].getAppropriateColumn()) !=
1602            -1) {
1603            return true;
1604        }
1605        return false;
1606    }
1607
1608    /* When left condition column type is CONSTANT type and right condition column is of REFERENCE type
1609     * i.e select * from post inner join classes on 2= postid
1610     */

1611
1612    else if (firstConditionType == CONSTANT &&
1613             secoundConditionType == REFERENCE) {
1614
1615        if (P.indexOfIgnoreCase(tableDetails[1].getColumnCharacteristics().
1616                                getPrimaryKeys(), cds[1].getAppropriateColumn()) !=
1617            -1) {
1618            return true;
1619        }
1620        return false;
1621    }
1622    /* When both conditional column are reference type
1623     * i.e select * from post inner join classes on classid= postid
1624     */

1625
1626    else if (firstConditionType == REFERENCE &&
1627             secoundConditionType == REFERENCE) {
1628
1629        boolean primaryKeyOnFirstColumn = P.indexOfIgnoreCase(tableDetails[0].
1630                getColumnCharacteristics().getPrimaryKeys(),
1631                                          cds[0].getAppropriateColumn()) != -1;
1632        boolean primaryKeyOnSecoundColumn = P.indexOfIgnoreCase(tableDetails[1].
1633                getColumnCharacteristics().getPrimaryKeys(),
1634                                            cds[1].getAppropriateColumn()) !=
1635                                            -1;
1636        /*When no table contains primary key . */
1637        if (primaryKeyOnFirstColumn || primaryKeyOnSecoundColumn)
1638            return true;
1639        return false;
1640
1641    }
1642}catch(Exception JavaDoc ex){
1643    return false;
1644}
1645        return false;
1646   }
1647
1648   /**
1649    * <br>This method checks the join condition, it gets the join type specified by the user.</br>
1650    * <br>If it is Left outer Join or Right Outer Join then checking is made off to maintain</br>
1651    * <br>the basic functionality of Join condition. For the case of Inner Join, Checking</br>
1652    * <br>is made, both sides will be same.</br>
1653    * @param variableValueOperation
1654    * @throws DException
1655    */

1656   public void verifyValues(_VariableValueOperations variableValueOperation) throws DException {
1657      getMyType();
1658      if (joinType == LEFT_OUTER_JOIN || joinType == RIGHT_OUTER_JOIN) {
1659         ( (VariableValueOperations) variableValueOperation).setCheckingIgnored(true);
1660      } else {
1661         ( (VariableValueOperations) variableValueOperation).setCheckingIgnored(false);
1662      }
1663      _joinspecification0.verifyValues(variableValueOperation);
1664   }
1665
1666   /**
1667    * <br>This method is used to set the default values according to where clause and join condition,</br>
1668    * <br><li><li>If user gives value of one of the join specification conditional column used in join</br>
1669    * <br>condition, value is set for the unspecified conditonal column to maintain the join condition.</li></br>
1670    * <br><li>If the where clause conditional column value is not given by the user, it is set</br>
1671    * <br>as default value.</li></ol></br>
1672    * <br>This methods calls the setDefaultValues method of left and right side tablereference</br>
1673    * <br>specified in join definition and of joinspecification specified.</br>
1674    * <br>the from clause.</br>
1675    * @param variableValueOperation
1676    * @throws DException
1677    */

1678   public void setDefaultValues(_VariableValueOperations variableValueOperation) throws DException {
1679      _tablereference4.setDefaultValues(variableValueOperation);
1680      _tablereference1.setDefaultValues(variableValueOperation);
1681      _joinspecification0.setDefaultValues(variableValueOperation);
1682   }
1683
1684   public _Reference[] checkSemantic(_ServerSession session,_OrderByClause orderClause,boolean checkUserRight,boolean checkSetOperatorPresent) throws DException {
1685      throw new DException("DSE565",new Object JavaDoc[]{"checkSemantic()"});
1686   }
1687
1688   public _TablePlan[] getTablePlans(_ServerSession session, booleanvalueexpression condition, _Order order, ColumnDetails[] columnDetails, ConditionArray conditionArray) throws DException {
1689      throw new UnsupportedOperationException JavaDoc("Method getTablePlans() not supported");
1690   }
1691
1692  public boolean hasConstantSelectedColumn(booleanvalueexpression bve) throws DException{
1693    throw new UnsupportedOperationException JavaDoc("Method hasConstantSelectedColumn() not supported");
1694  }
1695
1696
1697  public _Reference[] getReferencesRelatedtoJoin(TableDetails[] td1,_ServerSession parent) throws DException{
1698     if(refs_Condition==null){
1699        return null;
1700     }
1701     ArrayList arr=new ArrayList();
1702     for (int i = 0; i < refs_Condition.length; i++) {
1703        if(refs_Condition[i].getReferenceType()==SimpleConstants.SUBQUERY){
1704           _Reference[] cd=((subquery)refs_Condition[i]).checkSemantic(parent);
1705           if(cd != null){
1706              for (int j = 0; j < cd.length; j++) {
1707                 if (cd[j].getReferenceType() != SimpleConstants.VARIABLECOLUMN) {
1708                    arr.add(cd[j]);
1709                 }
1710              }
1711           }
1712        }
1713     }
1714     return arr.isEmpty()? null : (_Reference[])arr.toArray(new _Reference[0]);
1715  }
1716
1717}
1718
Popular Tags