KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > daffodilwoods > daffodildb > server > sql99 > dql > iterator > set > IntersectAllIterator


1 package com.daffodilwoods.daffodildb.server.sql99.dql.iterator.set;
2
3
4 import java.util.*;
5 import com.daffodilwoods.daffodildb.client.*;
6 import com.daffodilwoods.daffodildb.server.sql99.common.*;
7 import com.daffodilwoods.daffodildb.server.sql99.dql.execution.*;
8 import com.daffodilwoods.daffodildb.server.sql99.dql.iterator.*;
9 import com.daffodilwoods.daffodildb.server.sql99.utils.*;
10 import com.daffodilwoods.daffodildb.utils.comparator.*;
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  *
18  * <p>Title: </p>
19  * <p>This class is required to retrive the result from a select query having
20  * INTERSECT ALL operator. INTERSECT operator displays the records which have
21  * same values of selected columns in corresonding iterator. INTERSECT ALL
22  * operator also retruns duplicate records. </p>
23  * <p>Copyright: Copyright (c) 2003</p>
24  * <p>Company: </p>
25  * @author SelectTeam
26  * @version 1.0
27  */

28
29 public class IntersectAllIterator extends BaseJoinIterator {
30   /**
31    * Selected columns from left iterator
32    */

33   protected _Reference[] leftColumnReferences;
34   /**
35    * Selected columns from right iterator
36    */

37   protected _Reference[] rightColumnReferences;
38   /**
39    * Order by columns from left iterator
40    */

41   protected _Reference[] orderLeftCD;
42   /**
43    * Order by columns from right iterator
44    */

45   protected _Reference[] orderRightCD;
46    /**
47     * Comparator that is used to compare the selected column values
48     * from left iterator with that of right iterator.
49     */

50    protected SuperComparator comparator;
51
52    /**
53     * A public constructor, that takes five arguments, two are left and right iterators, and
54     * other two are left and right side selected column References. A comparator is also provided for the
55     * purpose of comparison.
56     *
57     * A state is also maintained, that specifies the current status of the current level iterator(this).
58     *
59     * The State INVALIDSTATE means iterator is not aligned properly and needs to be aligned
60     * before doing any further operations.
61     *
62     * The State VALIDSTATE means iterator is aligned properly and can be moved next()/ previous()
63     * as well as values can also be retrieved
64     *
65     * The State BEFOREFIRST means, iterator has reached before the first record or there is no record in the result set.
66     * Iterator is not aligned properly and needs to be aligned through calling first()/ last() before doing any further operations.
67     *
68     * The State AFTERLAST means, iterator has reached after the last record or there is no record in the result set.
69     * Iterator is not aligned properly and needs to be aligned through calling first()/ last() before doing any further operations.
70     *
71    /**
72     * Initializes the variables required in Intersect All operator result of two
73     * passed iterators.
74     * @param leftIterator left iterator
75     * @param rightIterator right resultset
76     * @param leftColumnReferences0 selected columns of left iterator
77     * @param rightColumnReferences0 selected columns of right iterator
78     * @param comparator0 that is used to compare the selected column values from
79     * left iterator with that from right iteraor.
80     * @param orderLeftCD0 order by columns from left iterator
81     * @param orderRightCD0 order by columns from right iterator
82     * @throws DException
83     */

84    public IntersectAllIterator(_Iterator leftIterator, _Iterator rightIterator, _Reference[] leftColumnReferences0, _Reference[] rightColumnReferences0, SuperComparator comparator0, _Reference[] orderLeftCD0, _Reference[] orderRightCD0) throws DException {
85       super(leftIterator, rightIterator);
86       leftColumnReferences = leftColumnReferences0;
87       rightColumnReferences = rightColumnReferences0;
88       comparator = comparator0;
89       orderLeftCD = orderLeftCD0;
90       orderRightCD = orderRightCD0;
91       state = INVALIDSTATE;
92    }
93
94   /**
95    * The following methods are used for navigation of records. These methods
96    * retrive the records from both iterator. Compare selected column values. If
97    * records are same, return the record. Else navigate both underlying iterators
98    * such that both iterator are aligned to records having same values of selected columns.
99    */

100   /**
101     * This method is responsible to retrieve the first record from the iterator.
102     * 1. First Record is retrieved from both underlying iterator. If any of the
103     * underlying iterator has no records, return false.
104     * 2. Get selected column values from both iterator. Compare the values.
105     * a. If values are same, it means both iterator are pointed to records
106     * with common selected column values, return true.
107     * b. Next record is retrieved from iterator that has smaller set of
108     * values as compared to that of another iterator. If iterator has
109     * no more records, return false Else, goto step 2.
110     *
111     * DETAILED DOCUMENTATION
112     *
113     * Both iterators are aligned to their valid first record. If true then Using the indexing feature. smaller value from
114     * among the iterator is relatively seeked from current location for the bigger record. The process continues till there does not appears any common record.
115     * @return true if first common record is found else return false.
116     * @throws DException
117     */

118    public boolean first() throws DException {
119       return (state = leftIterator.first() && rightIterator.first()
120               && alignForward() ? VALIDSTATE : AFTERLAST) != AFTERLAST;
121    }
122
123    /**
124     * This method is responsible to retrieve the last record from the iterator.
125     * 1. Last Record is retrieved from both underlying iterator. If any of the
126     * underlying iterator has no records, return false.
127     * 2. Get selected column values from both iterator. Compare the values.
128     * a. If values are same, it means both iterator are pointed to records
129     * with common selected column values, return true.
130     * b. Previous record is retrieved from iterator that has larger set of
131     * values as compared to that of another iterator. If iterator has
132     * no more records, return false Else goto step 2.
133     *
134     * DETAILED DOCUMENTATION
135     *
136     * Both iterators are aligned to their valid last record. If true then Using the indexing feature. smaller value from
137     * among the iterator is relatively seeked from current location for the smaller record. The process continues till there does not appears any common record.
138     * @return true if last common record is found else return false.
139     * @throws DException
140     */

141    public boolean last() throws DException {
142       return (state = leftIterator.last() && rightIterator.last()
143               && alignBackward() ? VALIDSTATE : BEFOREFIRST) != BEFOREFIRST;
144    }
145
146    /**
147     * This method is responsible to retrieve the next record from the iterator.
148     * 1. Next Record is retrieved from both underlying iterator. If any of the
149     * underlying iterator has no more records, return false.
150     * 2. Get selected column values from both iterator. Compare the values.
151     * a. If values are same, it means both iterator are pointed to records
152     * with common selected column values, return true.
153     * b. Next record is retrieved from iterator that has smaller set of
154     * values as compared to that of another iterator. If iterator has
155     * no more records, return false Else, goto step 2.
156     *
157     * DETAILED DOCUMENTATION
158     *
159     * * i. If previous state is INVALIDSTATE,
160     * through Invalid State Exception.
161     * ii. Else If previous state is AFTERLAST,
162     * return false.
163     * iii. Else If previous state is BEFOREFIRST,
164     * call and return its first() .
165     * iv. Else If any of the iterator could not iterate to the valid next position then method 'll return false.
166     * v. Otherwise they 'll be aligned to the valid common record using forward seek from its current position
167     * and its result 'll be returned .
168     *
169     * @return true if next common record is found else return false.
170     * @throws DException
171     */

172    public boolean next() throws DException {
173       switch (state) {
174          case INVALIDSTATE:
175             throw new DException("DSE4116", null);
176          case BEFOREFIRST:
177             return first();
178          case AFTERLAST:
179             return false;
180          default:
181             if (!leftIterator.next()) {
182                return false;
183             }
184             if (!rightIterator.next()) {
185                return false;
186             }
187             return alignForward();
188       }
189    }
190
191    /**
192     * This method is responsible to retrieve the previous record from the iterator.
193     * 1. Previous Record is retrieved from both underlying iterator. If any of the
194     * underlying iterator has no more records, return false.
195     * 2. Get selected column values from both iterator. Compare the values.
196     * a. If values are same, it means both iterator are pointed to records
197     * with common selected column values, return true.
198     * b. Previous record is retrieved from iterator that has larger set of
199     * values as compared to that of another iterator. If iterator has
200     * no more records, return false Else goto step 2.
201     *
202     * DETAILED DOCUMENTATION
203     *
204     * i. If previous state is INVALIDSTATE,
205     * through Invalid State Exception.
206     * ii. Else If previous state is BEFOREFIRST,
207     * return false.
208     * iii.Else If previous state is AFTERLAST,
209     * call and return its last() .
210     * iv. Else If any of the iterator could not iterate to the valid previous position then method 'll return false.
211     * v. Otherwise they 'll be aligned to the valid common record using backward seek from its current position
212     * and its result 'll be returned .
213     *
214     * @return true if previous common record is found else return false.
215     * @throws DException
216     */

217    public boolean previous() throws DException {
218       switch (state) {
219          case INVALIDSTATE:
220             throw new DException("DSE4117", null);
221          case AFTERLAST:
222             return last();
223          case BEFOREFIRST:
224             return false;
225          default:
226             if (!leftIterator.previous()) {
227                state = BEFOREFIRST;
228                return false;
229             }
230             if (!rightIterator.previous()) {
231                state = BEFOREFIRST;
232                return false;
233             }
234             return alignBackward();
235       }
236    }
237
238    /**
239     * This method is used to navigate left and right iterators in the forward
240     * direction, till both iterators are aligned to common record.
241     *
242     * DETAILED DOCUMENTAION
243     *
244     * This private method is used to align to a valid common record position
245     * after their current position in the same direction.
246     * Algo:
247     * i. IF both the iterators are currently aligned then returned true.
248     * ii. ELse iterator with smaller values 'll seek relatively to the other iterator.
249     * iii. Step ii 'll keep on repeating untill either any one iterator exausts or reaches
250     * to a common valid record.
251     *
252     * @return true if common record found, false otherwise
253     * @throws DException
254     */

255    protected boolean alignForward() throws DException {
256       Object JavaDoc leftObjectValues = leftIterator.getColumnValues(orderLeftCD);
257       Object JavaDoc rightObjectValues = rightIterator.getColumnValues(orderRightCD);
258       int cmp = compare(leftObjectValues, rightObjectValues);
259       while (cmp != 0) {
260          if (cmp > 0) {
261             if (!seekFromTopRelative(leftObjectValues, rightIterator, orderRightCD, true)) {
262                return false;
263             }
264          } else {
265             if (!seekFromTopRelative(rightObjectValues, leftIterator, orderLeftCD, false)) {
266                return false;
267             }
268          }
269          leftObjectValues = leftIterator.getColumnValues(orderLeftCD);
270          rightObjectValues = rightIterator.getColumnValues(orderRightCD);
271          cmp = compare(leftObjectValues, rightObjectValues);
272       }
273       return true;
274    }
275
276    /**
277     * This method navigates the passed iterator in forward direction till the
278     * iterator is pointed to the record, that has same or larger values as
279     * compared to that of passed values.
280     * @param toCompare values to be compared
281     * @param iterator underlying iterator i.e.
282     * @param references selected column corresponing to left/right iterator
283     * @param leftRight that determines the values to compare belong to left or
284     * right iterator. If the values to be compared belong to left iterator i.e.
285     * to be seeked into right iterator, passed variable is true, false, otherwise.
286     * @return if iterator has required record, false otherwise.
287     * @throws DException
288     */

289    private boolean seekFromTopRelative(Object JavaDoc toCompare, _Iterator iterator, _Reference[] references, boolean leftRight) throws DException {
290       while (iterator.next()) {
291          if (leftRight) {
292             if (compare(toCompare, iterator.getColumnValues(references)) <= 0) {
293                return true;
294             }
295          } else {
296             if (compare(iterator.getColumnValues(references), toCompare) >= 0) {
297                return true;
298             }
299          }
300       }
301       return false;
302    }
303
304    /**
305     * This method is used to navigate left and right iterators in the backward
306     * direction, till both iterators are aligned to common record.
307     *
308     * DETAILED DOCUMENTAION
309     *
310     * This private method is used to align to a valid common record position before their current position in the reverse direction.
311     * Algo:
312     * i. IF both the iterators are currently aligned then returned true.
313     * ii. ELse iterator with larger values 'll reverse seek relatively to the other iterator.
314     * iii. Step ii 'll keep on repeating untill either any one iterator exausts or reaches
315     * to a common valid record.
316     *
317     * @return
318     * @throws DException
319     */

320    protected boolean alignBackward() throws DException {
321       Object JavaDoc leftObjectValues = leftIterator.getColumnValues(orderLeftCD);
322       Object JavaDoc rightObjectValues = rightIterator.getColumnValues(orderRightCD);
323       int cmp = compare(leftObjectValues, rightObjectValues);
324
325       while (cmp != 0) {
326          if (cmp < 0) {
327             try {
328                if (!seekFromBottomRelative(leftObjectValues, rightIterator, orderRightCD, true)) {
329                   return false;
330                }
331             } catch (NullPointerException JavaDoc ex) {
332                throw ex;
333             }
334          } else {
335
336             if (!seekFromBottomRelative(rightObjectValues, leftIterator, orderLeftCD, false)) {
337                return false;
338             }
339          }
340          leftObjectValues = leftIterator.getColumnValues(orderLeftCD);
341          rightObjectValues = rightIterator.getColumnValues(orderRightCD);
342          cmp = compare(leftObjectValues, rightObjectValues);
343
344       }
345       return true;
346    }
347
348    /**
349     * This method navigates the passed iterator in backward direction till the
350     * iterator is pointed to the record, that has same or smaller values as
351     * compared to that of passed values.
352     * @param toCompare values to be compared
353     * @param iterator underlying iterator i.e.
354     * @param references selected column corresponing to left/right iterator
355     * @param leftRight that determines the values to compare belong to left or
356     * right iterator. If the values to be compared belong to left iterator i.e.
357     * to be seeked into right iterator, passed variable is true, false, otherwise.
358     * @return if iterator has required record, false otherwise.
359     * @throws DException
360     */

361    private boolean seekFromBottomRelative(Object JavaDoc toCompare, _Iterator iterator, _Reference[] references, boolean leftRight) throws DException {
362       while (iterator.previous()) {
363          if (leftRight) {
364             if (compare(toCompare, iterator.getColumnValues(references)) >= 0) {
365                return true;
366             }
367          } else {
368             if (compare(iterator.getColumnValues(references), toCompare) <= 0) {
369                return true;
370             }
371          }
372       }
373       return false;
374    }
375
376    /**
377     * This method is used to retrive the KEY of IntersectAllIterator i.e. an
378     * Object array having left iterator keys and right iterator keys.
379     * @return key of intersect all iterator at current record
380     * @throws DException
381     */

382    public Object JavaDoc getKey() throws DException {
383       switch (state) {
384          case INVALIDSTATE:
385          case BEFOREFIRST:
386          case AFTERLAST:
387             throw new DException("DSE4116", null);
388          default:
389             return new Object JavaDoc[] {leftIterator.getKey(), rightIterator.getKey()};
390       }
391    }
392
393    /**
394     * This method is responsible to move iterator to a particular record having
395     * passed key. This method extracts the left and right iterator keys and moves
396     * these left and right iterators corresponding to their keys.
397     * @param kee Key where the iterator to align
398     * @throws DException
399     */

400    public void move(Object JavaDoc kee) throws DException {
401       Object JavaDoc[] key = (Object JavaDoc[]) kee;
402       leftIterator.move(key[0]);
403       rightIterator.move(key[1]);
404    }
405
406    /**
407     * The following methods are used for getting values of current record.
408     * The values of current record are retrieved from the left resultset.
409     */

410    /**
411     * This method is used to retrieve the values of passed references.
412     * @param references reference for which values are to be retrived.
413     * Reference may be column or parameter.
414     * @return NonShared FieldBases denoting the value of References. Non Shared
415     * FieldBases are those for which BufferRange is not shared with some other
416     * FieldBase.
417     * @throws DException
418     */

419    public Object JavaDoc getColumnValues(_Reference[] references) throws DException {
420       int[] indexes = GeneralPurposeStaticClass.getSelectedIndexes(references, leftColumnReferences);
421       _Reference[] leftReferences = GeneralPurposeStaticClass.getReferencesToIndex(indexes, leftColumnReferences);
422       return leftIterator.getColumnValues(leftReferences);
423    }
424
425    /**
426     * This method is used to retrieve the value of passed reference.
427     * @param reference reference for which value is to be retrived.
428     * Reference may be column or parameter.
429     * @return NonShared FieldBase denoting the value of Reference. Non Shared
430     * FieldBases are those for which BufferRange is not shared with some other
431     * FieldBase.
432     * @throws DException
433     */

434    public Object JavaDoc getColumnValues(_Reference reference) throws DException {
435       int index = GeneralPurposeStaticClass.getSelectedColumnIndex(reference, leftColumnReferences);
436       if (index == -1) {
437          return leftIterator.getColumnValues(reference);
438       }
439       _Reference leftReferences = leftColumnReferences[index];
440       return leftIterator.getColumnValues(leftReferences);
441    }
442
443    /**
444     * This method return the shared FieldBases for the passed references. By Shared
445     * FieldBase we mean, BufferRange of FieldBase is shared with other FieldBase
446     * objects.
447     * @param references reference for which values are to be retrived
448     * @return shared field base correspondition to passed column reference
449     * @throws DException
450     */

451    public FieldBase[] fields(_Reference[] references) throws DException {
452       int[] indexes = GeneralPurposeStaticClass.getSelectedIndexes(references, leftColumnReferences);
453       _Reference[] leftReferences = GeneralPurposeStaticClass.getReferencesToIndex(indexes, leftColumnReferences);
454       return leftIterator.fields(leftReferences);
455    }
456
457    /**
458     * This method return the shared FieldBase for the passed reference. By Shared
459     * FieldBase we mean, BufferRange of FieldBase is shared with other FieldBase
460     * objects.
461     * @param references reference for which value is to be retrived
462     * @return shared field base correspondition to passed column reference
463     * @throws DException
464     */

465    public FieldBase field(_Reference reference) throws DException {
466       int index = GeneralPurposeStaticClass.getSelectedColumnIndex(reference, leftColumnReferences);
467       if (index == -1) {
468          return leftIterator.field(reference);
469       }
470       _Reference leftReferences = leftColumnReferences[index];
471       return leftIterator.field(leftReferences);
472    }
473
474    /**
475     * This method is responsible to display the executionPlan of a Select Query.
476     * @return _ExecutionPlan
477     * @throws DException
478     */

479    public _ExecutionPlan getExecutionPlan() throws DException {
480       _ExecutionPlan cplans[] = new _ExecutionPlan[2];
481       cplans[0] = leftIterator.getExecutionPlan();
482       cplans[1] = rightIterator.getExecutionPlan();
483       return new ExecutionPlan("IntersectAllIterator", cplans, null, null, null);
484    }
485
486    /**
487     * This method is responsible to display the iterators hierarchy of a Select Query.
488     * @return ExecutionPlanForBrowser
489     * @throws DException
490     */

491    public ExecutionPlanForBrowser getExecutionPlanForBrowser() throws DException {
492       ExecutionPlanForBrowser cplans[] = new ExecutionPlanForBrowser[2];
493       cplans[0] = leftIterator.getExecutionPlanForBrowser();
494       cplans[1] = rightIterator.getExecutionPlanForBrowser();
495       return new ExecutionPlanForBrowser("InterSect All", "Intersect All Iterator", cplans, null, null, null);
496    }
497
498    /**
499     * This method compares the selected column values got from left iterator
500     * with that of from right iterator.
501     * @param object1 values from left iterator
502     * @param object2 values from right iterator
503     * @return 0 if both are same
504     * >0 if object1 > object2
505     * <0 otherwise.
506     * @throws DException
507     */

508    protected int compare(Object JavaDoc object1, Object JavaDoc object2) throws DException {
509       int cmp = comparator.compare(object1, object2);
510       return cmp;
511    }
512
513    /**
514     * This method is used to release the resources releated with the particular
515     * parameters. For e.g comparators. The call to release resouces is delegated
516     * to both underlying iterators.
517     * @throws DException
518     */

519    public void releaseResource() throws DException {
520       leftIterator.releaseResource();
521       rightIterator.releaseResource();
522       /*Done by vibha to solve bug no 11497 on 26-08-2004*/
523    }
524
525    /**
526     * This method is used to get the lowest level iterator.
527     * @param column column corresponding to which iterator is to return.
528     * @return same iterator.
529     * @throws DException
530     */

531    public _Iterator getBaseIterator(ColumnDetails column) throws DException {
532       return this;
533    }
534
535    /**
536     * The following method transfer the call to left iterator. These method
537     * perform the functioning on the left result set.
538     */

539    /**
540     * Initializes the tables corresponding to right iterator. And returns the
541     * names of the tables involved in the set operation.
542     * @return tables involved in set operaton.
543     * @throws DException
544     */

545    public TableDetails[] getTableDetails() throws DException {
546       rightIterator.getTableDetails();
547       return leftIterator.getTableDetails();
548    }
549
550    public void setKeyCount(Object JavaDoc[][] tableAndKeyCount) throws DException {
551       leftIterator.setKeyCount(tableAndKeyCount);
552    }
553
554    public _KeyColumnInformation[] getKeyColumnInformations() throws DException {
555       return leftIterator.getKeyColumnInformations();
556    }
557
558    /**
559     * The following methods of this class are used a intermediate in the
560     * iterator hierarchy. These methods simply transfer the call to the
561     * underlying iterator with the same arguments.
562     */

563    public Object JavaDoc[] getUniqueColumnReference() throws DException {
564       return leftIterator.getUniqueColumnReference();
565    }
566
567    public boolean seekFromTopRelative(Object JavaDoc parm1) throws DException {
568       return leftIterator.seekFromTopRelative(parm1) ? rightIterator.seekFromTopRelative(parm1) : false;
569    }
570
571    public boolean seekFromBottomRelative(Object JavaDoc parm1) throws DException {
572       return leftIterator.seekFromBottomRelative(parm1) ? rightIterator.seekFromBottomRelative(parm1) : false;
573    }
574
575    public _OrderCount getOrderCounts() throws DException {
576       rightIterator.getOrderCounts(); // to initialize the OrderCount in RightIterator
577
return (orderCount = leftIterator.getOrderCounts());
578    }
579
580    public boolean seek(Object JavaDoc parm1) throws DException {
581       return GeneralPurposeStaticClass.seek(parm1, leftIterator, rightIterator);
582    }
583
584    public String JavaDoc toString() {
585       return " IntersectAllIterator [" + leftIterator + "] [" + rightIterator + "]";
586    }
587
588   public byte[] getByteKey() throws DException {
589     switch(state){
590       case INVALIDSTATE:
591       case BEFOREFIRST:
592       case AFTERLAST:
593         throw new DException("", null);
594       default :
595         byte[] leftKey = leftIterator.getByteKey();
596         byte[] rightKey = rightIterator.getByteKey();
597         short leftLen = (short)leftKey.length;
598         byte[] resultantKeys = new byte[leftKey.length+rightKey.length+2];
599         System.arraycopy(CCzufDpowfsufs.getBytes(leftLen),0,resultantKeys,0,2);
600         System.arraycopy(leftKey,0,resultantKeys,2,leftKey.length);
601         System.arraycopy(rightKey,0,resultantKeys,leftKey.length+2,rightKey.length);
602         return resultantKeys;
603     }
604   }
605
606   public void moveByteKey(byte[] key) throws DException {
607     short leftLen =CCzufDpowfsufs.getShortValue(key,0);
608     byte[] leftKeys = new byte[leftLen];
609     byte[] rightKeys = new byte[key.length-leftKeys.length-2];
610     System.arraycopy(key,2,leftKeys,0,leftKeys.length);
611     System.arraycopy(key,leftLen+2,rightKeys,0,rightKeys.length);
612     leftIterator.moveByteKey(leftKeys);
613     rightIterator.move(rightKeys);
614   }
615
616   public void setSpecificUnderlyingReferences(_Reference[] specificUnderlyingReferences) throws DException{
617     throw new java.lang.UnsupportedOperationException JavaDoc("Method setSpecificUnderlyingReferences(_Reference[]) not yet implemented.");
618   }
619
620
621 }
622
Popular Tags