KickJava   Java API By Example, From Geeks To Geeks.

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


1 package com.daffodilwoods.daffodildb.server.sql99.dql.iterator.set;
2
3 import com.daffodilwoods.daffodildb.client.*;
4 import com.daffodilwoods.daffodildb.server.sql99.common.*;
5 import com.daffodilwoods.daffodildb.server.sql99.dql.execution.*;
6 import com.daffodilwoods.daffodildb.server.sql99.dql.iterator.*;
7 import com.daffodilwoods.daffodildb.server.sql99.utils.*;
8 import com.daffodilwoods.daffodildb.utils.comparator.*;
9 import com.daffodilwoods.daffodildb.utils.field.*;
10 import com.daffodilwoods.database.resource.*;
11 import com.daffodilwoods.database.utility.*;
12 import com.daffodilwoods.daffodildb.server.datasystem.indexsystem.
13
    TableKeyColumnInformation;
14 import com.daffodilwoods.daffodildb.utils.byteconverter.CCzufDpowfsufs;
15
16 /**
17  *
18  * <p>Title: UnionAllOrderedIterator </p>
19  * <p>This class is used for retrieval of records from a query having UNION ALL
20  * set operator and ORDER BY clause. UNION ALL set operator returns all the
21  * records from both the underlying iterators acc. to the order given in select
22  * query. In UNION ALL ORDERED Iterator, records from both iterator are compared,
23  * all records are retrived in the specified order. </p>
24  *
25  *
26  * <p>This class is meant for merging and retrieval of the combined result for <UNION Clause>
27  * set Operator with orderBy clause specified.. By Default UNION means UNION ALL, which states
28  * that all the records from both
29  * the underlying iterators 'll be returned .With the presence of the order By Clause All the records 'll
30  * be arranged in the specified order.
31  * In UNION ALL Iterator, all records of left iterator is retrieved, thereafter all records of right
32  * iterator shall be retrieved. This Iterator 'll further maintain the order specified.
33  * </p>
34  * <p>Copyright: Copyright (c) 2003</p>
35  * <p>Company: </p>
36  * @author unascribed
37  * @version 1.0
38  */

39
40 public class UnionAllOrderedIterator
41     extends BaseJoinIterator
42     implements SimpleConstants {
43
44   /**
45    * Selected columns from the left iterator
46    */

47   protected _Reference[] leftColumnReferences; //selected References from LeftIterator
48

49   /**
50    * Selected columns from the right iterator
51    */

52   protected _Reference[] rightColumnReferences; //selected References from RightIterator
53

54   /**
55    * Columns of left iterator involved in oreder by clause
56    */

57   protected _Reference[] orderLeftCD;
58
59   /**
60    * Columns of right iterator involved in oreder by clause
61    */

62   protected _Reference[] orderRightCD;
63
64   /**
65    * The comparator that is used to compare the selected column values
66    * of current record from left iterator with that of right iterator.
67    */

68   protected SuperComparator comparator;
69
70   /**
71    * Variable representing the fetching direction, true, while navigating
72    * top to bottom, false otherwise.
73    */

74   protected int direction; // -1 BACKWARD, 0 UNINITIALIZED, 1 FORWARD
75

76   /**
77    * An array representing data types of selected columns of resultant iterator
78    */

79   protected int[] appropriateDataTypes;
80
81   /**
82    * An array representing sizes of selected columns of resultant iterator
83    */

84   protected int[] appropriateSizes;
85
86   /**
87    * An array representing the values of the record from the left iterator
88    * which will be converted into their promoted data type
89    */

90   private boolean[] leftConversion;
91
92   /**
93    * An array representing the values of the record from the right iterator
94    * which will be converted into their promoted data type
95    */

96   private boolean[] rightConversion;
97
98   public UnionAllOrderedIterator(_Iterator leftIterator,
99                                  _Iterator rightIterator,
100                                  _Reference[] leftColumnReferences0,
101                                  _Reference[] rightColumnReferences0,
102                                  int[] appropriateDataTypes0,
103                                  int[] appropriateSizes0,
104                                  _Reference[] orderLeftCD0,
105                                  _Reference[] orderRightCD0) throws DException {
106     super(leftIterator, rightIterator);
107     leftColumnReferences = leftColumnReferences0;
108     rightColumnReferences = rightColumnReferences0;
109     appropriateDataTypes = appropriateDataTypes0;
110     appropriateSizes = appropriateSizes0;
111     orderLeftCD = orderLeftCD0;
112     orderRightCD = orderRightCD0;
113   }
114
115   /**
116    * A public constructor, that takes five arguments, two are left and right iterators, and
117    * other two are left and right side selected column References. A comparator is also provided for the
118    * purpose of comparison.
119    *
120    * A state is also maintained, that specifies the current status of the current level iterator(this).
121    *
122    * The State INVALIDSTATE means iterator is not aligned properly and needs to be aligned
123    * before doing any further operations.
124    *
125    * The State VALIDSTATE means iterator is aligned properly and can be moved next()/ previous()
126    * as well as values can also be retrieved
127    *
128    * The State BEFOREFIRST means, iterator has reached before the first record or there is no record in the result set.
129    * Iterator is not aligned properly and needs to be aligned through calling first()/ last() before doing any further operations.
130    *
131    * The State AFTERLAST means, iterator has reached after the last record or there is no record in the result set.
132    * Iterator is not aligned properly and needs to be aligned through calling first()/ last() before doing any further operations.
133    *
134    * The State FIRSTISCURRENT means, left iterator is the current iterator and is ready to provide the value for the current row.
135    *
136    * The State SECONDISCURRENT means, right iterator is the current iterator and is ready to provide the value for the current row.
137    *
138    * @param leftIterator0
139    * @param rightIterator0
140    * @param leftColumnReferences0
141    * @param rightColumnReferences0
142    */

143   public UnionAllOrderedIterator(_Iterator leftIterator,
144                                  _Iterator rightIterator,
145                                  _Reference[] leftColumnReferences0,
146                                  _Reference[] rightColumnReferences0,
147                                  SuperComparator comparator0,
148                                  int[] appropriateDataTypes0,
149                                  int[] appropriateSizes0,
150                                  _Reference[] orderLeftCD0,
151                                  _Reference[] orderRightCD0) throws DException {
152     super(leftIterator, rightIterator);
153     leftColumnReferences = leftColumnReferences0;
154     rightColumnReferences = rightColumnReferences0;
155     comparator = comparator0;
156     appropriateDataTypes = appropriateDataTypes0;
157     appropriateSizes = appropriateSizes0;
158     orderLeftCD = orderLeftCD0;
159     orderRightCD = orderRightCD0;
160   }
161
162   boolean flag = false;
163
164   /**
165    * This method is responsible for retriving first record of Union Iterator.
166    * First record is retrived from first and second iterator and a flag is
167    * maintained that represents that whether first or second iterator is
168    * CURRENT iterator (Iterator for which, values of selected columns is
169    * smaller than that of other iterator). For equal values, state is set
170    * to BOTHHAVESAMEDATA. If either of the iterator has no data, flag is
171    * initialized to ONLYFIRSTHASDATA or ONLYSECONDHASDATA accordingly.
172    *
173    * DETAILED DOCUMENTATION
174    *
175    * FIRST this method aligns the iterator to its first valid record.
176    * Algo :::
177    * the direction is initialized as FORWARD.
178    * then we call the first of both the iterators
179    * if both are true then we compare the values and the one with the smaller value is set as current.
180    * if the first of the first iterator is true and the first of the second iterator is true then the
181    * state is set as ONLYFIRSTHASDATA.
182    * else if the first of the second iterator is true
183    * state is set as ONLYSECONDHASDATA.
184    * else if both are false then the state is set as AFTERLAST.
185    *
186    * @return true if either of the iterator has record, false, if none of the
187    * iterator has records.
188    * @throws DException
189    */

190   public boolean first() throws DException {
191     direction = FORWARD;
192     boolean leftFlag = leftIterator.first();
193     boolean rightFlag = rightIterator.first();
194     state = leftFlag ? rightFlag ?
195         compare(leftIterator.getColumnValues(orderLeftCD),
196                 rightIterator.getColumnValues(orderRightCD)) <= 0 ?
197         FIRSTISCURRENT : SECONDISCURRENT
198         : ONLYFIRSTHAVEDATA
199         : rightFlag ? ONLYSECONDHAVEDATA
200         : AFTERLAST;
201     return state != AFTERLAST;
202   }
203
204   /**
205    * This method is responsible for retriving last record of Union Iterator.
206    * Last record is retrived from first and second iterator and a flag is
207    * maintained that represents that whether first or second iterator is
208    * CURRENT iterator (Iterator for which, values of selected columns is
209    * larger than that of other iterator). For equal values, state is set
210    * to BOTHHAVESAMEDATA. If either of the iterator has no data, flag is
211    * initialized to ONLYFIRSTHASDATA or ONLYSECONDHASDATA accordingly.
212    *
213    * DETAILED DOCUMENTATION
214    *
215    * The direction flag is set as BACKWARD
216    * ALGO::
217    * calls the last of both the iterators.
218    * if last of both iterator are true
219    * then the one with the larger value is set as current.
220    * if either is false then the state is set as ONLYFIRSTHASDATA or ONLYSECONDHASDATA accordingly.
221    * if neither is true then the state is set as BEFOREFIRST
222    * if the state is BEFOREFIRST then we return false.
223    * @return true if either of the iterator has record, false, if none of the
224    * iterator has records.
225    * @throws DException
226    */

227   public boolean last() throws DException {
228     direction = BACKWARD;
229     boolean leftFlag = leftIterator.last();
230     boolean rightFlag = rightIterator.last();
231     state = leftFlag ? rightFlag ?
232         compare(leftIterator.getColumnValues(orderLeftCD),
233                 rightIterator.getColumnValues(orderRightCD)) <= 0 ?
234         SECONDISCURRENT : FIRSTISCURRENT
235         : ONLYFIRSTHAVEDATA
236         : rightFlag ? ONLYSECONDHAVEDATA
237         : BEFOREFIRST;
238     return state != BEFOREFIRST;
239   }
240
241   /**
242    * This method is responsible for retriving next record of Union Iterator.
243    * 1. If the state denotes that one of the iterator is current. Next
244    * record is retrived from CURRENT iterator. Goto 3.
245    * 2. If the state is BOTHHAVESAMEDATA, Next record is retrived from
246    * both of the underlying iterators. Goto 3
247    * 3. Compare the values of selected columns, Make one of iterator to CURRENT,
248    * which has smaller values of selected columns as compared to that of other
249    * iterator and update the state acc. to compare result.
250    * 4. If state is ONLYFIRSTHASDATA or ONLYSECONDHASDATA it means only one of
251    * the iterator has data that must be navigated in forward direction to
252    * retrieve next record.
253    *
254    * For forward fetching after backward fetching (if last or previous method
255    * has called before call to next method), special handing has been done.
256    * Both underlying iterators are navigated in such a way that produce state
257    * of both underlying iterators as same as that of before call to backward
258    * fetching method (last or previous method). In backward fetching, records
259    * from the iterator having larger values of selected columns are returned
260    * first, if any one of the iterator has no records, it's last record's values
261    * are compared with that of the selected column values of the another iterator.
262    * Larger Values must be returned first. Hence, the iterator having smaller
263    * values is navigated back(next method called) to its previous state. Thus,
264    * maintaining the previous state of both underlying iterators and returning
265    * the appropriate selected columns values.
266    *
267    * DETAILED DOCUMENTATION
268    *
269    * This method aligns the iterator to the next valid record. The data has to be
270    * ordered thus the record selected should be the smaller of the values of the
271    * values of the left and right iterator.
272    * Special cases that involve mixed fetching such as next after previous or previous after next;
273    * in such cases we need to make sure that the iterator is restored to the state it was in before next is called.
274    * First we check what is the current state of the iterator:
275    * INVALIDSTATE : then throws exception
276    * BEFOREFIRST : then align the iterator to the first record.
277    * AFTERLAST : returns false as there is no next record.
278    * ONLYFIRSTHAVEDATA : this state means that only the first iterator has data and the second iterator is in invalid state.
279    * we check the direction of navigation
280    * if it is backward i.e. it is the case of mixed feching
281    * in this case we call the method iteratePositiveAfterNegativeWhenOneHasData
282    * else
283    * then the direction is reversed i.e.set to FORWARD.
284    * we call the next of the first iterator and set the state appropriately.
285    * ONLYSECONDHAVEDATA :
286    * if the direction = BACKWARD
287    * we call the method iteratePositiveAfterNegativeWhenOneHasData
288    * else
289    * then the direction is reversed i.e.set to FORWARD.
290    * we call the next of the second iterator and set the state accordingly.
291    * FIRSTISCURRENT :
292    * if the direction is backward then
293    * call the method iteratePositiveAfterNegativeWhenOneIsCurrent
294    * else
295    * call the method iteratePositive
296    * SECONDISCURRENT :
297    * if the direction is backward then
298    * call the method iteratePositiveAfterNegativeWhenOneIsCurrent
299    * else
300    * call the method iteratePositive
301    *
302    * @return true if either of the iterator has more record in same forward
303    * navigation, false, otherwise.
304    * @throws DException
305    */

306   public boolean next() throws DException {
307     switch (state) {
308       case INVALIDSTATE:
309         throw new DException("DSE4116", null);
310       case BEFOREFIRST:
311         return first();
312       case AFTERLAST:
313         return false;
314       case ONLYFIRSTHAVEDATA:
315         if (direction == BACKWARD) {
316           return iteratePositiveAfterNegativeWhenOneHasData(leftIterator,
317               rightIterator, orderLeftCD, orderRightCD);
318         }
319         direction = FORWARD;
320         boolean flag = leftIterator.next();
321         state = flag ? state : AFTERLAST;
322         return flag;
323       case ONLYSECONDHAVEDATA:
324         if (direction == BACKWARD) {
325           return iteratePositiveAfterNegativeWhenOneHasData(rightIterator,
326               leftIterator, orderRightCD, orderLeftCD);
327         }
328         direction = FORWARD;
329         boolean b = rightIterator.next();
330         state = b ? state : AFTERLAST;
331         return b;
332       case FIRSTISCURRENT:
333         if (direction == BACKWARD) {
334           return iteratePositiveAfterNegativeWhenOneIsCurrent(leftIterator,
335               rightIterator, orderLeftCD, orderRightCD);
336         }
337         return iteratePositive(leftIterator, rightIterator, 1, orderLeftCD,
338                                orderRightCD);
339       case SECONDISCURRENT:
340         if (direction == BACKWARD) {
341           return iteratePositiveAfterNegativeWhenOneIsCurrent(rightIterator,
342               leftIterator, orderRightCD, orderLeftCD);
343         }
344         return iteratePositive(rightIterator, leftIterator, -1, orderRightCD,
345                                orderLeftCD);
346     }
347     return false;
348   }
349
350   /**
351    * This method is responsible to navigate one of the underlying iterator in
352    * forward direction, when both of the underlying iterators have data but
353    * one of the iterator is current. The purpose of this method is to navigate
354    * current iterator in forward direction and to compare the selected column
355    * values with that of another iterator and to update the state correspondingly.
356    * If there are no records in current iterator, state is set to ONLYFIRSTHASDATA
357    * or ONLYSECONDHASDATA accordingly.
358    *
359    * DETAILED DOCUMENTAION
360    *
361    * This method is called by next.
362    * Firstly it sets the direction of navigation equal to FORWARD.
363    * It then gets the current values from the current iterator.
364    * It then calls the next of the current iterator.
365    * If the next of the current iterator is false
366    * then we set the state accordingly.
367    * i.e. if the first iterator is current then the state would be ONLYSECONDHASDATA
368    * or if the second iterator is current then the state would be ONLYFIRSTHASDATA.
369    * else
370    * we get the record from the current iterator and from the other iterator.
371    * the iterator with the smaller value is set as current.
372    * @usage assistance in next method for forward direction fetching
373    * @param currentIterator current iterator
374    * @param otherIterator other iterator which is not current
375    * @param reverse {1 or -1} 1 when left iterator is current, -1 when
376    * right iterator is current.
377    * @param currentReferences given selected columns of current iterator
378    * @param otherReferences given selected columns of other iterator
379    * @return TRUE
380    * @throws DException
381    */

382   private boolean iteratePositive(_Iterator currentIterator,
383                                   _Iterator otherIterator, int reverse,
384                                   _Reference[] currentReferences,
385                                   _Reference[] otherReferences) throws
386       DException {
387     direction = FORWARD;
388     Object JavaDoc toCompare = currentIterator.getColumnValues(currentReferences);
389     boolean flag = currentIterator.next();
390     if (!flag) {
391       state = reverse == 1 ? ONLYSECONDHAVEDATA : ONLYFIRSTHAVEDATA;
392       return true;
393     }
394     Object JavaDoc first = currentIterator.getColumnValues(currentReferences);
395     Object JavaDoc second = otherIterator.getColumnValues(otherReferences);
396     state = reverse == 1 ? compare(first, second) <= 0 ? FIRSTISCURRENT :
397         SECONDISCURRENT
398         : compare(second, first) <= 0 ? FIRSTISCURRENT : SECONDISCURRENT;
399     return true;
400
401   }
402
403   /**
404    * This method is called by next when the state is FIRSTISCURRENT and
405    * previously fetching direction was backward (previous or last called).
406    * Next record is retrieved from both of the underlying iterator. The
407    * previous of underlying iterator is called which has larger values of
408    * selected columns to maintain the previous state of the both underlying
409    * iterators, since larger values will be returned if the next is called
410    * again. If both values are same, state is set to BOTHHAVESAMEDATA.
411    *
412    * DETAILED DOCUMENTATION
413    *
414    * First the next of both iterators is called.
415    * if both are true then
416    * we get the values from both iterators
417    * if the values are equal then
418    * state is set as FIRSTISCURRENT and the previous of the other iterator is called.
419    * else
420    * the value we set the iterator with the smaller value as CURRENT and we call the previous of the other iterator.
421    * if the next of the current iterator is true then
422    * call the last of the other iterator
423    * if the iterator is true then
424    * call the last of the current and set the state the other iterator is current.
425    * else
426    * set the state as AFTERLAST.
427    * @usage assistance in next method when fetching direction
428    * changes from backward to forward
429    * @param currentIterator current iterator
430    * @param otherIterator other iterator which is not current
431    * @param currentReferences given selected columns of current iterator
432    * @param otherReferences given selected columns of other iterator
433    * @return FALSE if both underlying iterator has no nore records, true otherwise.
434    * @throws DException
435    */

436   private boolean iteratePositiveAfterNegativeWhenOneIsCurrent(_Iterator
437       currentIterator, _Iterator otherIterator, _Reference[] currentReferences,
438       _Reference[] otherReferences) throws DException {
439     boolean currentNext = currentIterator.next();
440     boolean otherNext = otherIterator.next();
441     if (currentNext && otherNext) {
442       Object JavaDoc currentObject = currentIterator.getColumnValues(currentReferences);
443       Object JavaDoc otherObject = otherIterator.getColumnValues(otherReferences);
444       int cmp = compare(currentObject, otherObject);
445       if (cmp == 0) {
446         cmp = state; // If Left is current then cmp = 1 and we want Previus of Other.
447
} // If Right is current then cmp = -1 and we want Previous of Current and state to FIRSTISCURRENT
448
if (cmp > 0) {
449         state = -state;
450         currentIterator.previous();
451       }
452       else {
453         otherIterator.previous();
454       }
455     }
456     else if (currentNext) {
457       otherIterator.last();
458     }
459     else if (otherNext) {
460       currentIterator.last();
461       state = -state;
462     }
463     else {
464       state = AFTERLAST;
465       return false;
466     }
467     return true;
468   }
469
470   /**
471    * This method is called by next in the case of mixed fetching when next
472    * method is called after previous method and state of iterator corresponds
473    * to case when only one of the iterator has data. Other iterator's selected
474    * column values of first record will be checked with that of next record of
475    * current iterator. If the other iterator's first record will have smaller
476    * values, these values must be returned first, hence, it is made as current
477    * iterator and current iterator is navigated revert back to previous state,
478    * otherwise, state remains to ONEISCURRENT (FIRST or SECOND same as before)
479    * and other iterator is set back to before first.
480    *
481    * DETAILED DOCUMENTATION
482    *
483    * In such cases the state after as only the first iterator has data it's next
484    * is called and the first of the second is called.
485    * if both return true.
486    * then get the values from the first and second iterator then
487    * these values are compared.
488    * if the values are same then
489    * the state is set to FIRSTISCURRENT and we call the previous of the second iterator.this restores the iterator to its previous position
490    * else
491    * the iterator with the smaller value is set a current and the previous of the other iterator is called.
492    * else if the next of the current is true then
493    * set state as ONLYFIRSTHASDATA or ONLYSECONDHASDATA
494    * else if the first of the second iterator is true then
495    * last of the current is called and the state is set as SECONDISCURRENT
496    * else
497    * state is AFTERLAST
498    *
499    * @usage assistance in next method when fetching direction
500    * changes from backward to forward
501    * @param currentIterator current iterator
502    * @param otherIterator other iterator which is not current
503    * @param currentReferences given selected columns of current iterator
504    * @param otherReferences given selected columns of other iterator
505    * @return FALSE if current iterator has no more records, true otherwise.
506    * @throws DException
507    */

508   private boolean iteratePositiveAfterNegativeWhenOneHasData(_Iterator
509       currentIterator, _Iterator otherIterator, _Reference[] currentReferences,
510       _Reference[] otherReferences) throws DException {
511     boolean currentNext = currentIterator.next();
512     boolean otherFirst = otherIterator.first();
513     if (currentNext && otherFirst) {
514       Object JavaDoc currentObject = currentIterator.getColumnValues(currentReferences);
515       Object JavaDoc otherObject = otherIterator.getColumnValues(otherReferences);
516       int cmp = compare(currentObject, otherObject);
517       if (cmp == 0) {
518         cmp = state; // If Left is current then cmp = 1 and we want Previous of Other.
519
} // If Right is current then cmp = -1 and we want Previous of Current and state to FIRSTISCURRENT
520
if (cmp > 0) {
521         state = state == ONLYSECONDHAVEDATA ? FIRSTISCURRENT
522             : state == ONLYFIRSTHAVEDATA ? SECONDISCURRENT : state;
523         currentIterator.previous();
524       }
525       else {
526         otherIterator.previous();
527       }
528     }
529     else if (currentNext) {
530     }
531     else if (otherFirst) {
532       currentIterator.last();
533       state = state == ONLYSECONDHAVEDATA ? FIRSTISCURRENT
534           : state == ONLYFIRSTHAVEDATA ? SECONDISCURRENT : state;
535     }
536     else {
537       state = AFTERLAST;
538       return false;
539     }
540     return true;
541   }
542
543   /**
544    * This method is responsible for retriving previous record of Union Iterator.
545    * 1. If the state denotes that one of the iterator is current. Previous
546    * record is retrived from CURRENT iterator. Goto 3.
547    * 2. If the state is BOTHHAVESAMEDATA, previous record is retrived from
548    * both of the underlying iterators. Goto 3
549    * 3. Compare the values of selected columns, Make one of iterator to CURRENT,
550    * which has larger values of selected columns as compared to that of other
551    * iterator) and update the state acc. to compare result.
552    * 4. If state is ONLYFIRSTHASDATA or ONLYSECONDHASDATA it means only one of
553    * the iterator has data which must be navigated in backward direction to
554    * retrieve previous record.
555    *
556    * For backward fetching after forward fetching (if first or next method
557    * has called before call to previous method),special handing has been done.
558    * Both underlying iterators are navigated in such a way to produce the same
559    * state of both underlying iterators as that of before call to forwards fetching
560    * method (first or next method) . In forward fetching records from the
561    * iterator having smaller values of selected columns are returned, if any one
562    * of the iterator has no records, it's first record's selected column values
563    * are compared with that of the selected column values of the another iterator.
564    * Smaller Values must be returned first. Hence, the iterator having larger
565    * values is navigated back(previous method called) to its previous state.
566    * Thus, maintaining the previous state of both underlying iterators and
567    * returning the appropriate selected columns values.
568    *
569    * DETAILED DOCUMENTATION
570    *
571    * This method is meant to align the iterator to the record previous to the current record.
572    * if the current state is
573    * INVALIDSTATE : then throw an exception
574    * BEFOREFIRST : the return false.
575    * AFTERLAST : then call the last method.
576    * ONLYFIRSTHASDATA :
577    * if the direction is FORWARD i.e. it is a case of mixed fetching. then
578    * call the iterateNegativeAfterPositiveWhenOneHasData
579    * else
580    * change the direction of navigation to BACKWRD and call the previous of the leftiterator.
581    * ONLYSECONDHASDATA : similar to the above case.
582    * FIRSTISCURRENT :
583    * if it is a case of mixed fetching then
584    * call the iterateNegativeAfterPositiveWhenOneIsCurrent method.
585    * else call the iteratePositive
586    * SECONFISCURRENT :
587    * similar to the above case.
588    *
589    * @return true if either of the iterator has more record in same backward
590    * navigation, false, otherwise.
591    * @throws com.daffodilwoods.database.resource.DException
592    */

593   public boolean previous() throws com.daffodilwoods.database.resource.
594
      DException {
595     switch (state) {
596       case INVALIDSTATE:
597         throw new DException("DSE4117", null);
598       case BEFOREFIRST:
599         return false;
600       case AFTERLAST:
601         return last();
602       case ONLYFIRSTHAVEDATA:
603         if (direction == FORWARD) {
604           return iterateNegativeAfterPositiveWhenOneHasData(leftIterator,
605               rightIterator, orderLeftCD, orderRightCD);
606         }
607         direction = BACKWARD;
608         boolean flag = leftIterator.previous();
609         state = flag ? state : BEFOREFIRST;
610         return flag;
611       case ONLYSECONDHAVEDATA:
612         if (direction == FORWARD) {
613           return iterateNegativeAfterPositiveWhenOneHasData(rightIterator,
614               leftIterator, orderRightCD, orderLeftCD);
615         }
616         direction = BACKWARD;
617         boolean b = rightIterator.previous();
618         state = b ? state : BEFOREFIRST;
619         return b;
620       case FIRSTISCURRENT:
621         if (direction == FORWARD) {
622           return iterateNegativeAfterPositiveWhenOneIsCurrent(leftIterator,
623               rightIterator, orderLeftCD, orderRightCD);
624         }
625         return iterateNegative(leftIterator, rightIterator, 1, orderLeftCD,
626                                orderRightCD);
627       case SECONDISCURRENT:
628         if (direction == FORWARD) {
629           return iterateNegativeAfterPositiveWhenOneIsCurrent(rightIterator,
630               leftIterator, orderRightCD, orderLeftCD);
631         }
632         return iterateNegative(rightIterator, leftIterator, -1, orderRightCD,
633                                orderLeftCD);
634     }
635     return false;
636   }
637
638   /**
639    * This method is called by previous in the case of mixed fetching when
640    * previous method is called after next method and state of iterator corresponds
641    * to case when only one of the iterator has data. Other iterator's selected
642    * column values of last record will be checked with that of previous record of
643    * current iterator. If the other iterator's last record will have larger
644    * values, these values must be retruned first, hence, it is made as current
645    * iterator and current iterator is navigated revert back to next state,
646    * otherwise, state remains to ONEISCURRENT (FIRST or SECOND same as before)
647    * and other iterator is set after last.
648    *
649    * DETAILED DOCUMENTATION
650    *
651    * This method is meant to align the iterator to a vaild previous record in the case of mixed fetching.
652    * ALGO:::
653    * call the previous of the current iterator and call the last of the other iterator.
654    * if both are true then-
655    * we compare the two values
656    * if the two are equal then
657    * we set the rightiterator as current. and call the next of the other iterator.
658    * else
659    * we set the one with the greater value as current. and call the next of the other iterator.
660    * if the previous of the current iterator is true then
661    * state is set equal to current has data.
662    * else if the last is true then
663    * we call the first of the current and set the other iterator as current.
664    * else if both are false then
665    * we set the state as BEFOREFIRST.
666    *
667    * @usage assistance in previous method when fetching direction
668    * changes from forward to backward
669    * @param currentIterator current iterator
670    * @param otherIterator other iterator which is not current
671    * @param currentReferences given selected columns of current iterator
672    * @param otherReferences given selected columns of other iterator
673    * @return FALSE if current iterator has no more records, true otherwise.
674    * @throws DException
675    */

676   private boolean iterateNegativeAfterPositiveWhenOneHasData(_Iterator
677       currentIterator, _Iterator otherIterator, _Reference[] currentReferences,
678       _Reference[] otherReferences) throws DException {
679     boolean currentPrevious = currentIterator.previous();
680     boolean otherLast = otherIterator.last();
681     if (currentPrevious && otherLast) {
682       Object JavaDoc currentObject = currentIterator.getColumnValues(currentReferences);
683       Object JavaDoc otherObject = otherIterator.getColumnValues(otherReferences);
684       int cmp = compare(currentObject, otherObject);
685       if (cmp == 0) {
686         cmp = state; // If Left is current then cmp = -1 and we want Next of Current and state to SECONDISCURRENT
687
} // If Right is current then cmp = 1 and we want Next of Other.
688
if (cmp < 0) {
689         state = state == ONLYSECONDHAVEDATA ? FIRSTISCURRENT
690             : state == ONLYFIRSTHAVEDATA ? SECONDISCURRENT : state;
691         currentIterator.next();
692       }
693       else {
694         otherIterator.next();
695       }
696     }
697     else if (currentPrevious) {
698     }
699     else if (otherLast) {
700       currentIterator.first();
701       state = state == ONLYSECONDHAVEDATA ? FIRSTISCURRENT
702           : state == ONLYFIRSTHAVEDATA ? SECONDISCURRENT : state;
703     }
704     else {
705       state = BEFOREFIRST;
706       return false;
707     }
708     return true;
709   }
710
711   /**
712    * This method is called by previous when the state is FIRSTISCURRENT and
713    * previously fetching direction was forward (first or next called).
714    * Previous record is retrieved from both of the underlying iterator. The
715    * next of underlying iterator is called which has smaller values of
716    * selected columns to maintain the previous state of the both underlying
717    * iterators, since smaller values will be returned if the previous is called
718    * again. If both values are same, state is set to BOTHHAVESAMEDATA.
719    *
720    * DETAILED DOCUMENTATION
721    *
722    * ALGO ::::
723    * we call the previous of both the iterators
724    * if both are true then
725    * we get both values and compare them.
726    * if both are equal then
727    * right iterator is set as current and then call the next of the other iterator.
728    * else
729    * the iterator with the larger value is set as current and the next of the other iterator is called.
730    * if only the previous of the current is true then
731    * call the first of the other.
732    * else if only the previous of the other iterator is true then
733    * call the first of the current and set the other iterator as current
734    * else if neither is true then
735    * set state equal to BEFOREFIRST
736    * @usage assistance in previous method when fetching direction
737    * changes from forward to backward
738    * @param currentIterator current iterator
739    * @param otherIterator other iterator which is not current
740    * @param currentReferences given selected columns of current iterator
741    * @param otherReferences given selected columns of other iterator
742    * @return FALSE if both underlying iterator has no nore records, true otherwise.
743    * @throws DException
744    */

745   private boolean iterateNegativeAfterPositiveWhenOneIsCurrent(_Iterator
746       currentIterator, _Iterator otherIterator, _Reference[] currentReferences,
747       _Reference[] otherReferences) throws DException {
748     boolean currentPrevious = currentIterator.previous();
749     boolean otherPrevious = otherIterator.previous();
750     if (currentPrevious && otherPrevious) {
751       Object JavaDoc currentObject = currentIterator.getColumnValues(currentReferences);
752       Object JavaDoc otherObject = otherIterator.getColumnValues(otherReferences);
753       int cmp = compare(currentObject, otherObject);
754       if (cmp == 0) {
755         cmp = state; // If Left is current then cmp = -1 and we want Next of Current and state to SECONDISCURRENT
756
} // If Right is current then cmp = 1 and we want Next of Other.
757
if (cmp < 0) {
758         state = -state;
759         currentIterator.next();
760       }
761       else {
762         otherIterator.next();
763       }
764     }
765     else if (currentPrevious) {
766       otherIterator.first();
767     }
768     else if (otherPrevious) {
769       currentIterator.first();
770       state = -state;
771     }
772     else {
773       state = BEFOREFIRST;
774       return false;
775     }
776     return true;
777   }
778
779   /**
780    * This method is responsible to navigate one of the underlying iterator in
781    * backward direction, when both of the underlying iterators have data but
782    * one of the iterator is current. The purpose of this method is to navigate
783    * current iterator in backward direction. If there are no records in current
784    * iterator, state is set to ONLYFIRSTHASDATA or ONLYSECONDHASDATA accordingly.
785    *
786    * DETAILED DOCUMENTAION
787    *
788    * This method is called by the previous method.
789    * ALGO ::::
790    * First the direction of navigation is changed to BACKWARD.
791    * we call the previous of the current iterator
792    * if previous is not true then
793    * set the state as ONLYFIRSTHASDATA or ONLYSECONDHASDATA according to which is current.
794    * else
795    * we get the records from both the iterators and compare them
796    * the one with the larger value is set as current.
797    *
798    * @usage assistance in previous method
799    * @param firstIterator current iterator
800    * @param secondIterator other iterator which is not current
801    * @param reverse {1 or -1} 1 when left iterator is current, -1 when
802    * right iterator is current.
803    * @param firstReferences given selected columns of current iterator
804    * @param secondReferences given selected columns of other iterator
805    * @return TRUE
806    */

807   private boolean iterateNegative(_Iterator firstIterator,
808                                   _Iterator secondIterator, int reverse,
809                                   _Reference[] firstReferences,
810                                   _Reference[] secondReferences) throws
811       DException {
812     direction = BACKWARD;
813     Object JavaDoc toCompare = firstIterator.getColumnValues(firstReferences);
814     int cmp = -1;
815     boolean flag = firstIterator.previous(); // Now firstIterator is at BEFOREFIRST.
816

817     if (!flag) {
818       state = reverse == 1 ? ONLYSECONDHAVEDATA : ONLYFIRSTHAVEDATA;
819       return true;
820     }
821     Object JavaDoc first = firstIterator.getColumnValues(firstReferences);
822     Object JavaDoc second = secondIterator.getColumnValues(secondReferences);
823
824
825     state = reverse == 1 ? compare(first, second) <= 0 ? SECONDISCURRENT :
826         FIRSTISCURRENT
827         : compare(second, first) <= 0 ? SECONDISCURRENT : FIRSTISCURRENT;
828     return true;
829   }
830
831   /**
832    * This method is used to get the KEY of the iterator at particular position.
833    * The Key of union iterator is SetOperatorKey ( Which stores the keys of
834    * both underlying iterators, key is null if there is no data in corresponding
835    * iterator) , state of iterator and fetching direction.
836    * @return Key of Valid record of Union Iterator
837    * @throws DException
838    */

839   public Object JavaDoc getKey() throws DException {
840     switch (state) {
841       case INVALIDSTATE:
842       case BEFOREFIRST:
843       case AFTERLAST:
844         throw new DException("DSE4116", null);
845       case ONLYFIRSTHAVEDATA:
846         return new Object JavaDoc[] {
847             new SetOperatorKey(new Object JavaDoc[] {leftIterator.getKey(), null}
848                                , state, direction)};
849       case ONLYSECONDHAVEDATA:
850         return new Object JavaDoc[] {
851             new SetOperatorKey(new Object JavaDoc[] {null, rightIterator.getKey()}
852                                , state, direction)};
853       case FIRSTISCURRENT:
854       case SECONDISCURRENT:
855       case BOTHHAVESAMEDATA:
856         return new Object JavaDoc[] {
857             new SetOperatorKey(new Object JavaDoc[] {leftIterator.getKey(),
858                                rightIterator.getKey()}
859                                , state, direction)};
860     }
861     throw new DException("DSE0", new Object JavaDoc[] {"INVALID STATE : " + state});
862   }
863
864   /**
865    * This method is used to move underlying iterators corresponding to key
866    * passed. It extracts the keys of left and right iterators from the passed
867    * key and moves both underlying iterators to corresponding keys.
868    * If extracted keys corresponding to any iterator is NULL, iterator is set
869    * before first/after last in case of backward and forward fetching respecively.
870    * Global variables are also initailized to recreate the state corresponding
871    * to passed key.
872    * @param keys keys on which iterator is required to align
873    * @throws DException
874    */

875   public void move(Object JavaDoc keys) throws DException {
876     SetOperatorKey setKey = (SetOperatorKey) ( (Object JavaDoc[]) keys)[0];
877     state = setKey.getState();
878     direction = setKey.getDirection();
879     Object JavaDoc[] underlyingKeys = setKey.getKeys();
880     Object JavaDoc leftKeys = underlyingKeys[0];
881     Object JavaDoc rightKeys = underlyingKeys[1];
882     if (leftKeys == null) {
883       moveWhenKeyIsNull(leftIterator, direction);
884     }
885     else {
886       leftIterator.move(leftKeys);
887     }
888     if (rightKeys == null) {
889       moveWhenKeyIsNull(rightIterator, direction);
890     }
891     else {
892       rightIterator.move(rightKeys);
893     }
894   }
895
896
897   /**
898    * This method is used in moving to a particular key. If any of the
899    * underlying iterator has no data coresponding to a particular state,
900    * iterator is set after last and before first if the fetching direction
901    * is forward and backward, respectively.
902    * @param iterator underlying iterator to align
903    * @param direction target fetching direction
904    * @throws DException
905    */

906   private void moveWhenKeyIsNull(_Iterator iterator, int direction) throws
907       DException {
908     if (direction == FORWARD) {
909       if (iterator.last()) {
910         iterator.next();
911       }
912     }
913     else if (direction == BACKWARD) {
914       if (iterator.first()) {
915         iterator.previous();
916
917       }
918     }
919   }
920
921   /**
922    * The following methods are used for getting values of current record.
923    * The values of record are retrived after converting the values into
924    * new values of resultant data type and sizes. For optimisation purpose,
925    * an array of flags is maintained to denote whether the conversion is
926    * required for the particular value of particular record from either of
927    * the underlying iterator.
928    */

929   /**
930    * This method is used to retrieve the value of passed reference.
931    * @param reference reference for which value is to be retrived.
932    * Reference may be column or parameter.
933    * @return NonShared FieldBase denoting the value of Reference. Non Shared
934    * FieldBases are those for which BufferRange is not shared with some other
935    * FieldBase.
936    * @throws DException
937    */

938   public Object JavaDoc getColumnValues(_Reference references) throws DException {
939     int index = -9;
940     Object JavaDoc result = null;
941     try {
942       index = GeneralPurposeStaticClass.getSelectedColumnIndex(references,
943           leftColumnReferences);
944       if (state <= 0) {
945         return result = leftConversion != null ?
946             convertToAppDataTypes(leftIterator.getColumnValues(references),
947                                   index, leftConversion) :
948             leftIterator.getColumnValues(references);
949       }
950       if (index == -1) { // index = -1 in case when value for__rowid column is needed. In case of order above this Iterator
951
return result = rightConversion != null ?
952             convertToAppDataTypes(rightIterator.getColumnValues(references),
953                                   index, rightConversion) :
954             rightIterator.getColumnValues(references);
955       }
956
957       return result = rightConversion != null ?
958           convertToAppDataTypes(
959           rightIterator.getColumnValues(rightColumnReferences[index]), index,
960           rightConversion) :
961           rightIterator.getColumnValues(rightColumnReferences[index]);
962     }
963     finally {
964
965     }
966
967   }
968
969   /**
970    * This method is used to retrieve the all the values of current record.
971    * @return an object array having values of all the records in the form of
972    * NonShared FieldBase denoting the value of Reference. Non Shared
973    * FieldBases are those for which BufferRange is not shared with some other
974    * FieldBase.
975    * @throws DException
976    */

977   public Object JavaDoc getColumnValues() throws DException {
978     if (state <= 0) {
979       return leftConversion != null ?
980           convertToAppDataTypes( (Object JavaDoc[])
981                                 leftIterator.getColumnValues(leftColumnReferences),
982                                 leftConversion) :
983           leftIterator.getColumnValues(leftColumnReferences);
984     }
985     return rightConversion != null ?
986         convertToAppDataTypes( (Object JavaDoc[])
987                               rightIterator.getColumnValues(rightColumnReferences),
988                               rightConversion) :
989         rightIterator.getColumnValues(rightColumnReferences);
990   }
991
992   /**
993    * This method is used to retrieve the values of passed references.
994    * @param references reference for which values are to be retrived.
995    * Reference may be column or parameter.
996    * @return NonShared FieldBases denoting the value of References. Non Shared
997    * FieldBases are those for which BufferRange is not shared with some other
998    * FieldBase.
999    * @throws DException
1000   */

1001  public Object JavaDoc getColumnValues(_Reference[] references) throws DException {
1002
1003    Object JavaDoc result = null;
1004    int indexes[] = GeneralPurposeStaticClass.getSelectedIndexes(references,
1005        leftColumnReferences);
1006    if (state <= 0) {
1007      return result = leftConversion != null ?
1008          convertToAppDataTypes( (Object JavaDoc[])
1009                                leftIterator.getColumnValues(references),
1010                                indexes, leftConversion) :
1011          leftIterator.getColumnValues(references);
1012    }
1013    _Reference[] rightReferences = GeneralPurposeStaticClass.
1014        getReferencesToIndex(indexes, rightColumnReferences);
1015    result = rightConversion != null ?
1016        convertToAppDataTypes( (Object JavaDoc[])
1017                              rightIterator.getColumnValues(rightReferences),
1018                              indexes, rightConversion) :
1019        rightIterator.getColumnValues(rightReferences);
1020    return result;
1021  }
1022
1023  /**
1024   * This method return the shared FieldBase for the passed reference. By Shared
1025   * FieldBase we mean, BufferRange of FieldBase is shared with other FieldBase
1026   * objects.
1027   * @param references reference for which value is to be retrived
1028   * @return shared field base correspondition to passed column reference
1029   * @throws DException
1030   */

1031  public FieldBase field(_Reference references) throws com.daffodilwoods.
1032
      database.resource.DException {
1033    int index = GeneralPurposeStaticClass.getSelectedColumnIndex(references,
1034        leftColumnReferences);
1035    if (state <= 0) {
1036      return leftConversion != null ?
1037          (FieldBase) convertToAppDataTypes(leftIterator.field(references),
1038                                            index, leftConversion) :
1039          leftIterator.field(references);
1040    }
1041    if (index == -1) {
1042      return rightConversion != null ?
1043          (FieldBase) convertToAppDataTypes(rightIterator.field(references),
1044                                            index, rightConversion) :
1045          rightIterator.field(references);
1046    }
1047    return rightConversion != null ?
1048        (FieldBase) convertToAppDataTypes(
1049        rightIterator.field(rightColumnReferences[index]), index,
1050        rightConversion) : rightIterator.field(rightColumnReferences[index]);
1051
1052  }
1053
1054  /**
1055   * This method return the shared FieldBases for the passed references. By Shared
1056   * FieldBase we mean, BufferRange of FieldBase is shared with other FieldBase
1057   * objects.
1058   * @param references reference for which values are to be retrived
1059   * @return shared field base correspondition to passed column reference
1060   * @throws DException
1061   */

1062  public FieldBase[] fields(_Reference[] references) throws com.daffodilwoods.
1063
      database.resource.DException {
1064    if (state <= 0) {
1065      return leftIterator.fields(references);
1066    }
1067    int indexes[] = GeneralPurposeStaticClass.getSelectedIndexes(references,
1068        leftColumnReferences);
1069    _Reference[] rightReferences = GeneralPurposeStaticClass.
1070        getReferencesToIndex(indexes, rightColumnReferences);
1071    return rightIterator.fields(rightReferences);
1072  }
1073
1074  /**
1075   * This method is responsible to covert the passed objects into resultant
1076   * data types and sizes after union opeatiion.
1077   * @param source an array if fieldbases objects to be converted
1078   * @param conversion whether conversion is required or not
1079   * @return an array of required values of selected columns after being
1080   * converted into required datatype and sizes.
1081   * @throws DException
1082   */

1083  public Object JavaDoc convertToAppDataTypes(Object JavaDoc[] source, boolean[] conversion) throws
1084      DException {
1085    int length = source.length;
1086    Object JavaDoc[] result = new Object JavaDoc[length];
1087    for (int i = 0; i < result.length; i++) {
1088      result[i] = convertToAppDataTypes(source[i], i, conversion);
1089    }
1090    return result;
1091  }
1092
1093  public Object JavaDoc convertToAppDataTypes(Object JavaDoc[] source, int[] indexes,
1094                                      boolean[] conversion) throws DException {
1095    int length = source.length;
1096    Object JavaDoc[] result = new Object JavaDoc[length];
1097    for (int i = 0; i < result.length; i++) {
1098      try {
1099        result[i] = convertToAppDataTypes(source[i], indexes[i], conversion);
1100      }
1101      catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
1102        throw ex;
1103      }
1104    }
1105    return result;
1106  }
1107
1108
1109  public Object JavaDoc convertToAppDataTypes(Object JavaDoc source, int index,
1110                                      boolean[] conversion) throws DException {
1111    Object JavaDoc obj = index != -1 && conversion[index] ?
1112        GeneralPurposeStaticClass.
1113        convertToAppropriateType( (FieldBase) source,
1114                                 appropriateDataTypes[index],
1115                                 appropriateSizes[index], null)
1116        : source;
1117    return obj;
1118  }
1119
1120
1121  /**
1122   * This method is responsible to compare the the selected column values
1123   * of current record from left iterator with that of current record of
1124   * right iterator.
1125   * @param object1 selected column values from left iterator
1126   * @param object2 selected column values from right iterator
1127   * @return 0 if both are same
1128   * >0 if left object is greather than right object
1129   * <0 otherwise.
1130   * @throws DException
1131   */

1132  protected int compare(Object JavaDoc object1, Object JavaDoc object2) throws DException {
1133    try {
1134      int cmp = comparator.compare(object1, object2);
1135      return cmp;
1136    }
1137    catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
1138      throw ex;
1139    }
1140  }
1141
1142  /**
1143   * This method is used to get the lowest level iterator.
1144   * @param column column corresponding to which iterator is to return.
1145   * @return same iterator.
1146   * @throws DException
1147   */

1148  public _Iterator getBaseIterator(ColumnDetails column) throws com.
1149
      daffodilwoods.database.resource.DException {
1150    return this;
1151  }
1152
1153  /**
1154   * This method is responsible to display the executionPlan of a Select Query.
1155   * @return _ExecutionPlan
1156   * @throws DException
1157   */

1158  public _ExecutionPlan getExecutionPlan() throws DException {
1159    _ExecutionPlan cplans[] = new _ExecutionPlan[2];
1160    cplans[0] = leftIterator.getExecutionPlan();
1161    cplans[1] = rightIterator.getExecutionPlan();
1162    return new ExecutionPlan("UnionAllOrderedIterator", cplans, null, null, null);
1163  }
1164
1165  /**
1166   * This method is responsible to display the iterators hierarchy of a Select Query.
1167   * @return ExecutionPlanForBrowser
1168   * @throws DException
1169   */

1170  public ExecutionPlanForBrowser getExecutionPlanForBrowser() throws DException {
1171    ExecutionPlanForBrowser cplans[] = new ExecutionPlanForBrowser[2];
1172    cplans[0] = leftIterator.getExecutionPlanForBrowser();
1173    cplans[1] = rightIterator.getExecutionPlanForBrowser();
1174    return new ExecutionPlanForBrowser("Union All Ordered",
1175                                       "Union All Ordered Iterator", cplans, null, null, null);
1176  }
1177
1178  /**
1179   * The following method transfer the call to left iterator. These method
1180   * perform the functioning on the left result set.
1181   */

1182  /**
1183   * Initializes the tables corresponding to right iterator. And returns the
1184   * names of the tables involved in the set operation.
1185   * @return tables involved in set operaton.
1186   * @throws DException
1187   */

1188  public TableDetails[] getTableDetails() throws com.daffodilwoods.database.
1189
      resource.DException {
1190    rightIterator.getTableDetails();
1191    TableDetails[] array = leftIterator.getTableDetails();
1192    return array;
1193  }
1194
1195  /**
1196   * The following methods of this class are used a intermediate in the
1197   * iterator hierarchy. These methods simply transfer the call to the
1198   * underlying iterator with the same arguments.
1199   */

1200  public _KeyColumnInformation[] getKeyColumnInformations() throws DException {
1201    return leftIterator.getKeyColumnInformations();
1202  }
1203
1204  public Object JavaDoc[] getUniqueColumnReference() throws DException {
1205    return leftIterator.getUniqueColumnReference();
1206  }
1207
1208  public boolean seek(Object JavaDoc indexKey) throws DException {
1209    return GeneralPurposeStaticClass.seek(indexKey, leftIterator, rightIterator);
1210  }
1211
1212  public _OrderCount getOrderCounts() throws com.daffodilwoods.database.
1213
      resource.DException {
1214    rightIterator.getOrderCounts(); // to initialize the OrderCount in RightIterator
1215
return (orderCount = leftIterator.getOrderCounts());
1216  }
1217
1218  public void setOriginalColumnDetails(ColumnDetails[] leftOriginal0,
1219                                       ColumnDetails[] rightOriginal0) throws
1220      DException {
1221    setTableDetailsIfNotMatched(leftOriginal0, rightOriginal0); // Done by Kaushik for Union Problem
1222
leftConversion = getConversionArray(leftOriginal0);
1223    rightConversion = getConversionArray(rightOriginal0);
1224  }
1225
1226  private boolean[] getConversionArray(ColumnDetails[] cd) throws DException {
1227    int length = cd.length;
1228    boolean[] result = new boolean[length];
1229    boolean noNeedOfConversion = true;
1230    for (int i = 0; i < length; i++) {
1231      result[i] = cd[i].getDatatype() != appropriateDataTypes[i] ||
1232          cd[i].getSize() != appropriateSizes[i];
1233      if (result[i]) {
1234        noNeedOfConversion = false;
1235      }
1236    }
1237    return noNeedOfConversion ? null : result;
1238  }
1239
1240  public byte[] getByteKey() throws DException {
1241    switch (state) {
1242      case INVALIDSTATE:
1243      case BEFOREFIRST:
1244      case AFTERLAST:
1245        throw new DException("DSE4116", null);
1246      case ONLYFIRSTHAVEDATA:
1247        return getDataWhenOnlyHaveData(true, leftIterator);
1248      case ONLYSECONDHAVEDATA:
1249        return getDataWhenOnlyHaveData(false, rightIterator);
1250      case FIRSTISCURRENT:
1251      case SECONDISCURRENT:
1252      case BOTHHAVESAMEDATA:
1253        return getDataWhenBothHaveData(leftIterator, rightIterator);
1254    }
1255    throw new DException("DSE0", new Object JavaDoc[] {"INVALID STATE : " + state});
1256  }
1257
1258  public void moveByteKey(byte[] key) throws DException {
1259    state = key[0];
1260    direction = key[1];
1261    byte[] leftKeys = new byte[CCzufDpowfsufs.getShortValue(key, 2)];
1262    System.arraycopy(key, 4, leftKeys, 0, leftKeys.length);
1263    byte[] rightKeys = new byte[CCzufDpowfsufs.getShortValue(key,
1264        leftKeys.length + 4)];
1265    System.arraycopy(key, leftKeys.length + 6, rightKeys, 0, rightKeys.length);
1266    if (leftKeys.length == 0)
1267      moveWhenKeyIsNull(leftIterator, direction);
1268    else
1269      leftIterator.moveByteKey(leftKeys);
1270    if (rightKeys.length == 0)
1271      moveWhenKeyIsNull(rightIterator, direction);
1272    else
1273      rightIterator.moveByteKey(rightKeys);
1274  }
1275
1276  private byte[] getDataWhenBothHaveData(_Iterator leftIterator,
1277                                         _Iterator rightIterator) throws
1278      DException {
1279    byte[] leftKeys = leftIterator.getByteKey();
1280    byte[] rightKeys = rightIterator.getByteKey();
1281    byte[] resultantKeys = new byte[leftKeys.length + rightKeys.length + 2 + 4]; // 2 for state and direction and 2 for length of left and right
1282
resultantKeys[0] = (byte) state;
1283    resultantKeys[1] = (byte) direction;
1284    short leftLen = (short) leftKeys.length;
1285    short rightLen = (short) rightKeys.length;
1286    System.arraycopy(CCzufDpowfsufs.getBytes(leftLen), 0, resultantKeys, 2, 2);
1287    System.arraycopy(leftKeys, 0, resultantKeys, 4, leftKeys.length);
1288    System.arraycopy(CCzufDpowfsufs.getBytes(rightLen), 0, resultantKeys,
1289                     4 + leftLen, 2);
1290    System.arraycopy(rightKeys, 0, resultantKeys, leftKeys.length + 6,
1291                     rightKeys.length);
1292    return resultantKeys;
1293  }
1294
1295  public byte[] getDataWhenOnlyHaveData(boolean flag, _Iterator iterator) throws
1296      DException {
1297    byte[] keys = iterator.getByteKey();
1298    byte[] resultantKeys = new byte[keys.length + 2 + 2 + 2]; // 2 for state and direction and 2 for length of left and right
1299
resultantKeys[0] = (byte) state;
1300    resultantKeys[1] = (byte) direction;
1301    if (flag) {
1302      System.arraycopy(CCzufDpowfsufs.getBytes( (short) keys.length), 0,
1303                       resultantKeys, 2, 2);
1304      System.arraycopy(keys, 0, resultantKeys, 4, keys.length);
1305      System.arraycopy(CCzufDpowfsufs.getBytes( (short) 0), 0, resultantKeys,
1306                       keys.length + 4, 2);
1307    }
1308    else {
1309      System.arraycopy(CCzufDpowfsufs.getBytes( (short) 0), 0, resultantKeys, 2,
1310                       2);
1311      System.arraycopy(CCzufDpowfsufs.getBytes( (short) keys.length), 0,
1312                       resultantKeys, 4, 2);
1313      System.arraycopy(keys, 0, resultantKeys, 6, keys.length);
1314    }
1315    return resultantKeys;
1316  }
1317
1318  public void setSpecificUnderlyingReferences(_Reference[]
1319                                              specificUnderlyingReferences) throws
1320      DException {
1321    throw new java.lang.UnsupportedOperationException JavaDoc(
1322        "Method setSpecificUnderlyingReferences(_Reference[]) not yet implemented.");
1323  }
1324
1325  public String JavaDoc toString() {
1326    return "UnionAllOrderedIterator[" + leftIterator + "]\n\n[" + rightIterator +
1327        "]";
1328  }
1329
1330  /**
1331   *
1332   * public void setTableDetailsIfNotMatched(ColumnDetails[] leftOriginal,ColumnDetails[] rightOriginal) throws DException{
1333    for (int i = 0; i < leftOriginal.length; i++) {
1334        if(((ColumnDetails)leftColumnReferences[i]).getTable()!=leftOriginal[i].getTable()){
1335          ((ColumnDetails)leftColumnReferences[i]).setTableDetails(leftOriginal[i].getTable());
1336        }
1337      }
1338      for (int i = 0; i < orderLeftCD.length; i++) {
1339        if(orderLeftCD[i]==leftOriginal[i])
1340   if(((ColumnDetails)orderLeftCD[i]).getTable()!=leftOriginal[i].getTable()){
1341   ((ColumnDetails)orderLeftCD[i]).setTableDetails(leftOriginal[i].getTable());
1342          }
1343
1344      }
1345        for (int i = 0; i < rightOriginal.length; i++) {
1346          if(((ColumnDetails)rightColumnReferences[i]).getTable()!=rightOriginal[i].getTable()){
1347            ((ColumnDetails)rightColumnReferences[i]).setTableDetails(rightOriginal[i].getTable());
1348          }
1349        }
1350
1351        for (int i = 0; i < orderRightCD.length; i++) {
1352            if (orderRightCD[i] == rightOriginal[i])
1353              if ( ( (ColumnDetails) orderRightCD[i]).getTable() !=
1354                  rightOriginal[j].getTable()) {
1355   ( (ColumnDetails) orderRightCD[i]).setTableDetails(rightOriginal[i].
1356                    getTable());
1357              }
1358          }
1359
1360      }
1361   }
1362<<<<<<< UnionAllOrderedIterator.java
1363}
1364=======
1365   *
1366   */

1367
1368  /* Done on 04-06-2004 regarding a problem in Union involving Views */
1369  public void setTableDetailsIfNotMatched(ColumnDetails[] leftOriginal,
1370                                          ColumnDetails[] rightOriginal) throws
1371      DException {
1372    for (int i = 0; i < leftOriginal.length; i++) {
1373      if ( ( (ColumnDetails) leftColumnReferences[i]).getTable() !=
1374          leftOriginal[i].getTable()) {
1375        ( (ColumnDetails) leftColumnReferences[i]).setTableDetails(leftOriginal[
1376            i].getTable());
1377      }
1378    }
1379    for (int i = 0; i < orderLeftCD.length; i++) {
1380      for (int j = 0; j < leftOriginal.length; j++) {
1381        if (orderLeftCD[i] == leftOriginal[j]) {
1382          if ( ( (ColumnDetails) orderLeftCD[i]).getTable() !=
1383              leftOriginal[j].getTable()) {
1384            ( (ColumnDetails) orderLeftCD[i]).setTableDetails(leftOriginal[j].
1385                getTable());
1386          }
1387          break;
1388        }
1389      }
1390    }
1391    for (int i = 0; i < rightOriginal.length; i++) {
1392      if ( ( (ColumnDetails) rightColumnReferences[i]).getTable() !=
1393          rightOriginal[i].getTable()) {
1394        ( (ColumnDetails) rightColumnReferences[i]).setTableDetails(
1395            rightOriginal[i].getTable());
1396      }
1397    }
1398
1399    for (int i = 0; i < orderRightCD.length; i++) {
1400      for (int j = 0; j < rightOriginal.length; j++) {
1401        if (orderRightCD[i] == rightOriginal[j]) {
1402          if ( ( (ColumnDetails) orderRightCD[i]).getTable() !=
1403              rightOriginal[j].getTable()) {
1404            ( (ColumnDetails) orderRightCD[i]).setTableDetails(rightOriginal[j].
1405                getTable());
1406          }
1407          break;
1408        }
1409      }
1410    }
1411  }
1412}
1413
1414
Popular Tags