KickJava   Java API By Example, From Geeks To Geeks.

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


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.sql99.common.*;
7 import com.daffodilwoods.daffodildb.server.sql99.dql.iterator.*;
8 import com.daffodilwoods.daffodildb.server.sql99.dql.listenerevents.*;
9 import com.daffodilwoods.daffodildb.server.sql99.utils.*;
10 import com.daffodilwoods.daffodildb.utils.*;
11 import com.daffodilwoods.daffodildb.utils.field.*;
12 import com.daffodilwoods.database.resource.*;
13 import com.daffodilwoods.database.utility.*;
14 import com.daffodilwoods.daffodildb.utils.byteconverter.CCzufDpowfsufs;
15
16 /**
17  * <p>Title: SemiJoinIterator </p>
18  * <p>Description: This Class is responsible for retrieving LEFT OUTER JOIN AND
19  * RIGHT OUTER JOIN results with SEEKABLE Join Condition. Left outer Joins
20  * result in all the records from the left table. For the records, for which,
21  * the condition evaluates to false, NULL value is appended for the values
22  * of right table. Here, the JOIN CONDITION is shifted to right underlying
23  * iterator. It also contains columns corresponding to left Iterator as well.
24  * The Iterator maintains the basic propertiy of any Iterator, however it also
25  * possesses couple of other attributes required . Right Outer Joins are just
26  * antisymmetric to the Left Outer Join in nature.
27  * A variable rightNull is used to indicate whether values corresponding to the
28  * right Iterator be valid value of the right Iterators or NULL 'll be appended
29  * instead. Initially it is set to false.
30  * </p>
31  * <p>Copyright: Copyright (c) 2004</p>
32  * <p>Company: </p>
33  * @author not attributable
34  * @version 1.0
35  */

36 public class SemiJoinIterator extends AbstractQualifiedJoinIterator implements _HasRecordIterator {
37
38    /**
39     * an Array of Columns involved in join condition of Left Iterator.
40     */

41    _Reference[] leftColumnReferences; //leftColumnReferences[]
42

43    /**
44     * Variable representing the count of key Columns from right iterator.
45     */

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

48    /**
49     * Variable to store the byte key lenght of the right iterator's keys
50     */

51    int rightKeysCount = -1;
52    /**
53     * The Constructor that is used to initialized the attributes in the class.
54     * @param leftIterator left iterator
55     * @param rightIterator right iterator
56     * @param leftColumnReferences0 conditional columns from left iterator
57     * @param leftKeyColumnInformation0 number of columns involved in group of left iterator
58     * @param rightKeyColumnInformation0 number of columns involved in group of right iterator
59     * @param hasRecordReferences0 hasRecord refererences
60     */

61    public SemiJoinIterator(_Iterator leftIterator, _Iterator rightIterator, _Reference[] leftColumnReferences0, _KeyColumnInformation[] leftKeyColumnInformation0, _KeyColumnInformation[] rightKeyColumnInformation0, ColumnDetails[] hasRecordReferences0) {
62       super(leftIterator, rightIterator, leftKeyColumnInformation0, rightKeyColumnInformation0, hasRecordReferences0);
63       leftColumnReferences = leftColumnReferences0;
64       rightCount = rightKeyColumnInformation0.length;
65       try {
66         rightKeysCount = 0;
67         for (int i = 0; i < rightKeyColumnInformation0.length; i++) {
68           rightKeysCount += rightKeyColumnInformation0[i].getColumnDetails().getSize();
69
70         }
71       }
72       catch (DException ex) {
73       }
74    }
75
76    /**
77     * This method is responsible for retrieving the first record from LOJ iterator.
78     * First record is retrieved from the left iterator, if no record found, return false.
79     * Get the values of conditional columns from left Iterator record and set these
80     * conditional columns values to Right Iterator. If right iterator has no records,
81     * set variable rightNull to true indicating that for the current row of left
82     * iterator right iterator has no matching records, otherwise false indicating
83     * that there exists some matching row in the right iterator that satisfy the
84     * given join condition.
85     *
86     ***************** DETAILED DOCUMENTAION ***********************
87     *
88     * This is the method that is used to align both the iterators in such a
89     * fashion that actually points to the first valid record of the Left Join
90     * Iterator.
91     * Algo :
92     * i. Left Iterator get aligned to its valid first position.
93     * If returned false then Iterator's <state> 'll be set AFTERLAST and
94     * SemiJoinIterator 'll return false indicating that there are no
95     * valid records and End.
96     * ii. After setting leftIterator to its valid first position, Its values
97     * are taken through getColumnValue(), passing leftColumnReferences,
98     * that 'll be setting the VariableValue through call to
99     * setConditionVariableVAlues() to the rightIterator.
100     * iii. first() of Right Iterator 'll be called. So as to get the corresponding
101     * value of leftIterator's aligned record.
102     * iv. If returned false then rightNull flag 'll be set to true.Means no row
103     * in right Iterator is satisfied for the left Iterator's first row.
104     * otherwise rightNull flag 'll become false and LeftJoinIteraotor 'll
105     * return true after setting the state to a VALIDSTATE.
106     *
107     * @return true if record found, false otherwise.
108     * @throws DException
109     */

110    public boolean first() throws DException {
111       rightNull = false;
112       if (!leftIterator.first()) {
113          state = AFTERLAST;
114          return false;
115       }
116       getAndSetConditionValues();
117       rightNull = !rightIterator.first();
118       state = VALIDSTATE;
119       return true;
120    }
121
122    /**
123     * This method is responsible for retrieving the last record from LOJ iterator.
124     * Last record is retrieved from the left iterator, if no record found, return false.
125     * Get the values of conditional columns from left Iterator record and set these
126     * conditional columns values to Right Iterator. If right iterator has no records,
127     * set variable rightNull to true indicating that for the current row of left
128     * iterator right iterator has no matching records, otherwise false indicating
129     * that there exists some matching row in the right iterator that satisfy the
130     * given join condition.
131     *
132     ***************** DETAILED DOCUMENTAION ***********************
133     *
134     * This is the method that is used to align both the iterators in such a fashion
135     * that actually points to the last valid record of the Left Join Iterator.
136     * Algo :
137     * i. Left Iterator get aligned to its valid last position. If returned
138     * false then Iterator's <state> 'll be set BEFOREFIRST and
139     * SemiJoinIterator 'll return false indicating that there are no
140     * valid records and End.
141     * ii. After setting leftIterator to its valid last position, Its values
142     * are taken through getColumnValue(), passing leftColumnReferences,
143     * that 'll be setting the VariableValue through call to
144     * setConditionVariableVAlues() to the rightIterator.
145     * iii. last() of Right Iterator 'll be called.So as to get the corresponding
146     * value of leftIterator's aligned record.
147     * iv. If returned false then rightNull flag 'll be set to true.Means no
148     * row in right Iterator is satisfied for the left Iterator's last row.
149     * otherwise rightNull flag 'll become false and LeftJoinIteraotor 'll
150     * return true after setting the state to a VALIDSTATE.
151     *
152     * @return true if record found, false otherwise.
153     * @throws DException
154     */

155    public boolean last() throws DException {
156       rightNull = false;
157       if (!leftIterator.last()) {
158          state = BEFOREFIRST;
159          return false;
160       }
161       getAndSetConditionValues();
162       rightNull = !rightIterator.last();
163       state = VALIDSTATE;
164       return true;
165    }
166
167    /**
168     * This method is responsible for retrieving the next record from the semi join
169     * iterator satisfying the join condition. The Algo used is as follows:
170     * 1. If variable rightNull is true it means current record from left iterator
171     * has no matching record from right iterator. Goto step 3.
172     * 2. If variable rightNull is false, it indicates that there may be more
173     * valid records corresponding to current value from left Iterator. Next
174     * record is retreived from right iterator. If record found, return true,
175     * else goto step 3.
176     * 3. Next record is retrieved from LEFT iterator, if no record
177     * found, return false.
178     * 4. Get the conditional columns values from left Iterator record and set
179     * these conditional columns values to Right Iterator.
180     * 5. If right iterator has no records, set variable rightNull to true,
181     * otherwise false. return true.
182     *
183     * DETAILED DOCUMENTATION
184     *
185     * This is the method that is used to align both the iterators in such a
186     * fashion that actually points to the next valid record of the Left Join
187     * Iterator from its current position.
188     * Algo :
189     * i. If previous state is INVALIDSTATE,
190     * through Invalid State Exception.
191     * Else If previous state is AFTERLAST,
192     * return false.
193     * Else If previous state is BEFOREFIRST,
194     * call and return its first() .
195     *
196     * ii. If rightNull flag is true then (indicating that no more valid records
197     * are left corresponding to current value from left Iterator)
198     * iii. 1. Left Iterator get aligned to its valid next position. If
199     * returned false then Iterator's <state> 'll be set AFTERLAST
200     * and SemiJoinIterator 'll return false indicating that there
201     * are no more valid records and method 'll return false.
202     * 2. After setting leftIterator to its valid next position, Its
203     * values are taken through getColumnValue(), passing leftColumnReferences,
204     * that 'll be setting the VariableValue through call to
205     * setConditionVariableValues() to the rightIterator.
206     * 3. first() of Right Iterator 'll be called.
207     * 4. If returned false then rightNull flag 'll be set to true.
208     * otherwise rightNull flag 'll become false and LeftJoinIteraotor 'll
209     * return true after setting the state to a VALIDSTATE.
210     * iv. Else (i.e rightNull flag is false indicating that there may be more
211     * records valid left corresponding to current value from left Iterator)
212     * right Iterator 'll be iterated to its valid next position.
213     * If returned true then state 'll set to VALIDSTATE and true 'll
214     * be returned.
215     * else (step iii) 'll be called and state 'll set to VALIDSTATE
216     * and true 'll be returned.
217     * @return true if record found, false otherwise.
218     * @throws DException
219     */

220
221    public boolean next() throws DException {
222       switch (state) {
223          case INVALIDSTATE:
224             throw new DException("DSE4116", null);
225          case AFTERLAST:
226             return false;
227          case BEFOREFIRST:
228             return first();
229          default: {
230             if (rightNull) {
231                if (!leftIterator.next()) {
232                   state = AFTERLAST;
233                   return false;
234                }
235                getAndSetConditionValues();
236                rightNull = !rightIterator.first();
237             } else {
238                if (!rightIterator.next()) {
239                   if (!leftIterator.next()) {
240                      state = AFTERLAST;
241                      return false;
242                   }
243                   getAndSetConditionValues();
244                   rightNull = !rightIterator.first();
245                }
246             }
247             state = VALIDSTATE;
248             return true;
249          }
250       }
251    }
252
253    /**
254     * This method is responsible for retrieving the previous record from the LOJ
255     * iterator satisfying the join condition. The Algo used is as follows:
256     * 1. If variable rightNull is true it means current record from left iterator
257     * has no matching record from right iterator. Goto step 3.
258     * 2. If variable rightNull is false, it indicates that there may be more
259     * valid records corresponding to current value from left Iterator. Previous
260     * record is retreived from right iterator. If record found, return true,
261     * else goto step 3.
262     * 3. Previous record is retrieved from LEFT iterator, if no record
263     * found, return false.
264     * 4. Get the conditional columns values from left Iterator record and set
265     * these conditional columns values to Right Iterator.
266     * 5. If right iterator has no records, set variable rightNull to true,
267     * otherwise false. return true.
268     *
269     * DETAILED DOCUMENTATION
270     *
271     * <p>This is the method that is used to align both the iterators in such a
272     * fashion that actually points to the previous valid record of the Left
273     * Join Iterator from its current position. Boolean <b>rightNull</b>
274     * indicates no more valid records are left corresponding to current value
275     * from left Iterator <br>
276     * <b>Algo :</b><br>
277     * <ol>
278     * <li> If previous <state> is INVALIDSTATE, through Invalid State Exception.</li>
279     * <li> If previous state is AFTERLAST,call and return its first() </li>
280     * <li> If previous state is BEFOREFIRST,return false.</li>
281     * <li>. If rightNull flag is true then
282     * <ol>
283     * <li> Left Iterator get aligned to its valid next position. If
284     * returned false then Iterator's <state> 'll be set BEFOREFIRST
285     * and SemiJoinIterator 'll return false indicating that there
286     * are no more valid records and method 'll return false.</li>
287     * <li> After setting leftIterator to its valid previous position,
288     * Its values are taken through getColumnValue(), passing
289     * leftColumnReferences, that 'll be set in the VariableValue
290     * through call to setConditionVariableValues() to the rightIterator,
291     * then last() of Right Iterator 'll be called.</li>
292     * <li> If returned false then rightNull flag 'll be set to true.
293     * otherwise rightNull flag 'll become false and LeftJoinIteraotor 'll
294     * return true after setting the state to a VALIDSTATE.</li>
295     * </ol><br>
296     * <b>ELSE</b><br>
297     * <p> Right Iterator 'll be iterated to its valid previous position.
298     * If returned true then state 'll set to VALIDSTATE and true
299     * will be returned. otherwise step 3 will be called and
300     * state 'll set to VALIDSTATE and true 'll be returned.</p>
301     * @return true if record found, false otherwise.
302     * @throws DException
303     */

304
305    public boolean previous() throws DException {
306       switch (state) {
307          case INVALIDSTATE:
308             throw new DException("DSE4117", null);
309          case AFTERLAST:
310             return last();
311          case BEFOREFIRST:
312             return false;
313          default: {
314             if (rightNull) {
315                if (!leftIterator.previous()) {
316                   state = BEFOREFIRST;
317                   return false;
318                }
319                getAndSetConditionValues();
320                rightNull = !rightIterator.last();
321             } else {
322                if (!rightIterator.previous()) {
323                   if (!leftIterator.previous()) {
324                      state = BEFOREFIRST;
325                      return false;
326                   }
327                   getAndSetConditionValues();
328                   rightNull = !rightIterator.last();
329                }
330             }
331             state = VALIDSTATE;
332             return true;
333          }
334       }
335    }
336
337    /**
338     * This method returns the key by concating the key of underlying Iterator.
339     * if rightNull is true then null is appended as key of Right Iterator.
340     * @return key of semi join iterator
341     * @throws com.daffodilwoods.database.resource.DException
342     */

343    public Object JavaDoc getKey() throws com.daffodilwoods.database.resource.DException {
344       ArrayList list = new ArrayList();
345       Object JavaDoc[] leftKeys = (Object JavaDoc[]) leftIterator.getKey();
346       list.addAll(java.util.Arrays.asList(leftKeys));
347       if (rightNull) {
348          for (int i = 0; i < rightCount; i++) {
349             list.add(null);
350          }
351       } else {
352          Object JavaDoc[] rightKeys = (Object JavaDoc[]) rightIterator.getKey();
353          list.addAll(java.util.Arrays.asList(rightKeys));
354       }
355       return list.toArray();
356    }
357
358   /**
359     * This method is responsible to align both underlying iterator acc. to key
360     * pasesed. It is used for a LOJ Iterator created for query having groupby
361     * clause. If any of the iterator's key length is zero, its first record is
362     * retrieved, since for this group, aggregates will be computed for all the
363     * records belonging to that group. Otherwise, key for left/right iterators
364     * are extracted from passed keys and move both the iterators to its corresponding keys.
365     * @param keys represents key where to align, underling iterators. keys
366     * have the values of group by columns.
367     * @throws DException
368     */

369    private void moveAcctoGroupKey(Object JavaDoc[] keys) throws DException {
370      if (leftKeyCount == 0) {
371         leftIterator.first();
372      } else {
373         Object JavaDoc[] leftKeys = new Object JavaDoc[leftKeyCount];
374         System.arraycopy(keys, 0, leftKeys, 0, leftKeyCount);
375         leftIterator.move(leftKeys);
376      }
377      getAndSetConditionValues();
378      if (rightKeyCount == 0) {
379         rightNull = !rightIterator.first();
380      } else {
381         int rightLength = keys.length - leftKeyCount;
382         Object JavaDoc[] rightKeys = new Object JavaDoc[rightLength];
383         System.arraycopy(keys, leftKeyCount, rightKeys, 0, rightLength);
384         if (isKeyNull(rightKeys)) {
385            rightNull = true;
386         } else {
387            rightNull = false;
388            rightIterator.move(rightKeys);
389         }
390      }
391      state = VALIDSTATE;
392    }
393
394    /**
395     * This method is responsible to align both underlying iterator acc. to key
396     * pasesed. For a Semi Join Iterator created on query having group by clause,
397     * call is transfered to moveAcctoGroupKey method.
398     * For a non-group by Join Query, left iterator and right keys are extracted
399     * from the passed key. First, left iterator is aligned acc. to the left iterator
400     * key and gets the conditional column values from left iterator record, and
401     * sets these values in to rightIterator. If the keys corresponding to right
402     * iterator are null, variable rightNull is set to NULL, indicating that the
403     * right iterator has no matching values from right iterator, Otherwise, right
404     * Iterator is aligned to non-null keys of right iterator extracted from passed key.
405     * @param keys key where to point to Semi Join iterator
406     * @throws com.daffodilwoods.database.resource.DException
407     */

408    public void move(Object JavaDoc keys) throws com.daffodilwoods.database.resource.DException {
409       if (leftKeyCount != 0 || rightKeyCount != 0) {
410          moveAcctoGroupKey( (Object JavaDoc[]) keys);
411          return;
412       }
413       Object JavaDoc[] rightKeys = new Object JavaDoc[rightCount];
414       int leftCount = ( (Object JavaDoc[]) keys).length - rightCount;
415       Object JavaDoc[] leftKeys = new Object JavaDoc[leftCount];
416       System.arraycopy(keys, 0, leftKeys, 0, leftCount);
417       System.arraycopy(keys, leftCount, rightKeys, 0, rightCount);
418       leftIterator.move(leftKeys);
419       getAndSetConditionValues();
420       if (isKeyNull(rightKeys)) {
421          rightNull = true;
422       } else {
423          rightNull = false;
424          rightIterator.move(rightKeys);
425       }
426       state = 0;
427    }
428
429    /**
430     * The following methods are used for getting values of current record.
431     * All retrival methods use the following logic.
432     * The retrival method checks passed column, if the column corresponds to LEFT
433     * table, values are retrived from left iterator, otherwise if rightNull flag
434     * is true, Null value is returned corresponding to that column reference, otherwise
435     * values are retrived from right iterator.
436     */

437    /**
438     * This method is used to retrieve the values of passed references.
439     * @param columnReferences reference for which values are to be retrived.
440     * Reference may be column or parameter.
441     * @return NonShared FieldBases denoting the value of References. Non Shared
442     * FieldBases are those for which BufferRange is not shared with some other
443     * FieldBase.
444     * @throws DException
445     */

446    public Object JavaDoc getColumnValues(_Reference[] columnReferences) throws DException {
447       int len = columnReferences.length;
448       Object JavaDoc[] values = new Object JavaDoc[len];
449       try {
450          for (int i = 0; i < len; i++) {
451             values[i] = getColumnValues(columnReferences[i]);
452          }
453       } catch (DException E) {
454          throw E;
455       }
456       return values;
457    }
458
459    /**
460     * This method is used to retrieve all the values from the join query.
461     * This method retrives all the values from the left iterator and values from
462     * right iterator and merge these values to return the valid record of join iterator.
463     * @return NonShared FieldBases denoting the values of all columns of join query.
464     * Non Shared FieldBases are those for which BufferRange is not shared with
465     * some other FieldBase.
466     * @throws DException
467     */

468    public Object JavaDoc getColumnValues() throws DException {
469       ArrayList aList = new ArrayList();
470       Object JavaDoc obj1 = null;
471       try {
472          obj1 = leftIterator.getColumnValues();
473       } catch (DException ex) {
474          throw ex;
475       }
476       aList.addAll(Arrays.asList( (Object JavaDoc[]) obj1));
477       Object JavaDoc[] obj2 = null;
478       if (rightNull) {
479         obj2=makeNullFieldLiteralArray(rightColumnCount);
480       } else {
481          obj2 = (Object JavaDoc[]) rightIterator.getColumnValues();
482       }
483       aList.addAll(Arrays.asList(obj2));
484       return aList.toArray();
485    }
486
487    /**
488     * This method is used to retrieve the value of passed reference.
489     * This method checks passed column, if the column corresponds to LEFT
490     * table, values are retrived from left iterator, otherwise if rightNull flag
491     * is true, Null value is returned corresponding to that column reference, otherwise
492     * values are retrived from right iterator.
493     * @param references reference for which value is to be retrived.
494     * Reference may be column or parameter.
495     * @return NonShared FieldBase denoting the value of Reference. Non Shared
496     * FieldBases are those for which BufferRange is not shared with some other
497     * FieldBase.
498     * @throws DException
499     */

500    public Object JavaDoc getColumnValues(_Reference references) throws DException {
501       Object JavaDoc values = null;
502       ColumnDetails refColumnDetail = (ColumnDetails) references;
503       TableDetails tDetails = refColumnDetail.getTable();
504       int index = searchInMapping(tDetails);
505       if (index == -1) {
506          return GeneralPurposeStaticClass.getColumnValuesFromQualified(leftIterator, rightIterator, references, rightNull);
507       }
508       if (index == SimpleConstants.LEFT) {
509          values = leftIterator.getColumnValues(references);
510       } else if (rightNull) {
511          values = new FieldLiteral(null, ( (ColumnDetails) references).getDatatype());
512          ( (FieldLiteral) values).setBufferRange(FieldUtility.NULLBUFFERRANGE);
513       } else {
514          values = rightIterator.getColumnValues(references);
515       }
516       return values;
517    }
518
519    /**
520     * This method return the shared FieldBase for the passed reference. By Shared
521     * FieldBase we mean, BufferRange of FieldBase is shared with other FieldBase
522     * objects.
523     * @param references reference for which value is to be retrived
524     * @return shared field base correspondition to passed column reference
525     * @throws DException
526     */

527    public FieldBase field(_Reference references) throws com.daffodilwoods.database.resource.DException {
528       FieldBase values = null;
529       ColumnDetails refColumnDetail = (ColumnDetails) references;
530       TableDetails tDetails = refColumnDetail.getTable();
531       int index = searchInMapping(tDetails);
532       if (index == -1) {
533          return GeneralPurposeStaticClass.getFieldFromQualified(leftIterator, rightIterator, references, rightNull);
534       }
535       if (index == SimpleConstants.LEFT) {
536          values = leftIterator.field(references);
537       } else if (rightNull) {
538          values = new FieldLiteral(null, ( (ColumnDetails) references).getDatatype());
539          ( (FieldLiteral) values).setBufferRange(FieldUtility.NULLBUFFERRANGE);
540       } else {
541          values = rightIterator.field(references);
542       }
543       return values;
544    }
545
546    /**
547     * This method return the shared FieldBases for the passed references. By Shared
548     * FieldBase we mean, BufferRange of FieldBase is shared with other FieldBase
549     * objects.
550     * @param columnReferences reference for which values are to be retrived
551     * @return shared field base correspondition to passed column reference
552     * @throws DException
553     */

554    public FieldBase[] fields(_Reference[] columnReferences) throws com.daffodilwoods.database.resource.DException {
555       int len = columnReferences.length;
556       FieldBase[] values = new FieldBase[len];
557       try {
558          for (int i = 0; i < len; i++) {
559             values[i] = field(columnReferences[i]);
560          }
561       } catch (DException E) {
562          throw E;
563       }
564       return values;
565    }
566
567    /**
568     * This method is responsible to align both underlying iterator acc. to key
569     * pasesed. It is used for a LOJ Iterator created for query having groupby
570     * clause. If any of the iterator's key length is zero, its first record is
571     * retrieved, since for this group, aggregates will be computed for all the
572     * records belonging to that group. Otherwise, key for left/right iterators
573     * are extracted from passed keys and move both the iterators to its corresponding keys.
574     * @param keys where to align the underling iterators
575     * @throws DException
576     */

577    private void moveAcctoGroupByteKey(byte[] keys) throws DException {
578      int k = 0, index = 0;
579      int[] t = null;
580      if (leftKeyCount == 0)
581        throw new DException("DSE0",
582                             new Object JavaDoc[] {"Left Key Count can not be null"});
583      else {
584        index = moveBytes(leftTableDetails, leftIterator, index, keys);
585      }
586      getAndSetConditionValues();
587      if (rightKeyCount == 0)
588        rightIterator.first();
589      else {
590        index = moveBytes(rightTableDetails, rightIterator, index, keys);
591      }
592      state = VALIDSTATE;
593    }
594
595   /**
596    * This method is used to move left or right iterator acc. to passed key.
597    * @param td left or right side tables
598    * @param iter left or right side iterators
599    * @param index it is 0
600    * @param keys where to move left or right iterator
601    * @return total keys length including all the tables of left/right hand side
602    * @throws DException
603    */

604   private int moveBytes(TableDetails[] td ,_Iterator iter, int index, byte[] keys) throws
605       DException {
606     int length = 0;
607     for (int j = 0; j < td.length; j++) {
608       short len = CCzufDpowfsufs.getShortValue(keys,index);
609       length +=len;
610       index = length + 2;
611     }
612     byte[] resultantKeys = new byte[length];
613     System.arraycopy(keys, 0, resultantKeys, 0, resultantKeys.length);
614     iter.move(resultantKeys);
615     rightNull = isKeyNull(resultantKeys);
616     return index;
617   }
618
619   /**
620    * This method returns the byte key by concating the byte keys of both
621    * underlying Iterator. If rightNull is true then -1 is put corresponding to
622    * byte key of Right Iterator.
623    * @return Array of Object having the key
624    * @throws DException
625    */

626   public byte[] getByteKey() throws DException {
627       byte[] leftKeys = leftIterator.getByteKey();
628       if (rightNull) {
629         byte[] result = new byte[leftKeys.length + rightKeysCount + 4];
630         short leftLen = (short)leftKeys.length;
631         System.arraycopy(CCzufDpowfsufs.getBytes(leftLen),0,result,0,2);
632         System.arraycopy(leftKeys, 0, result, 2, leftKeys.length);
633         System.arraycopy(CCzufDpowfsufs.getBytes((short)-1),0,result,leftLen+2,2);
634         Arrays.fill(result,leftLen+4,result.length-1,(byte)-1);
635         return result;
636       }
637       else{
638         byte[] rightKeys = rightIterator.getByteKey();
639         byte[] resultantKeys = new byte[leftKeys.length + rightKeys.length + 4];
640         short leftLen = (short)leftKeys.length;
641         System.arraycopy(CCzufDpowfsufs.getBytes(leftLen),0,resultantKeys,0,2);
642         System.arraycopy(leftKeys, 0, resultantKeys, 2, leftKeys.length);
643         short rightLen = (short)rightKeys.length;
644         System.arraycopy(CCzufDpowfsufs.getBytes(rightLen),0,resultantKeys,leftLen+2,2);
645         System.arraycopy(rightKeys, 0, resultantKeys, leftKeys.length + 4,
646                          rightKeys.length);
647         return resultantKeys;
648
649       }
650   }
651
652   /**
653    * This method is responsible to align both underlying iterator acc. to key
654    * pasesed. For a Semi Join Iterator created on query having group by clause,
655    * call is transfered to moveAcctoGroupByteKey method.
656    * For a non-group by Join Query, left iterator's key are extracted from the
657    * passed key. Left iterator is aligned acc. to the extracted key and gets the
658    * conditional column values from left iterator record and sets these values
659    * in to rightIterator. If the keys corresponding to right iterator are null,
660    * variable rightNull is set to NULL, indicating that the right iterator has
661    * no matching values from right iterator, Otherwise, right Iterator is aligned
662    * to non-null keys of right iterator extracted from passed key.
663    * @param key key where to point to SemiJoiniterator
664    * @throws com.daffodilwoods.database.resource.DException
665    */

666   public void moveByteKey(byte[] key) throws DException {
667     if (leftKeyCount != 0 || rightKeyCount != 0) {
668       moveAcctoGroupByteKey(key);
669       return;
670     }
671     short leftLength = CCzufDpowfsufs.getShortValue(key,0);
672     byte[] leftKeys = new byte[leftLength];
673     System.arraycopy(key, 2, leftKeys, 0, leftKeys.length);
674     leftIterator.moveByteKey(leftKeys);
675     getAndSetConditionValues();
676     short rightLength =CCzufDpowfsufs.getShortValue(key,leftLength+2);
677     if (rightLength <0)
678       rightNull = true;
679     else {
680       rightNull = false;
681       byte[] rightKeys = new byte[rightLength];
682       System.arraycopy(key, leftKeys.length + 4, rightKeys, 0, rightLength);
683       rightIterator.moveByteKey(rightKeys);
684     }
685     state = 0;
686   }
687
688    /**
689     * This method is responsible to check whether the passed tables
690     * corresponds to left iterator or right iterator.
691     * @param tDetails table to check
692     * @return table belongs to LEFT or RIGHT iterator.
693     * @throws DException
694     */

695    private int searchInMapping(TableDetails tDetails) throws DException {
696       for (int i = 0; i < tableDetailsMapping.length; i++) {
697          if (tableDetailsMapping[i][0] == tDetails) {
698             return ( (Integer JavaDoc) tableDetailsMapping[i][1]).intValue();
699          }
700       }
701       return -1;
702    }
703
704    /**
705     * OTHER SUPPORTING METHODS
706     */

707
708    /**
709     * This method is responsible to set the values got from left iterator into
710     * right iterator. It retrieves the values of conditional columns from left
711     * iterator and sets their values to Right Iterator. ConditionalColumns of
712     * left Iterator will act as parameters in the join condition placed in right
713     * iterator E.g if condition is RightTable.rightColumn = LeftTable.leftColumn,
714     * then it will be placed in rightIterator and the value of LeftTable.leftColumn
715     * is provided by JoinIterator.
716     * @throws DException
717     */

718    public void getAndSetConditionValues() throws DException {
719      Object JavaDoc[] values = (Object JavaDoc[]) leftIterator.getColumnValues(leftColumnReferences);
720      rightIterator.setConditionVariableValue(leftColumnReferences, values, 1);
721    }
722
723    /**
724     * This method is used to get the lowest level iterator of the passed column.
725     * For the passed column, Base iterator can not be either of the underlying
726     * iterator, since the column may correspond to either of the table. The value
727     * of passed column are retrieved by checking the variable rightNull. Since,
728     * if rightNull is true and column corresponds to right iterator, NULL will
729     * be returned, otherwise, value is retrived from corresponding iterator.
730     * @param column corresponding to which, iterator has to return
731     * @return base table iterator corresponding to column passed
732     * @throws DException
733     */

734    public _Iterator getBaseIterator(ColumnDetails column) throws com.daffodilwoods.database.resource.DException {
735       return this;
736    }
737
738    /**
739     * This method is responsible to display the executionPlan of a Select Query.
740     * @return _ExecutionPlan
741     * @throws DException
742     */

743    public _ExecutionPlan getExecutionPlan() throws DException {
744       _ExecutionPlan plan = leftIterator.getExecutionPlan();
745       _ExecutionPlan plan1 = rightIterator.getExecutionPlan();
746       _ExecutionPlan cplans[] = new _ExecutionPlan[] {plan, plan1};
747       return new ExecutionPlan("SemiJoinIterator", cplans, null, null, null);
748    }
749
750    /**
751     * This method is responsible to display the iterators hierarchy of a Select Query.
752     * @return ExecutionPlanForBrowser
753     * @throws DException
754     */

755    public ExecutionPlanForBrowser getExecutionPlanForBrowser() throws DException {
756       int length = 2;
757       ExecutionPlanForBrowser cplans[] = new ExecutionPlanForBrowser[length];
758       cplans[0] = leftIterator.getExecutionPlanForBrowser();
759       cplans[1] = rightIterator.getExecutionPlanForBrowser();
760       String JavaDoc refer = leftColumnReferences == null ? "" : "" + Arrays.asList(leftColumnReferences);
761       refer = " Outer Reference " + refer;
762       return new ExecutionPlanForBrowser("Nested Join/Semi Join" + refer, "Semi Join Iterator", cplans, refer, null, null);
763    }
764
765    public String JavaDoc toString() {
766       return "SemiJoinIterator[" + leftIterator + "]\n\n\n[" + rightIterator + "]";
767    }
768
769 }
770
Popular Tags