KickJava   Java API By Example, From Geeks To Geeks.

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


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.daffodildb.utils.byteconverter.CCzufDpowfsufs;
16 import com.daffodilwoods.database.utility.P;
17
18 /**
19  * <p>Title: SemiJoinFilteredIterator </p>
20  * <p>Description: This Class is responsible for retrieving LEFT OUTER JOIN AND
21  * RIGHT OUTER JOIN results with NON- SEEKABLE Join Condition. Left outer Joins
22  * result in all the records from the left table. For the records, for which,
23  * the condition evaluates to true, values are retrieved from right iterator,
24  * otherwise NULL is appended for the values of right table. Here, the join
25  * condition could not be shifted to any of the underlying iterator and will be
26  * evaluated for each iteration. The Iterator maintains the basic propertiy of
27  * any Iterator, however it also possesses couple of other attributes required.
28  * Right Outer Joins are just antisymmetric to the Left Outer Join in nature.
29  * A variable rightNull is used to indicate whether values corresponding to the
30  * right Iterator be valid value from the right Iterators or NULL 'll be appended
31  * instead. Initially it is set to false.
32  * </p>
33  * <p>Copyright: Copyright (c) 2004</p>
34  * <p>Company: </p>
35  * @author not attributable
36  * @version 1.0
37  */

38 public class SemiJoinFilteredIterator extends AbstractQualifiedJoinIterator implements _HasRecordIterator {
39   /**
40    * Variable representing the LOJ non-seekable condition.
41    */

42   protected ConditionVariableValue conditionVariableValue;
43   /**
44    * Variable representing the count of key Columns from right iterator.
45    */

46   protected int rightCount = -1; //to be Used for Counting the keyColumnInformation from leftIterator.
47

48   /**
49    * Initializes the variables for proper retrieval of LOJ records.
50    * @param leftIterator0 left iterator
51    * @param rightIterator0 right iterator
52    * @param condition given LOJ condition
53    * @param leftKeyColumnInformation0 number of columns involved in group of left iterator
54    * @param rightKeyColumnInformation0 number of columns involved in group of right iterator
55    * @param hasRecordReferences0 hasRecord refererences
56    * @param session serversession to create instance of _VariableValues
57    * @throws DException
58    */

59   public SemiJoinFilteredIterator(_Iterator leftIterator0, _Iterator rightIterator0, booleanvalueexpression condition, _KeyColumnInformation[] leftKeyColumnInformation0, _KeyColumnInformation[] rightKeyColumnInformation0, ColumnDetails[] hasRecordReferences0, _ServerSession session) throws DException {
60       super(leftIterator0, rightIterator0, leftKeyColumnInformation0, rightKeyColumnInformation0, hasRecordReferences0);
61       leftIterator = leftIterator0;
62       _VariableValues vValues = GeneralPurposeStaticClass.getNewVariableValues(condition, getTableDetails(), session);
63       vValues.setIterator(this);
64       conditionVariableValue = new ConditionVariableValue(vValues, condition);
65       rightCount = rightKeyColumnInformation0.length;
66    }
67
68    /**
69     * This method is responsible to retrieve the first record from iterator.
70     * 1. If there are no records in left iterator, return false.
71     * 2. First record is retrieved from right iterator, if there are no records
72     * in right iterator, goto step 5, else goto step 3.
73     * 3. Given Join Condition is verified on records got from both underlying
74     * iterators. If condition evaluates to true, variable rightNull is set to
75     * false indicating that for current record from left iterator, there exists
76     * a matching record in right iterator. Return true, Else goto step 4.
77     * 4. Next record from the right iterator is retrived, if no record found,
78     * goto step 5, else goto step 3.
79     * 5. Variable rightNull is set to true indicating that for the current record
80     * of left iterator right iterator has no matching record values, return true.
81     *
82     * DETAILED DOCUMENTATION
83     *
84     * This is the method that is used to align both the iterators in such a fashion
85     * that actually points to the first valid record of the Left Join Iterator.
86     * Algo :
87     * i. Left Iterator get aligned to its valid first position. If returned
88     * false then Iterator's <state> 'll be set AFTERLAST and LeftJoinIterator
89     * 'll return false indicating that there are no valid records and End.
90     * ii. first() of Right Iterator 'll be called .
91     * iii. If first() of rightIterator returned true and condition also
92     * evaluated true then rightNull flag 'll become false otherwise
93     * rightNull flag 'll become true.LeftJoinIteraotor 'll return true
94     * after setting the state to a VALIDSTATE.
95     * @return true if record found, false otherwise.
96     * @throws DException
97     */

98
99    public boolean first() throws DException {
100       rightNull = false;
101       if (!leftIterator.first()) {
102          state = AFTERLAST;
103          return false;
104       }
105       if (rightIterator.first()) {
106          if (ifConditionSolvedForward()) {
107             return true;
108          }
109       }
110       rightNull = true;
111       state = VALIDSTATE;
112       return true;
113    }
114
115    boolean result;
116
117    /**
118     * This method is responsible to retrieve the NEXT record from iterator.
119     * 1. If the right iterator has matching records with respect to left
120     * iterator current record, rightNull will be false. For this case, right
121     * iterator is checked for next set of matching records satisfying join
122     * condition. If next record found from right iterator that satisfies the
123     * join condition, variable rightNull remains set to false
124     * indicating that for current record from left iterator, there exists
125     * a matching record in right iterator. Return true, Else goto step 3.
126     * 2. If the variable rightNull is true, means the current record from left
127     * iterator does not have more matching records from right iterator,goto step3.
128     * 3. Next record is retrieved from left iterator, if record not found return
129     * false.
130     * 4. First record is retrieved from right iterator, if there are no records
131     * in right iterator, goto step 7, else goto step 5.
132     * 5. Given Join Condition is verified on records got from both underlying
133     * iterators. If condition evaluates to true, variable rightNull is set to
134     * false indicating that for current record from left iterator, there exists
135     * a matching record in right iterator. Return true, Else goto step 6.
136     * 6. Next record from the right iterator is retrived, if no record found,
137     * goto step 7, else goto step 5.
138     * 7. Variable rightNull is set to true indicating that for the current record
139     * of left iterator right iterator has no matching record values, return true.
140     *
141     * DETAILED DOCUMENTATION
142     *
143     * This is the method that is used to align both the iterators in such a
144     * fashion that actually points to the next valid record of the Left Join
145     * Iterator from its current position.
146     * Algo :
147     * i. If previous state is INVALIDSTATE,
148     * through Invalid State Exception.
149     * Else If previous state is AFTERLAST,
150     * return false.
151     * Else If previous state is BEFOREFIRST,
152     * call and return its first() .
153     *
154     * ii. If rightNull flag is true then (indicating that no more valid records
155     * are left corresponding to current value from left Iterator)
156     * iii. Both iterator 'll be attempted to moved to next valid position if
157     * possible and result 'll be returned accordingly .
158     * iv. Else call next() of rightIterator.
159     * v. If returned true and condition evaluated true then return true with
160     * rightNull flag set to false.
161     * vi. Else repeat step iii return its result .
162     * @return true if record found, false otherwise.
163     * @throws DException
164     */

165    public boolean next() throws DException {
166       switch (state) {
167          case INVALIDSTATE:
168             throw new DException("DSE4116", null);
169          case BEFOREFIRST:
170             result = first();
171             return result;
172          case AFTERLAST:
173             result = false;
174             return false;
175          default: {
176             if (rightNull) {
177                result = checkInBothForward();
178                return result;
179             } else {
180                if (!rightIterator.next()) {
181                   result = checkInBothForward();
182                   return result;
183                } else {
184                   if (ifConditionSolvedForward()) {
185                      result = true;
186                      return result;
187                   }
188                   result = checkInBothForward();
189                   return result;
190                }
191             }
192          }
193       }
194    }
195
196    /**
197     * This method is responsible to retrieve the LAST record from iterator.
198     * 1. If there are no records in left iterator, return false.
199     * 2. Last record is retrieved from right iterator, if there are no records
200     * in right iterator, goto step 5, else goto step 3.
201     * 3. Given Join Condition is verified on records got from both underlying
202     * iterators. If condition evaluates to true, variable rightNull is set to
203     * false indicating that for current record from left iterator, there exists
204     * a matching record in right iterator. Return true, Else goto step 4.
205     * 4. Previous record from the right iterator is retrived, if no record found,
206     * goto step 5, else goto step 3.
207     * 5. Variable rightNull is set to true indicating that for the current record
208     * of left iterator right iterator has no matching record values, return true.
209     *
210     * DETAILED DOCUMENTAION
211     *
212     * This is the method that is used to align both the iterators in such a
213     * fashion that actually points to the last valid record of the Left Join
214     * Iterator.
215     * Algo :
216     * i. Left Iterator get aligned to its valid last position. If returned
217     * false then Iterator's <state> 'll be set BEFOREFIRST and LeftJoin
218     * Iterator 'll return false indicating that there are no valid records
219     * and return false.
220     * ii. last() of Right Iterator 'll be called .
221     * iii. If last() of rightIterator returned true and condition also evaluated
222     * true then rightNull flag 'll become false otherwise rightNull flag
223     * 'll become true.LeftJoinIteraotor 'll return true after setting the
224     * state to a VALIDSTATE.
225     * @return true if record found, false otherwise.
226     * @throws DException
227     */

228    public boolean last() throws DException {
229       rightNull = false;
230       if (!leftIterator.last()) {
231          state = BEFOREFIRST;
232          return false;
233       }
234       if (rightIterator.last()) {
235          if (ifConditionSolvedBackward()) {
236             return true;
237          }
238       }
239       rightNull = true;
240       state = VALIDSTATE;
241       return true;
242    }
243
244    /**
245     * This method is responsible to retrieve the PREVIOUS record from iterator.
246     * 1. If the right iterator has matching records with respect to left
247     * iterator current record, rightNull will be false. For this case, right
248     * iterator is checked for previous set of matching records satisfying join
249     * condition. If previous record found from right iterator that satisfies the
250     * join condition, variable rightNull remains set to false indicating that
251     * for current record from left iterator, there exists a matching record in
252     * right iterator. Return true, Else goto step 3.
253     * 2. If the variable rightNull is true, means the current record from left
254     * iterator does not have more matching records from right iterator,goto step3.
255     * 3. Previous record is retrieved from left iterator, if record not
256     * found return false.
257     * 4. Last record is retrieved from right iterator, if there are no records
258     * in right iterator, goto step 7, else goto step 5.
259     * 5. Given Join Condition is verified on records got from both underlying
260     * iterators. If condition evaluates to true, variable rightNull is set to
261     * false indicating that for current record from left iterator, there exists
262     * a matching record in right iterator. Return true, Else goto step 6.
263     * 6. Previous record from the right iterator is retreived, if no record
264     * found, goto step 7, else goto step 5.
265     * 7. Variable rightNull is set to true indicating that for the current record
266     * of left iterator right iterator has no matching record values, return true.
267     *
268     * DETAILED DOCUMENTAION
269     *
270     * This is the method that is used to align both the iterators in such a
271     * fashion that actually points to the previous valid record of the Left Join
272     * Iterator from its current position.
273     * Algo :
274     * i. If previous state is INVALIDSTATE,
275     * through Invalid State Exception.
276     * Else If previous state is AFTERLAST,
277     * call and return its first() .
278     * Else If previous state is BEFOREFIRST,
279     * return false.
280     *
281     * ii. If rightNull flag is true then (indicating that no more valid
282     * records are left corresponding to current value from left Iterator)
283     * iii. Both iterator 'll be attempted to moved to previous valid position
284     * if possible and result 'll be returned accordingly .
285     * iv. Else call previous() of rightIterator.
286     * v. If returned true and condition evaluated true then return true with
287     * rightNull flag set to false.
288     * vi. Else repeat step iii return its result .
289     * @return true if record found, false otherwise.
290     * @throws DException
291     */

292    public boolean previous() throws DException {
293       switch (state) {
294          case INVALIDSTATE:
295             throw new DException("DSE4117", null);
296          case BEFOREFIRST:
297             result = false;
298             return false;
299          case AFTERLAST:
300             result = last();
301             return result;
302          default: {
303             if (rightNull) {
304                result = checkInBothBackward();
305                return result;
306             } else {
307                if (!rightIterator.previous()) {
308                   result = checkInBothBackward();
309                   return result;
310                } else {
311                   if (ifConditionSolvedBackward()) {
312                      result = true;
313                      return result;
314                   }
315                   result = checkInBothBackward();
316                   return result;
317                }
318             }
319          }
320       }
321    }
322
323    /**
324     * This method is responsible for evaluation of given join condition. This
325     * method checks the condition for current record from left iterator and
326     * navigates the right iterator in the forward direction, untill the given
327     * join condition is satisfied.
328     * @return true,if condition is satisfied for any record from right iterator,
329     * returns false, if exists no record in right iterator satisfying join condition.
330     * @throws DException
331     */

332    private boolean ifConditionSolvedForward() throws DException {
333       do {
334          if (conditionVariableValue.run().hashCode() == 0) {
335             state = VALIDSTATE;
336             rightNull = false;
337             return true;
338          }
339       } while (rightIterator.next());
340       return false;
341    }
342
343    /**
344     * This method is responsible for evaluation of given join condition. This
345     * method checks the condition for current record from left iterator and
346     * navigates the right iterator in the backward direction, untill the given
347     * join condition is satisfied.
348     * @return true,if condition is satisfied for any record from right iterator,
349     * returns false, if exists no record in right iterator satisfying join condition.
350     * @throws DException
351     */

352    private boolean ifConditionSolvedBackward() throws DException {
353       do {
354          if (conditionVariableValue.run().hashCode() == 0) {
355             state = VALIDSTATE;
356             return true;
357          }
358       } while (rightIterator.previous());
359       return false;
360    }
361
362    /**
363     * This method is responsible to align the underlying iterators acc. to join
364     * condition.
365     * 1. Next record is retrieved from left iterator, if record not found return
366     * false.
367     * 2. Alignes the right iterator satisfying the join condition.
368     * 3. If there are no records in right iterator that satisfy the join condition,
369     * variable rightNull is set to true indicating that for the current record of
370     * left iterator right iterator has no matching record values.
371     * 4. Return true.
372     * @return true.
373     * @throws DException
374     */

375    private boolean checkInBothForward() throws DException {
376       if (!leftIterator.next()) {
377          state = AFTERLAST;
378          return false;
379       }
380       rightNull = false;
381       if (rightIterator.first()) {
382          if (ifConditionSolvedForward()) {
383             return true;
384          }
385       }
386       rightNull = true;
387       state = VALIDSTATE;
388       return true;
389    }
390
391    /**
392     * This method is responsible to align the underlying iterators acc. to join
393     * condition.
394     * 1. Previous record is retrieved from left iterator, if record
395     * not found return false.
396     * 2. Alignes the right iterator satisfying the join condition.
397     * 3. If there are no records in right iterator that satisfy the join condition,
398     * variable rightNull is set to true indicating that for the current record of
399     * left iterator right iterator has no matching record values.
400     * 3. Return true.
401     * @return true.
402     * @throws DException
403     */

404    private boolean checkInBothBackward() throws DException {
405       if (!leftIterator.previous()) {
406          state = BEFOREFIRST;
407          return false;
408       }
409       rightNull = false;
410       if (rightIterator.last()) {
411          if (ifConditionSolvedBackward()) {
412             return true;
413          }
414       }
415       rightNull = true;
416       state = VALIDSTATE;
417       return true;
418    }
419
420
421    /**
422     * This method returns the key by concating the key of underlying Iterator.
423     * if rightNull is true, it means right iterator has no matching values, then
424     * null is appended as key of Right Iterator.
425     * @return key of left join iterator
426     * @throws com.daffodilwoods.database.resource.DException
427     */

428    public Object JavaDoc getKey() throws com.daffodilwoods.database.resource.DException {
429       ArrayList list = new ArrayList();
430       Object JavaDoc[] leftKeys = (Object JavaDoc[]) leftIterator.getKey();
431       list.addAll(java.util.Arrays.asList(leftKeys));
432       if (rightNull) {
433          for (int i = 0; i < rightCount; i++) {
434             list.add(null);
435          }
436       } else {
437          Object JavaDoc[] rightKeys = (Object JavaDoc[]) rightIterator.getKey();
438          list.addAll(java.util.Arrays.asList(rightKeys));
439       }
440       return list.toArray();
441    }
442
443    /**
444     * This method is responsible to align both underlying iterator acc. to key
445     * pasesed. It is used for a LOJ Iterator created for query having groupby
446     * clause. If any of the iterator's key length is zero, its first record is
447     * retrieved, since for this group, aggregates will be computed for all the
448     * records belonging to that group. Otherwise, key for left/right iterators
449     * are extracted from passed keys and move both the iterators to its corresponding keys.
450     * @param keys represents key where to align, underling iterators. keys
451     * have the values of group by columns.
452     * @throws DException
453     */

454    private void moveAcctoGroupKey(Object JavaDoc[] keys) throws DException {
455       if (leftKeyCount == 0) {
456          leftIterator.first();
457       } else {
458          Object JavaDoc[] leftKeys = new Object JavaDoc[leftKeyCount];
459          System.arraycopy(keys, 0, leftKeys, 0, leftKeyCount);
460          leftIterator.move(leftKeys);
461       }
462       if (rightKeyCount == 0) {
463          rightNull = !rightIterator.first();
464       } else {
465          int rightLength = keys.length - leftKeyCount;
466          Object JavaDoc[] rightKeys = new Object JavaDoc[rightLength];
467          System.arraycopy(keys, leftKeyCount, rightKeys, 0, rightLength);
468          if (isKeyNull(rightKeys)) {
469             rightNull = true;
470          } else {
471             rightNull = false;
472             rightIterator.move(rightKeys);
473          }
474       }
475       state = 0;
476    }
477
478
479    /**
480     * This method returns the byte key by concating the byte keys of both
481     * underlying Iterator. If rightNull is true then -1 is put corresponding to
482     * byte key of Right Iterator.
483     * @return Array of Object having the key
484     * @throws DException
485     */

486   public byte[] getByteKey() throws DException {
487     byte[] leftKeys = leftIterator.getByteKey();
488     if (rightNull) {
489       byte[] result = new byte[leftKeys.length + 4];
490       short leftLen = (short)leftKeys.length;
491       System.arraycopy(CCzufDpowfsufs.getBytes(leftLen),0,result,0,2);
492       System.arraycopy(leftKeys, 0, result, 2, leftKeys.length);
493       System.arraycopy(CCzufDpowfsufs.getBytes((short)-1),0,result,leftLen+2,2);
494       return result;
495     }
496     else{
497       byte[] rightKeys = rightIterator.getByteKey();
498       byte[] resultantKeys = new byte[leftKeys.length + rightKeys.length + 4];
499       short leftLen = (short)leftKeys.length;
500       System.arraycopy(CCzufDpowfsufs.getBytes(leftLen),0,resultantKeys,0,2);
501       System.arraycopy(leftKeys, 0, resultantKeys, 2, leftKeys.length);
502       short rightLen = (short)rightKeys.length;
503       System.arraycopy(CCzufDpowfsufs.getBytes(rightLen),0,resultantKeys,leftLen+2,2);
504       System.arraycopy(rightKeys, 0, resultantKeys, leftKeys.length + 4,
505                        rightKeys.length);
506       return resultantKeys;
507     }
508   }
509
510    /**
511     * This method is responsible to align both underlying iterator acc. to key
512     * pasesed. For a left Join Iterator created on query having group by clause,
513     * call is transfered to moveAcctoGroupKey method.
514     * For a non-group by Join Query, left iterator keys are extracted from the
515     * passed key. Left iterator is aligned acc. to the left iterator key. If the
516     * keys corresponding to right iterator are null, the variable rightNull is
517     * set to true, indicating that the right iterator has no matching values,
518     * Otherwise, right Iterator is aligned to non-null keys of right iterator
519     * extracted from passed key.
520     * @param keys key where to point to Left Join iterator
521     * @throws com.daffodilwoods.database.resource.DException
522     */

523    public void move(Object JavaDoc keys) throws com.daffodilwoods.database.resource.DException {
524       if (leftKeyCount != 0 || rightKeyCount != 0) {
525          moveAcctoGroupKey( (Object JavaDoc[]) keys);
526          return;
527       }
528       Object JavaDoc[] rightKeys = new Object JavaDoc[rightCount];
529       int leftCount = ( (Object JavaDoc[]) keys).length - rightCount;
530       Object JavaDoc[] leftKeys = new Object JavaDoc[leftCount];
531       System.arraycopy(keys, 0, leftKeys, 0, leftCount);
532       System.arraycopy(keys, leftCount, rightKeys, 0, rightCount);
533       leftIterator.move(leftKeys);
534       if (isKeyNull(rightKeys)) {
535          rightNull = true;
536       } else {
537          rightNull = false;
538          rightIterator.move(rightKeys);
539       }
540       state = 0;
541    }
542
543
544    /**
545     * The following methods are used for getting values of current record.
546     * All retrival methods use the following logic.
547     * The retrival method checks passed column, if the column corresponds to LEFT
548     * table, values are retrived from left iterator, otherwise if rightNull flag
549     * is true, Null value is returned corresponding to that column reference of right
550     * iterator, otherwise values are retrived from right iterator.
551     */

552    /**
553     * This method is used to retrieve the values of passed references.
554     * @param columnReferences reference for which values are to be retrived.
555     * Reference may be column or parameter.
556     * @return NonShared FieldBases denoting the value of References. Non Shared
557     * FieldBases are those for which BufferRange is not shared with some other
558     * FieldBase.
559     * @throws DException
560     */

561    public Object JavaDoc getColumnValues(_Reference[] columnReferences) throws DException {
562       int len = columnReferences.length;
563       Object JavaDoc[] values = new Object JavaDoc[len];
564       for (int i = 0; i < len; i++) {
565          values[i] = getColumnValues(columnReferences[i]);
566       }
567       return values;
568    }
569
570    /**
571     * This method is responsible to check whether the passed tables
572     * corresponds to left iterator or right iterator.
573     * @param tDetails table to check
574     * @return table belongs to LEFT or RIGHT iterator.
575     * @throws DException
576     */

577    private int searchInMapping(TableDetails tDetails) throws DException {
578       for (int i = 0; i < tableDetailsMapping.length; i++) {
579          if (tableDetailsMapping[i][0] == tDetails) {
580             return ( (Integer JavaDoc) tableDetailsMapping[i][1]).intValue();
581          }
582       }
583       return -1;
584    }
585
586    /**
587     * This method is used to retrieve all the values from the join query.
588     * This method retrives all the values from the left iterator and values from
589     * right iterator and merge these values to return the valid record of join iterator.
590     * @return NonShared FieldBases denoting the values of all columns of join query.
591     * Non Shared FieldBases are those for which BufferRange is not shared with
592     * some other FieldBase.
593     * @throws DException
594     */

595    public Object JavaDoc getColumnValues() throws DException {
596       ArrayList aList = new ArrayList();
597       Object JavaDoc obj1 = leftIterator.getColumnValues();
598       aList.addAll(Arrays.asList( (Object JavaDoc[]) obj1));
599       Object JavaDoc[] obj2 = null;
600       if (rightNull) {
601         obj2=makeNullFieldLiteralArray(rightColumnCount);
602       } else {
603          obj2 = (Object JavaDoc[]) rightIterator.getColumnValues();
604       }
605       aList.addAll(Arrays.asList(obj2));
606       return aList.toArray();
607    }
608
609    /**
610     * This method is responsible to align both underlying iterator acc. to key
611     * pasesed. It is used for a LOJ Iterator created for query having groupby
612     * clause. If any of the iterator's key length is zero, its first record is
613     * retrieved, since for this group, aggregates will be computed for all the
614     * records belonging to that group. Otherwise, key for left/right iterators
615     * are extracted from passed keys and move both the iterators to its corresponding keys.
616     * @param keys where to align the underling iterators
617     * @throws DException
618     */

619    private void moveAcctoGroupByteKey(byte[] keys) throws DException {
620      int k=0,index =0;
621      int[] t=null;
622        if (leftKeyCount == 0)
623          throw new DException("DSE0", new Object JavaDoc[] {"Left Key Count can not be null"});
624        else{
625          index = moveBytes(leftTableDetails,leftIterator,index,keys);
626        }
627        if (rightKeyCount == 0)
628            rightIterator.first();
629        else{
630          index = moveBytes(rightTableDetails,rightIterator,index,keys);
631        }
632        state = VALIDSTATE;
633     }
634
635     /**
636      * This method is used to move left or right iterator acc. to passed key.
637      * @param td left or right side tables
638      * @param iter left or right side iterators
639      * @param index it is 0
640      * @param keys where to move left or right iterator
641      * @return total keys length including all the tables of left/right hand side
642      * @throws DException
643      */

644     private int moveBytes(TableDetails[] td, _Iterator iter, int index,
645                           byte[] keys) throws DException {
646       byte[] temp;
647       int length = 0;
648       for (int j = 0; j < td.length; j++) {
649         short len = CCzufDpowfsufs.getShortValue(keys,index);
650         length +=len;
651         index = length + 2;
652       }
653       byte[] resultantKeys = new byte[length];
654       System.arraycopy(keys, 0, resultantKeys, 0, resultantKeys.length);
655       iter.move(resultantKeys);
656       rightNull = isKeyNull(resultantKeys);
657       return index;
658     }
659
660     /**
661      * This method is responsible to align both underlying iterator acc. to key
662      * pasesed. For a SemiJoinFilteredIterator created on query having group by clause,
663      * call is transfered to moveAcctoGroupByteKey method.
664      * For a non-group by Join Query, left iterator's key are extracted from the
665      * passed key. Left iterator is aligned acc. to the extracted key and gets the
666      * conditional column values from left iterator record and sets these values
667      * in to rightIterator. If the keys corresponding to right iterator are null,
668      * variable rightNull is set to NULL, indicating that the right iterator has
669      * no matching values from right iterator, Otherwise, right Iterator is aligned
670      * to non-null keys of right iterator extracted from passed key.
671      * @param key key where to point to SemiJoinFilterediterator
672      * @throws com.daffodilwoods.database.resource.DException
673      */

674     public void moveByteKey(byte[] key) throws DException {
675       /** @todo group by iterator work */
676       if (leftKeyCount != 0 || rightKeyCount != 0) {
677         moveAcctoGroupByteKey(key);
678         return;
679       }
680       short leftLength = CCzufDpowfsufs.getShortValue(key,0);
681       byte[] leftKeys = new byte[leftLength];
682       System.arraycopy(key, 2, leftKeys, 0, leftKeys.length);
683       leftIterator.moveByteKey(leftKeys);
684       short rightLength =CCzufDpowfsufs.getShortValue(key,leftKeys.length+2);
685       if (rightLength < 0 )
686         rightNull = true;
687       else {
688         rightNull = false;
689         byte[] rightKeys = new byte[rightLength];
690         System.arraycopy(key, leftKeys.length + 4, rightKeys, 0, rightLength);
691         rightIterator.moveByteKey(rightKeys);
692       }
693       state = 0;
694     }
695
696    /**
697     * This method is used to retrieve the value of passed reference.
698     * This method checks passed column, if the column corresponds to LEFT
699     * table, values are retrived from left iterator, otherwise if rightNull flag
700     * is true, Null value is returned corresponding to that column reference, otherwise
701     * values are retrived from right iterator.
702     * @param references reference for which value is to be retrived.
703     * Reference may be column or parameter.
704     * @return NonShared FieldBase denoting the value of Reference. Non Shared
705     * FieldBases are those for which BufferRange is not shared with some other
706     * FieldBase.
707     * @throws DException
708     */

709    public Object JavaDoc getColumnValues(_Reference references) throws DException {
710       Object JavaDoc values;
711       ColumnDetails refColumnDetail = (ColumnDetails) references;
712       TableDetails tDetails = refColumnDetail.getTable();
713       int index = searchInMapping(tDetails);
714       if (index == -1) {
715          return GeneralPurposeStaticClass.getColumnValuesFromQualified(leftIterator, rightIterator, references, rightNull);
716       }
717       if (index == SimpleConstants.LEFT) {
718          values = leftIterator.getColumnValues(references);
719       } else if (rightNull) {
720          values = new FieldLiteral(FieldUtility.NULLBUFFERRANGE, ( (ColumnDetails) references).getDatatype());
721       } else {
722          values = rightIterator.getColumnValues(references);
723       }
724       return values;
725    }
726
727    /**
728     * This method return the shared FieldBase for the passed reference. By Shared
729     * FieldBase we mean, BufferRange of FieldBase is shared with other FieldBase
730     * objects.
731     * @param references reference for which value is to be retrived
732     * @return shared field base correspondition to passed column reference
733     * @throws DException
734     */

735    public FieldBase field(_Reference references) throws com.daffodilwoods.database.resource.DException {
736       FieldBase values;
737       ColumnDetails refColumnDetail = (ColumnDetails) references;
738       TableDetails tDetails = refColumnDetail.getTable();
739       int index = searchInMapping(tDetails);
740       if (index == -1) {
741          return GeneralPurposeStaticClass.getFieldFromQualified(leftIterator, rightIterator, references, rightNull);
742       }
743       if (index == SimpleConstants.LEFT) {
744          values = leftIterator.field(references);
745       } else if (rightNull) {
746          values = new FieldLiteral(null, ( (ColumnDetails) references).getDatatype());
747          ( (FieldLiteral) values).setBufferRange(FieldUtility.NULLBUFFERRANGE);
748       } else {
749          values = rightIterator.field(references);
750       }
751       return values;
752    }
753
754    /**
755     * This method return the shared FieldBases for the passed references. By Shared
756     * FieldBase we mean, BufferRange of FieldBase is shared with other FieldBase
757     * objects.
758     * @param columnReferences reference for which values are to be retrived
759     * @return shared field base correspondition to passed column reference
760     * @throws DException
761     */

762    public FieldBase[] fields(_Reference[] columnReferences) throws com.daffodilwoods.database.resource.DException {
763       int len = columnReferences.length;
764       FieldBase[] values = new FieldBase[len];
765       for (int i = 0; i < len; i++) {
766          values[i] = field(columnReferences[i]);
767       }
768       return values;
769    }
770
771    /**
772     * This method is used to get the lowest level iterator of the passed column.
773     * For the passed column, Base iterator can not be either of the underlying
774     * iterator, since the column may correspond to either of the table. The value
775     * of passed column are retrieved by checking the variable rightNull. Since,
776     * if rightNull is true and column corresponds to right iterator, NULL will
777     * be returned, otherwise, value is retrived from corresponding iterator.
778     * @param column corresponding to which, iterator has to return
779     * @return base table iterator corresponding to column passed
780     * @throws DException
781     */

782    public _Iterator getBaseIterator(ColumnDetails column) throws com.daffodilwoods.database.resource.DException {
783       return this;
784    }
785
786    /**
787     * This method is used to release the resources(e.g. comparator) releated
788     * with particular iterator and condition.
789     * @throws DException
790     */

791    public void releaseResource() throws DException {
792       conditionVariableValue.releaseResource();
793       leftIterator.releaseResource();
794       rightIterator.releaseResource();
795    }
796    /**
797     * This method is responsible to display the executionPlan of a Select Query.
798     * @return _ExecutionPlan
799     * @throws DException
800     */

801    public _ExecutionPlan getExecutionPlan() throws DException {
802       _ExecutionPlan plan = leftIterator.getExecutionPlan();
803       _ExecutionPlan plan1 = rightIterator.getExecutionPlan();
804       _ExecutionPlan cplans[] = new _ExecutionPlan[] {plan, plan1};
805       return new ExecutionPlan("SemiJoinFilteredIterator", cplans, null, null, null);
806    }
807
808    /**
809     * This method is responsible to display the iterators hierarchy of a Select Query.
810     * @return ExecutionPlanForBrowser
811     * @throws DException
812     */

813    public ExecutionPlanForBrowser getExecutionPlanForBrowser() throws DException {
814       int length = 2;
815       ExecutionPlanForBrowser cplans[] = new ExecutionPlanForBrowser[length];
816       cplans[0] = leftIterator.getExecutionPlanForBrowser();
817       cplans[1] = rightIterator.getExecutionPlanForBrowser();
818       return new ExecutionPlanForBrowser("Nested Join/Left Join", "Join Iterator", cplans, "" + conditionVariableValue, null, null);
819    }
820
821    public void setConditionVariableValue(_Reference[] parm1, Object JavaDoc[] parm2, int parm3) throws DException {
822      if (underlyingRef != null) {
823        parm1 = GeneralPurposeStaticClass.getJointReferences(parm1, underlyingRef);
824        parm2 = GeneralPurposeStaticClass.getJointValues(this, parm2,
825            underlyingRef.length);
826      }
827      super.setConditionVariableValue(parm1, parm2, parm3);
828      conditionVariableValue.setVariableValues(parm1, parm2, parm3);
829      }
830
831    public String JavaDoc toString() {
832       return "SemiJoinFilteredIterator[" + leftIterator + "][" + rightIterator + "]" + conditionVariableValue + "]";
833    }
834 }
835
Popular Tags