KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > daffodilwoods > daffodildb > server > sql99 > dql > iterator > table > IndexedFullJoinIterator


1 package com.daffodilwoods.daffodildb.server.sql99.dql.iterator.table;
2
3 import java.util.*;
4
5 import com.daffodilwoods.daffodildb.client.*;
6 import com.daffodilwoods.daffodildb.server.serversystem.*;
7 import com.daffodilwoods.daffodildb.server.sql99.common.*;
8 import com.daffodilwoods.daffodildb.server.sql99.dql.iterator.*;
9 import com.daffodilwoods.daffodildb.server.sql99.dql.listenerevents.*;
10 import com.daffodilwoods.daffodildb.server.sql99.expression.booleanvalueexpression.*;
11 import com.daffodilwoods.daffodildb.server.sql99.utils.*;
12 import com.daffodilwoods.daffodildb.utils.*;
13 import com.daffodilwoods.daffodildb.utils.field.*;
14 import com.daffodilwoods.database.resource.*;
15 import com.daffodilwoods.database.utility.P;
16
17 /**
18  * <p>Title: IndexedFullJoinIterator </p>
19  * <p>Description: This Class is responsible for retriving the records from the
20  * FULL JOIN of two tables (underlying iterators) provided that both the tables
21  * have primary/unique key on the column involved in given join codition.
22  * This iterator maintains the current position of both underlying iterators and
23  * navigates the underlying iterator(s) accordingly. </p>
24  * <p>Copyright: Copyright (c) 2004</p>
25  * <p>Company: </p>
26  * @author not attributable
27  * @version 1.0
28  */

29 public class IndexedFullJoinIterator extends AbstractQualifiedJoinIterator implements _HasRecordIterator {
30
31   /**
32    * Selected columns of the left table.
33    */

34   protected _Reference[] leftColumnReferences;
35   /**
36    * Selected columns of the right table.
37    */

38   protected _Reference[] rightColumnReferences;
39
40    protected boolean movingForward;
41    /**
42     * Variable representing the given join condition
43     */

44    private ConditionVariableValue conditionVariableValue;
45    /*Done by vibha acc to findbug .next three int are made static*/
46    private final static int LEFTNULL = 0;
47    private final static int RIGHTNULL = 1;
48    private final static int NONULL = 2;
49    private int status = -5;
50
51    /**
52     * Initializes the variable required for the working of iterator.
53     * @param leftIterator0 left table
54     * @param rightIterator0 right table
55     * @param condition0 given join condition
56     * @param leftKeyColumnInformation0 number of columns involved in group of left iterator
57     * @param rightKeyColumnInformation0 number of columns involved in group of right iterator
58     * @param hasRecordReferences0 hasRecord refererences
59     * @param session instance of connection
60     * @throws DException
61     */

62    public IndexedFullJoinIterator(_Iterator leftIterator0, _Iterator rightIterator0, booleanvalueexpression condition0, _KeyColumnInformation[] leftKeyColumnInformation0, _KeyColumnInformation[] rightKeyColumnInformation0, ColumnDetails[] hasRecordReferences0, _ServerSession session) throws DException {
63       super(leftIterator0, rightIterator0, leftKeyColumnInformation0, rightKeyColumnInformation0, hasRecordReferences0);
64       leftIterator = leftIterator0;
65       _VariableValues vValues = GeneralPurposeStaticClass.getNewVariableValues(condition0, getTableDetails(), session);
66       vValues.setIterator(this);
67       conditionVariableValue = new ConditionVariableValue(vValues, condition0);
68    }
69
70    /**
71     * This method is responsible to get the first record from the iterator.
72     * 1. First record is retrived from both of the underlying iterators.
73     * 2. Given Join Condition is evaluated for the current values got from
74     * both underlying iterator.
75     * a. If both iterator has similar set of selected column values, record
76     * is returned. A flag is set to NONULL indicating that both of the
77     * underlying iterators are pointed to the records having the same values.
78     * b. Else, A flag is set to LEFTNULL or RIGHTNULL representing right or left
79     * iterator having the smaller values of selected columns and left or right
80     * iterator having larger values of selected columns or have no data,
81     * respectively.
82     * @return false if any of the iterator has no records, true otherwise.
83     * @throws DException
84     */

85    public boolean first() throws DException {
86       movingForward = true;
87       return alignForward(leftIterator.first(), rightIterator.first());
88    }
89
90    /**
91     * This method is responsible to get the next record from the iterator.
92     * 1. Check the flag that maintaines the current underlying iterator.
93     * a. If status of iterator is NONULL, Next record is retrived from the
94     * both underlying iterators.
95     * b. Else if state is RIGHTNULL, Next record is retrived from left iterator.
96     * c. Else if state is LEFTNULL, Next record is retrived from right iterator.
97     * 2. Given Join Condition is evaluated for the current values got from
98     * both underlying iterator.
99     * a. If both iterator has similar set of selected column values, record
100     * is returned. A flag is set to NONULL indicating that both of the
101     * underlying iterators are pointed to the records having the same values.
102     * b. Else, A flag is set to LEFTNULL or RIGHTNULL representing right or left
103     * iterator having the smaller values of selected columns, respectively and
104     * left or right iterator having larger values of selected columns i.e must
105     * be returned in the further iteration.
106     * @return false if any of the iterator has no records, true otherwise.
107     * @throws DException
108     */

109    public boolean next() throws DException {
110       switch (state) {
111          case INVALIDSTATE:
112             throw new DException("DSE4116", null);
113          case BEFOREFIRST:
114             return first();
115          case AFTERLAST:
116             return false;
117          default: {
118             if (status == NONULL) {
119                return alignForward(leftIterator.next(), rightIterator.next());
120             } else if (status == LEFTNULL) {
121                return alignForward(true, rightIterator.next());
122             } else {
123                return alignForward(leftIterator.next(), true);
124             }
125          }
126       }
127    }
128
129    /**
130     * This method is responsible to get the LAST record from the iterator.
131     * 1. Last record is retrived from both of the underlying iterators.
132     * 2. Given Join Condition is evaluated for the current values got from
133     * both underlying iterator.
134     * a. If both iterator has similar set of selected column values, record
135     * is returned. A flag is set to NONULL indicating that both of the
136     * underlying iterators are pointed to the records having the same values.
137     * b. Else, A flag is set to LEFTNULL or RIGHTNULL representing right or left
138     * iterator having the larger values of selected columns and left or right
139     * iterator having smaller values of selected columns or have no data,
140     * respectively.
141     * @return false if any of the iterator has no records, true otherwise.
142     * @throws DException
143     */

144    public boolean last() throws DException {
145       movingForward = false;
146       return alignBackward(leftIterator.last(), rightIterator.last());
147    }
148
149    /**
150     * This method is responsible to get the previous record from the iterator.
151     * 1. Check the flag that maintaines the current underlying iterator.
152     * a. If status of iterator is NONULL, Previous record is retrived from the
153     * both underlying iterators.
154     * b. Else if state is RIGHTNULL, Previous record is retrived from left iterator.
155     * c. Else if state is LEFTNULL, Previous record is retrived from right iterator.
156     * 2. Given Join Condition is evaluated for the current values got from
157     * both underlying iterator.
158     * a. If both iterator has similar set of selected column values, record
159     * is returned. A flag is set to NONULL indicating that both of the
160     * underlying iterators are pointed to the records having the same values.
161     * b. Else, A flag is set to LEFTNULL or RIGHTNULL representing right or left
162     * iterator having the larger values of selected columns, respectively and
163     * left or right iterator having smaller values of selected columns i.e must
164     * be returned in the further iteration.
165     * @return false if any of the iterator has no records, true otherwise.
166     * @throws DException
167     */

168    public boolean previous() throws DException {
169       switch (state) {
170          case INVALIDSTATE:
171             throw new DException("DSE4117", null);
172          case BEFOREFIRST:
173             return false;
174          case AFTERLAST:
175             return last();
176          default: {
177             if (status == NONULL) {
178                return alignBackward(leftIterator.previous(), rightIterator.previous());
179             } else if (status == LEFTNULL) {
180                return alignBackward(true, rightIterator.previous());
181             } else {
182                return alignBackward(leftIterator.previous(), true);
183             }
184          }
185       }
186    }
187
188    /**
189     * This method is used to set the state of iterator accordingly to the
190     * state of underlying iterators during the forward direction navigation.
191     * It compares the selected column values from left and the right iterators
192     * and sets the flag accordingly that assists in further navigation.
193     * @param leftIteratorValid true if left iterator is pointed to valid
194     * record, false otherwise.
195     * @param rightIteratorValid true if right iterator is pointed to valid
196     * record, false otherwise.
197     * @return false both of the underlying iterators are at invalid status.
198     * @throws DException
199     */

200    private boolean alignForward(boolean leftIteratorValid, boolean rightIteratorValid) throws DException {
201       int cmp = compare();
202       if (leftIteratorValid && rightIteratorValid) {
203          status = cmp < 0 ? LEFTNULL : cmp > 0 ? RIGHTNULL : NONULL;
204       } else if (!rightIteratorValid) {
205          status = RIGHTNULL;
206       } else {
207          status = LEFTNULL;
208       }
209       return (state = !leftIteratorValid && !rightIteratorValid ? AFTERLAST : VALIDSTATE) != VALIDSTATE;
210    }
211
212    /**
213     * This method is used to set the state of iterator accordingly to the
214     * state of underlying iterators during the backward direction navigation.
215     * It compares the selected column values from left and the right iterators
216     * and sets the flag accordingly that assists in further navigation.
217     * @param leftIteratorValid true if left iterator is pointed to valid
218     * record, false otherwise.
219     * @param rightIteratorValid true if right iterator is pointed to valid
220     * record, false otherwise.
221     * @return false both of the underlying iterators are at invalid status.
222     * @throws DException
223     */

224    private boolean alignBackward(boolean leftIteratorValid, boolean rightIteratorValid) throws DException {
225       int cmp = compare();
226       if (leftIteratorValid && rightIteratorValid) {
227          status = cmp < 0 ? LEFTNULL : cmp > 0 ? RIGHTNULL : NONULL;
228       } else if (!rightIteratorValid) {
229          status = RIGHTNULL;
230       } else {
231          status = LEFTNULL;
232       }
233       return (state = !leftIteratorValid && !rightIteratorValid ? BEFOREFIRST : VALIDSTATE) != VALIDSTATE;
234    }
235
236    /**
237     * The following methods are used for getting values from the current record.
238     * At first, it checks the passed column,
239     * If the column corresponds to left table, checks the status -
240     * If status is LEFTNULL, NULL is returned else call is transfered to
241     * left iterator for getting the passed column value.
242     * Else If the column corresponds to left table, checks the status -
243     * If status is RIGHTNULL, NULL is returned else call is transfered to
244     * right iterator for getting the passed column value.
245     */

246
247    /**
248     * This method is responsible to execute the given join condition.
249     * @return result of execution of join condition for the current
250     * values of the join iterator.
251     * @throws DException
252     */

253    protected int compare() throws DException {
254       return conditionVariableValue.run().hashCode();
255    }
256    /**
257     * This method is used to retrieve the values of passed references.
258     * @param columnReferences reference for which values are to be retrived.
259     * Reference may be column or parameter.
260     * @return NonShared FieldBases denoting the value of References. Non Shared
261     * FieldBases are those for which BufferRange is not shared with some other
262     * FieldBase.
263     * @throws DException
264     */

265    public Object JavaDoc getColumnValues(_Reference[] columnReferences) throws DException {
266       int len = columnReferences.length;
267       Object JavaDoc[] values = new Object JavaDoc[len];
268       for (int i = 0; i < len; i++) {
269          values[i] = getColumnValues(columnReferences[i]);
270       }
271       return values;
272    }
273
274    /**
275     *
276     * METHOD IMPLEMENTATION SUBJECT TO VERIFY
277     *
278     * This method is used to retrieve the value of passed reference.
279     * It checks the table of column, if the column corresponds to LEFT table, values
280     * are retrived from left iterator, otherwise from right table.
281     * @param references reference for which value is to be retrived.
282     * Reference may be column or parameter.
283     * @return NonShared FieldBase denoting the value of Reference. Non Shared
284     * FieldBases are those for which BufferRange is not shared with some other
285     * FieldBase.
286     * @throws DException
287     */

288    public Object JavaDoc getColumnValues(_Reference references) throws DException {
289       ColumnDetails refColumnDetail = (ColumnDetails) references;
290       TableDetails tDetails = refColumnDetail.getTable();
291       int index = searchInMapping(tDetails);
292       if (index == -1)
293          return GeneralPurposeStaticClass.getColumnValuesFromQualified(leftIterator, rightIterator, references, rightNull);
294       if (index == SimpleConstants.LEFT) {
295         if(status == RIGHTNULL || status == NONULL)
296           return leftIterator.getColumnValues(references);
297         return new FieldLiteral(FieldUtility.NULLBUFFERRANGE, ( (ColumnDetails) references).getDatatype());
298       }
299       if (status == LEFTNULL || status == NONULL)
300           return rightIterator.getColumnValues(references);
301       return new FieldLiteral(FieldUtility.NULLBUFFERRANGE, ( (ColumnDetails) references).getDatatype());
302    }
303
304    /**
305     * getColumnValus was prewritten as follows:
306     */

307    public Object JavaDoc getColumnValues1(_Reference references) throws DException {
308       Object JavaDoc values;
309       ColumnDetails refColumnDetail = (ColumnDetails) references;
310       TableDetails tDetails = refColumnDetail.getTable();
311       int index = searchInMapping(tDetails);
312       if (index == -1) {
313          return GeneralPurposeStaticClass.getColumnValuesFromQualified(leftIterator, rightIterator, references, rightNull);
314       }
315       if (index == SimpleConstants.LEFT) {
316          values = leftIterator.getColumnValues(references);
317       } else if (rightNull) {
318          values = new FieldLiteral(FieldUtility.NULLBUFFERRANGE, ( (ColumnDetails) references).getDatatype());
319       } else {
320          values = rightIterator.getColumnValues(references);
321       }
322       return values;
323    }
324
325    /**
326     * This method is responsible to check whether the passed tables
327     * corresponds to left iterator or right iterator.
328     * @param tDetails table to check
329     * @return table belongs to LEFT or RIGHT iterator.
330     * @throws DException
331     */

332    private int searchInMapping(TableDetails tDetails) throws DException {
333       for (int i = 0; i < tableDetailsMapping.length; i++) {
334          if (tableDetailsMapping[i][0] == tDetails) {
335             return ( (Integer JavaDoc) tableDetailsMapping[i][1]).intValue();
336          }
337       }
338       return -1;
339    }
340
341    /**
342     * THE FOLLWING METHOD IS NOT CURRUNTLY IN USE
343     * @param keys
344     * @throws DException
345     */

346    private void moveAcctoGroupKey(Object JavaDoc[] keys) throws DException {
347       if (leftKeyCount == 0) {
348          leftIterator.first();
349       } else {
350          Object JavaDoc[] leftKeys = new Object JavaDoc[leftKeyCount];
351          System.arraycopy(keys, 0, leftKeys, 0, leftKeyCount);
352          leftIterator.move(leftKeys);
353       }
354       if (rightKeyCount == 0) {
355          rightNull = !rightIterator.first();
356       } else {
357          int rightLength = keys.length - leftKeyCount;
358          Object JavaDoc[] rightKeys = new Object JavaDoc[rightLength];
359          System.arraycopy(keys, leftKeyCount, rightKeys, 0, rightLength);
360          if (isKeyNull(rightKeys)) {
361             rightNull = true;
362          } else {
363             rightNull = false;
364             rightIterator.move(rightKeys);
365          }
366       }
367       state = 0;
368    }
369
370    /**
371     * This method is used to retrieve all the values from the join query.
372     * This method retrives all the values from the left iterator and values from
373     * right iterator and merge these values to return the valid record of join iterator.
374     * If any of the underlying iterators corresponds to NULL, null values are
375     * used rather than getting the actual values.
376     * @return NonShared FieldBases denoting the values of all columns of join query.
377     * Non Shared FieldBases are those for which BufferRange is not shared with
378     * some other FieldBase.
379     * @throws DException
380     */

381    public Object JavaDoc getColumnValues() throws DException {
382       ArrayList aList = new ArrayList();
383       Object JavaDoc[] obj = null;
384       switch (status) {
385          case NONULL: {
386             Object JavaDoc obj1 = leftIterator.getColumnValues();
387             Object JavaDoc obj2 = rightIterator.getColumnValues();
388             aList.addAll(Arrays.asList( (Object JavaDoc[]) obj1));
389             aList.addAll(Arrays.asList( (Object JavaDoc[]) obj2));
390          }
391          case RIGHTNULL: {
392             Object JavaDoc obj1 = leftIterator.getColumnValues();
393             obj =makeNullFieldLiteralArray(rightColumnCount);
394             aList.addAll(Arrays.asList( (Object JavaDoc[]) obj1));
395             aList.addAll(Arrays.asList( (Object JavaDoc[]) obj));
396          }
397          case LEFTNULL: {
398            obj=makeNullFieldLiteralArray(leftColumnCount);
399            Object JavaDoc obj2 = rightIterator.getColumnValues();
400            aList.addAll(Arrays.asList( (Object JavaDoc[]) obj));
401            aList.addAll(Arrays.asList( (Object JavaDoc[]) obj2));
402          }
403       }
404       return aList.toArray();
405    }
406
407    /**
408     * This method return the shared FieldBase for the passed reference. By Shared
409     * FieldBase we mean, BufferRange of FieldBase is shared with other FieldBase
410     * objects.
411     * @param references reference for which value is to be retrived
412     * @return shared field base correspondition to passed column reference
413     * @throws DException
414     */

415    public FieldBase field(_Reference references) throws com.daffodilwoods.database.resource.DException {
416       ColumnDetails refColumnDetail = (ColumnDetails) references;
417       TableDetails tDetails = refColumnDetail.getTable();
418       int index = searchInMapping(tDetails);
419       if (index == -1)
420          return GeneralPurposeStaticClass.getFieldFromQualified(leftIterator, rightIterator, references, rightNull);
421       if (index == SimpleConstants.LEFT) {
422         if(status == RIGHTNULL || status == NONULL)
423           return leftIterator.field(references);
424         return new FieldLiteral(FieldUtility.NULLBUFFERRANGE, ( (ColumnDetails) references).getDatatype());
425       }
426       if (status == LEFTNULL || status == NONULL)
427           return rightIterator.field(references);
428       return new FieldLiteral(FieldUtility.NULLBUFFERRANGE, ( (ColumnDetails) references).getDatatype());
429    }
430
431    /**
432     * getColumnValus was prewritten as follows:
433     */

434    public FieldBase field1(_Reference references) throws com.daffodilwoods.database.resource.DException {
435       FieldBase values;
436       ColumnDetails refColumnDetail = (ColumnDetails) references;
437       TableDetails tDetails = refColumnDetail.getTable();
438       int index = searchInMapping(tDetails);
439       if (index == -1) {
440          return GeneralPurposeStaticClass.getFieldFromQualified(leftIterator, rightIterator, references, rightNull);
441       }
442       if (index == SimpleConstants.LEFT) {
443          values = leftIterator.field(references);
444       } else if (rightNull) {
445          values = new FieldLiteral(null, ( (ColumnDetails) references).getDatatype());
446          ( (FieldLiteral) values).setBufferRange(FieldUtility.NULLBUFFERRANGE);
447       } else {
448          values = rightIterator.field(references);
449       }
450       return values;
451    }
452
453    /**
454     * This method return the shared FieldBases for the passed references. By Shared
455     * FieldBase we mean, BufferRange of FieldBase is shared with other FieldBase
456     * objects.
457     * @param columnReferences reference for which values are to be retrived
458     * @return shared field base correspondition to passed column reference
459     * @throws DException
460     */

461    public FieldBase[] fields(_Reference[] columnReferences) throws com.daffodilwoods.database.resource.DException {
462       int len = columnReferences.length;
463       FieldBase[] values = new FieldBase[len];
464       for (int i = 0; i < len; i++) {
465          values[i] = field(columnReferences[i]);
466       }
467       return values;
468    }
469
470    /**
471     * This method is used to get the lowest level iterator of the passed column.
472     * This is used for optimised retrieval of record from the maintained
473     * mapping of iterators rather than navigating in iterators hierarchy.
474     * @usage - top level resulset of select query.
475     * @param column corresponding to which, iterator has to return
476     * @return base table iterator corresponding to column passed
477     * @throws DException
478     */

479    public _Iterator getBaseIterator(ColumnDetails column) throws com.daffodilwoods.database.resource.DException {
480       return this;
481    }
482
483    /**
484     * This method is responsible to display the executionPlan of a Select Query.
485     * @return _ExecutionPlan
486     * @throws DException
487     */

488    public _ExecutionPlan getExecutionPlan() throws DException {
489       _ExecutionPlan plan = leftIterator.getExecutionPlan();
490       _ExecutionPlan plan1 = rightIterator.getExecutionPlan();
491       _ExecutionPlan cplans[] = new _ExecutionPlan[] {plan, plan1};
492       return new ExecutionPlan("IndexedFullJoinIterator", cplans, null, null, null);
493    }
494
495    /**
496     * This method is responsible to display the iterators hierarchy of a Select Query.
497     * @return ExecutionPlanForBrowser
498     * @throws DException
499     */

500    public ExecutionPlanForBrowser getExecutionPlanForBrowser() throws DException {
501       int length = 2;
502       ExecutionPlanForBrowser cplans[] = new ExecutionPlanForBrowser[length];
503       cplans[0] = leftIterator.getExecutionPlanForBrowser();
504       cplans[1] = rightIterator.getExecutionPlanForBrowser();
505       return new ExecutionPlanForBrowser("Nested Join/Left Join", "Join Iterator", cplans, "" + conditionVariableValue, null, null);
506    }
507
508    /**
509     * The following method is used to set values of unresolved references.
510     * This method sets the values of unresolved references from the passed
511     * references. If the particular refernces matched with that of involved
512     * in the bve, its value is put in the maintained mapping that is used in
513     * run method of the bve.
514     * @param parm1 references
515     * @param parm2 values of corresponding references
516     * @param parm3 NOT KNOWN
517     * @throws DException
518     */

519    public void setConditionVariableValue(_Reference[] parm1, Object JavaDoc[] parm2, int parm3) throws DException {
520      if(underlyingRef!=null){
521       parm1 = GeneralPurposeStaticClass.getJointReferences(parm1,underlyingRef);
522       parm2 = GeneralPurposeStaticClass.getJointValues(this, parm2,underlyingRef.length);
523     }
524      super.setConditionVariableValue(parm1, parm2, parm3);
525       conditionVariableValue.setVariableValues(parm1, parm2, parm3);
526    }
527
528    /**
529     * This method is used to release the resources(e.g. comparator) releated
530     * with particular iterator and condition.
531     * @throws DException
532     */

533    public void releaseResource() throws DException {
534       conditionVariableValue.releaseResource();
535       leftIterator.releaseResource();
536       rightIterator.releaseResource();
537    }
538
539    public String JavaDoc toString() {
540       try {
541          return "IndexedFullJoinIterator[" + leftIterator + "][" + rightIterator + "]" + conditionVariableValue.getCondition() + "]";
542       } catch (DException ex) {
543          return null;
544       }
545    }
546 }
547
Popular Tags