KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > daffodilwoods > daffodildb > server > sql99 > dql > plan > set > SetOperatorAbstract


1 package com.daffodilwoods.daffodildb.server.sql99.dql.plan.set;
2
3 import java.text.*;
4 import java.util.*;
5
6 import com.daffodilwoods.daffodildb.server.serversystem.*;
7 import com.daffodilwoods.daffodildb.server.sql99.common.*;
8 import com.daffodilwoods.daffodildb.server.sql99.dql.listenerevents.*;
9 import com.daffodilwoods.daffodildb.server.sql99.dql.plan.*;
10 import com.daffodilwoods.daffodildb.server.sql99.dql.plan.condition.*;
11 import com.daffodilwoods.daffodildb.server.sql99.expression.booleanvalueexpression.*;
12 import com.daffodilwoods.daffodildb.server.sql99.utils.*;
13 import com.daffodilwoods.daffodildb.utils.*;
14 import com.daffodilwoods.daffodildb.utils.comparator.*;
15 import com.daffodilwoods.daffodildb.utils.parser.*;
16 import com.daffodilwoods.database.resource.*;
17 import com.daffodilwoods.database.sqlinitiator.*;
18 import com.daffodilwoods.database.utility.*;
19
20 /**
21  * It provides functionality for common operations related to Set operators i.e
22  * UNION/EXCEPT/INTERSET with DISTINCT/ALL.
23  *
24  * <p>Title: </p>
25  * <p>Description: </p>
26  * <p>Copyright: Copyright (c) 2003</p>
27  * <p>Company: </p>
28  * @author Pardeep Sharma
29  * @version 1.0
30  */

31 public abstract class SetOperatorAbstract implements SetOperatorConstants {
32
33    /**
34     * Represents the clone of columns of left query.
35     */

36
37    protected ColumnDetails[] clonedLeftColumnDetails;
38
39    /**
40     * Represents the clone of columns of right query.
41     */

42
43    protected ColumnDetails[] clonedRightColumnDetails;
44
45    /**
46     * Represents the array of data types of objects which constitutes a record.
47     */

48
49    protected int[] appropriateDataTypes;
50
51    /**
52     * Represents the array of sizes of objects which constitutes a record.
53     */

54
55    protected int[] appropriateSizes;
56
57
58    /**
59     * Following fields are decalared by Sandeep to solve problem in union
60     * involving views. Propblem was in Testcase :TestUnionDistinct_usingViews.TestHirerchicalUnionDistinctWithOrderBy_OrderByOnAllColumnUsing)indexCount
61     * These are initiialized in getAdjustedOrder
62     * Represents the clone of ordered columns of left query.
63     */

64
65    protected ColumnDetails[] clonedLeftOrderColumnDetails;
66
67    /**
68     * Represents the clone of ordered columns of right query.
69     */

70
71    protected ColumnDetails[] clonedRightOrderColumnDetails;
72
73
74    /**
75     * It allows user to obtain order and its comparator for both queries when
76     * no order is present on this set operator. But to solve this set operator,
77     * selected columns needs to be in order.
78     * @param columnDetailsLeft - columns of left query.
79     * @param columnDetailsRight - columns of right query.
80     * @param serverSession
81     * @param columnOrder - represents the orderspecification of order.
82     * @return order and its comparator.
83     * @throws DException
84     */

85
86    public abstract ComparatorAndOrder getComparatorAndOrderForNormalOrder(ColumnDetails[] columnDetailsLeft, ColumnDetails[] columnDetailsRight, _ServerSession serverSession, boolean[] columnOrder) throws DException;
87
88    /**
89     * It allows user to obtain order and its comparator for both queries when
90     * order is present on this set operator. And the order is arranged so as to
91     * get all the selected columns to be involved in this order. It is required
92     * to obtain their result optimally.
93     * @param columnDetailsLeft - columns of left query.
94     * @param columnDetailsRight - columns of right query.
95     * @param serverSession
96     * @param columnOrder - represents the orderspecification of order.
97     * @return order and its comparator.
98     * @throws DException
99     */

100
101    public abstract ComparatorAndOrder getComparatorAndOrderForRearrangedOrder(ColumnDetails[] columnDetailsLeft, ColumnDetails[] columnDetailsRight, _ServerSession serverSession, boolean[] columnOrder) throws DException;
102
103    /**
104     * It allows user to obtain order and its comparator for both queries when
105     * order is present on this set operator. And the order is already adjusted
106     * according to the selected columns. It is the case when setoperator is left
107     * child of set operator. In that case topmost setoperator perform the
108     * adjustment of selected column, so in this case only the selected column of
109     * right child of underlying set operator needs to be adjusted acc. to order.
110     * @param columnDetailsLeft - columns of left query.
111     * @param columnDetailsRight - columns of right query.
112     * @param serverSession
113     * @param columnOrder - represents the orderspecification of order.
114     * @return order and its comparator.
115     * @throws DException
116     */

117
118    public abstract ComparatorAndOrder getComparatorAndOrderForAlreadyAdjustedOrder(_Order order, ColumnDetails[] columnDetailsLeft, ColumnDetails[] columnDetailsRight, _ServerSession serverSession, boolean[] columnOrder) throws DException;
119
120    /**
121     * This method is required when condition is given on a view in which set
122     * operators are present. And that condition is solvable by view. So we've to
123     * shift this condition to underlying queries of set operator so as to give
124     * result optimally. Now columns in the condition belongs to only query of
125     * left most side. So when we've to shift condition to query of right side,
126     * we've to change columns of condition according to columns of right side
127     * query.
128     * @param conditionColumnDetails represents columns involved in condition
129     * @param oldColumn represents the columns of query of left side.
130     * @param newColumn represents the columns of query of right side.
131     * @throws DException
132     */

133    protected void changeColumnDetails(ColumnDetails conditionColumnDetails[], ColumnDetails[] oldColumn, ColumnDetails[] newColumn) throws DException {
134       int newColDetailsLen = oldColumn.length;
135       ColumnDetails tempColDetails;
136       for (int i = 0; i < conditionColumnDetails.length; i++) {
137          ColumnDetails columnDetail = conditionColumnDetails[i];
138          String JavaDoc t1 = columnDetail.getQualifiedColumnName();
139          for (int j = 0; j < newColDetailsLen; j++) {
140             String JavaDoc t2 = oldColumn[j].getQualifiedColumnName();
141             if (t1.equalsIgnoreCase(t2)) {
142                columnDetail.setTableDetails(newColumn[j].getTable()); // TableDetails of Actual
143
columnDetail.setObject(newColumn[j].getObject()); // Derived Object of Actual
144
columnDetail.setColumnName(newColumn[j].getType() == TypeConstants.REFERENCE ? newColumn[j].getColumnName() : (String JavaDoc[])new String JavaDoc[] {newColumn[j].getColumn()});
145                if (columnDetail.getAliasName() != null) {
146                   columnDetail.setAliasName(newColumn[j].getAliasName());
147                }
148                columnDetail.setType(newColumn[j].getType());
149                columnDetail.setTableAliasArray(newColumn[j].getTableAliasArray());
150                columnDetail.setDatatype(newColumn[j].getDatatype());
151                break;
152             }
153          }
154       }
155    }
156
157    /**
158     * Returns the ComparatorAndOrder Object configured according to Order
159     * required on the Set data.<p>
160     * This method handles all the cases i.e union/distinct/intersect with
161     * distinct/all.<p>
162     * First case is when explicit order is not specified then in case of
163     * union/distinct/intersect, data is reutred in order according to
164     * selected columns.<p>
165     * But in case of Union All, if explicit order is not there then data is
166     * returned in natural order i.e no order is imposed on data.<p>
167     * Second case is when explicit order is spcified then there arries two
168     * cases whether the Order Object got here is already configured for
169     * Left Part or not.<p>
170     * If Order Object is alrady configured for Left part then there is nothing
171     * to do, simply make Order for Right Part according to Left Part.<p>
172     * Otherwise if Order Object is not configured then make AdjustedSelectOrder
173     * for Both Parts and return the configured order object i.e.
174     * ComparatorAndOrder instance.
175     * @param order The Order Object for which configured ComparatorAndOrder
176     * required.
177     * @param exceptOrUnion whether the case is of Except or of Union.
178     * @param distinctOrAll whether the case is of Distinct or of All.
179     * @param isIntersect represents whether the case is of Intersect or not.
180     * @param columnDetailsLeft ColumnDetails Array of Left Part.
181     * @param columnDetailsRight ColumnDetails Array of Right Part.
182     * @return ComparatorAndOrder configured according to order required.
183     * @throws DException
184     */

185    protected ComparatorAndOrder getAdjustedSelectOrder(_Order order, ColumnDetails[] columnDetailsLeft, ColumnDetails[] columnDetailsRight, _ServerSession serverSession) throws DException {
186       if (order == null) {
187          return getOrderAccordingToSelectCols(columnDetailsLeft, columnDetailsRight, serverSession);
188       }
189       if (! ( (_OrderWithTableInformation) order).isAdjustedOrder()) {
190          return getRearrangedOrder(order, columnDetailsLeft, columnDetailsRight, serverSession);
191       }
192
193       return getOrderWhenAlreadyAdjusted(order, columnDetailsLeft, columnDetailsRight, serverSession);
194    }
195
196
197    protected ComparatorAndOrder getOrderWhenUnionAllwithOrderby(_Order order, ColumnDetails[] columnDetailsLeft, ColumnDetails[] columnDetailsRight, _ServerSession serverSession) throws DException {
198       Object JavaDoc[] adjustedIndexesAndOrder = GeneralPurposeStaticClass.getColumnIndexesAndBooleanOrderOfOrderby(order, columnDetailsLeft);
199       int[] indexes = (int[]) adjustedIndexesAndOrder[0];
200       boolean[] orderSpecifications = (boolean[]) adjustedIndexesAndOrder[1];
201       ColumnDetails[] adjustedColsRight = GeneralPurposeStaticClass.getColumnDetailsAccToIndexes(indexes, columnDetailsRight);
202       ColumnDetails[] adjustedColsLeft = GeneralPurposeStaticClass.getColumnDetailsAccToIndexes(indexes, columnDetailsLeft);
203       return getComparatorAndOrderForUnionAllWithOrderby(order, adjustedColsLeft, adjustedColsRight, serverSession, orderSpecifications);
204    }
205
206
207    public ComparatorAndOrder getComparatorAndOrderForUnionAllWithOrderby(_Order order, ColumnDetails[] columnDetailsLeft, ColumnDetails[] columnDetailsRight, _ServerSession serverSession, boolean[] orderSpecifications) throws DException{
208         _Order derivedOrderLeft = new SelectOrder(columnDetailsLeft,orderSpecifications,true);
209          _Order derivedOrderRight = new SelectOrder(columnDetailsRight, orderSpecifications, true);
210 /* done on 03-06-2004 regarding problem in union involving views */
211          return new ComparatorAndOrder(getComparableComparator(order.getKeyColumnDetails(), columnDetailsRight, orderSpecifications, serverSession), new _Order[] {derivedOrderLeft, derivedOrderRight});
212
213
214       }
215
216
217
218    /**
219     * Returns a ComparatorAndOrder Object. This method is used when Order
220     * is requried according to Selected Columns i.e. Order By Clause is not
221     * specified. Except of "Union All" case, all cases returns data in order
222     * of selected column if Order By is not specified by user.
223     * @param columnDetailsLeft ColumnDetails Array of Left Part.
224     * @param columnDetailsRight ColumnDetails Array of Right Part.
225     * @return ComparatorAndOrder configured accroding to selected columns.
226     * @throws DException
227     */

228    protected ComparatorAndOrder getOrderAccordingToSelectCols(ColumnDetails[] columnDetailsLeft, ColumnDetails[] columnDetailsRight, _ServerSession serverSession) throws DException {
229       boolean[] columnOrder = new boolean[columnDetailsLeft.length];
230       Arrays.fill(columnOrder, true);
231       return getComparatorAndOrderForNormalOrder(columnDetailsLeft, columnDetailsRight, serverSession, columnOrder);
232    }
233
234    /**
235     * Returns the ComparatorAndOrder Object after configuring the Order for
236     * both parts of query.<p>
237     * This method is used when Order Object is not configured according to
238     * order desired.<p>
239     * This method first makes indexes and order specification array for
240     * the columns included in the order required. Then makes left and right
241     * column details according to these indexes. Finally it makes
242     * AdjustedSelectOrder instances for Let and Right part and returns
243     * ComparatorAndOrder Object constructed using these Left and Right
244     * AdjustedSelectOrder.
245     * @param order The Order Object which is to be configured according to
246     * Order Columns.
247     * @param columnDetailsLeft ColumnDetails Array of Left Part.
248     * @param columnDetailsRight ColumnDetails Array of Right Part.
249     * @return ComparatorAndOrder configured according to Order Columns.
250     * @throws DException
251     */

252    protected ComparatorAndOrder getRearrangedOrder(_Order order, ColumnDetails[] columnDetailsLeft, ColumnDetails[] columnDetailsRight, _ServerSession serverSession) throws DException {
253       Object JavaDoc[] indexAndBooleanOrder = GeneralPurposeStaticClass.getColumnIndexesAndBooleanOrderOfAdjustedOrder(order, columnDetailsLeft,false);
254       ColumnDetails[] orderColumns = order.getColumnDetails();
255       int[] indexes = null;
256       try {
257          indexes = (int[]) indexAndBooleanOrder[0];
258       } catch (NullPointerException JavaDoc ex) {
259          throw ex;
260       }
261       boolean[] orderSpecifications = (boolean[]) indexAndBooleanOrder[1];
262       ColumnDetails[] adjustedColumnsLeft = GeneralPurposeStaticClass.getColumnDetailsAccToIndexes(indexes, columnDetailsLeft);
263       ColumnDetails[] adjustedColumnsRight = GeneralPurposeStaticClass.getColumnDetailsAccToIndexes(indexes, columnDetailsRight);
264       return getComparatorAndOrderForRearrangedOrder(adjustedColumnsLeft, adjustedColumnsRight, serverSession, orderSpecifications);
265    }
266
267    /**
268     * Returns the ComparatorAndOrder object. This method is used when Order
269     * is already adjusted on the Left Part of the Union/Distinct or Intersect
270     * operation.<p>
271     * As Order is already adjusted on the Left Part, for making new
272     * ComparatorAndOrder instance, the Left Order is used in creation of Order
273     * of right part.
274     * @param order The Order Object already ajusted on Left Part.
275     * @param columnDetailsLeft ColumnDetails Array of Left Part.
276     * @param columnDetailsRight ColumnDetails Array of Right Part.
277     * @return ComparatorAndOrder Containing adjusted order for Right Part.
278     * @throws DException
279     */

280    protected ComparatorAndOrder getOrderWhenAlreadyAdjusted(_Order order, ColumnDetails[] columnDetailsLeft, ColumnDetails[] columnDetailsRight, _ServerSession serverSession) throws DException {
281       Object JavaDoc[] adjustedIndexesAndOrder = GeneralPurposeStaticClass.getColumnIndexesAndBooleanOrderOfAdjustedOrder(order, columnDetailsLeft,false);
282       int[] indexes = (int[]) adjustedIndexesAndOrder[0];
283       boolean[] orderSpecifications = (boolean[]) adjustedIndexesAndOrder[1];
284       ColumnDetails[] adjustedCols = GeneralPurposeStaticClass.getColumnDetailsAccToIndexes(indexes, columnDetailsRight);
285
286 /** Done on 03-06-2004 changes being done to solve a problem related to union query involving views */
287 ColumnDetails[] adjustedLeftCols = GeneralPurposeStaticClass.getColumnDetailsAccToIndexes(indexes,columnDetailsLeft);
288
289       return getComparatorAndOrderForAlreadyAdjustedOrder(order, adjustedLeftCols, adjustedCols, serverSession, orderSpecifications);
290
291    }
292
293    /**
294     * It represents the order and comparator for underlying queries of set
295     * operators.
296     * <p>Title: </p>
297     * <p>Description: </p>
298     * <p>Copyright: Copyright (c) 2003</p>
299     * <p>Company: </p>
300     * @author unascribed
301     * @version 1.0
302     */

303    public class ComparatorAndOrder {
304
305       /**
306        * Represents the array of order. It is of size two. One order is for
307        * query of left side of set operator and other is for query of right side
308        * of set operator.
309        */

310
311       public _Order order[];
312
313       /**
314        * Represents the comparator to compare the order of underlying queries
315        * of set operator.
316        */

317
318       public SuperComparator comparator;
319
320       public ComparatorAndOrder(SuperComparator comparator0, _Order[] order0) {
321          order = order0;
322          comparator = comparator0;
323       }
324
325    }
326
327    /**
328     * Returns comparator according to datatype of both columns. If any
329     * column of left or right query can't use byte comparison then object
330     * comparator is created otherwise appropriate ByteComparator is created.
331     * @param leftColumns
332     * @param rightColumns
333     * @param orderSpecifications
334     * @param serverSession
335     * @return
336     * @throws DException
337     */

338    public SuperComparator getComparableComparator(ColumnDetails[] leftColumns, ColumnDetails[] rightColumns, boolean[] orderSpecifications, _ServerSession serverSession) throws DException {
339       int length = leftColumns.length;
340       SuperComparator[] superComparators = new SuperComparator[length];
341       for (int i = 0; i < length; i++) {
342          try {
343             Collator collator1 = leftColumns[i].getType() == TypeConstants.REFERENCE ? leftColumns[i].getTable() == null ? null : leftColumns[i].getTable().cc.getCollator() : null;
344             collator1 = collator1 == null && rightColumns[i].getType() == TypeConstants.REFERENCE ? rightColumns[i].getTable() == null ? null : rightColumns[i].getTable().cc.getCollator() : collator1;
345             superComparators[i] = leftColumns[i].canUseByteComparison() && rightColumns[i].canUseByteComparison() ? new CPsefsDpnqbsbups(GetByteComparator.getAppropriateComparator(leftColumns[i].getDatatypeForOrder(), rightColumns[i].getDatatypeForOrder(), serverSession, collator1), orderSpecifications[i])
346                 : new CPsefsDpnqbsbups(new CPckfduDpnqbsbups(), orderSpecifications[i]);
347          } catch (NullPointerException JavaDoc ex) {
348             throw ex;
349          }
350       }
351       return new CKpjoDpnqbsbups(superComparators);
352    }
353
354    /**
355     * This method is used to retrieve the maximum data type and size for
356     * corresponding columns of both queries. And also set this max. data type
357     * and size in corresponding columns. It is required to return same type of
358     * objects from set operators. Set opearator result is formed from the result
359     * of both queries, so the objects of both query must be of same datatype and
360     * size.
361     * @throws DException
362     */

363
364    public void initializeAppropriateDataTypeAndSize() throws DException {
365       int length = clonedLeftColumnDetails.length;
366       appropriateDataTypes = new int[length];
367       appropriateSizes = new int[length];
368       for (int i = 0; i < length; i++) {
369          int dt1 = clonedLeftColumnDetails[i].getDatatype();
370          int dt2 = clonedRightColumnDetails[i].getDatatype();
371          appropriateDataTypes[i] = dt1 > dt2 ? dt1 : dt2;
372          int sz1 = clonedLeftColumnDetails[i].getSize();
373          int sz2 = clonedRightColumnDetails[i].getSize();
374          appropriateSizes[i] = sz1 > sz2 ? sz1 : sz2;
375          if (clonedRightColumnDetails[i].getType() != TypeConstants.REFERENCE) { // To make sure that Byte comparison will be used only when both query has Reference type of columns
376
clonedLeftColumnDetails[i].setByteComparison(false);
377          }
378       }
379    }
380
381    /**
382     * For the documentation of follwing methods, refer the documentation of
383     * queryexpressionbody. And the methods which are throwing unsupported
384     * exception, are not required for set operator.
385     */

386
387    public boolean isSimpleQuery(_ServerSession serverSession) throws DException {
388       return false;
389    }
390
391    public boolean isViewOptimizationPossible() throws DException {
392       return false;
393    }
394
395    public _TablePlan[] getTablePlans(_ServerSession session, booleanvalueexpression condition, _Order order, ColumnDetails[] columnDetails, ConditionArray conditionArray) throws DException {
396       throw new UnsupportedOperationException JavaDoc("Method getTablePlans() not supported");
397    }
398
399    public _BVEPlan getBveExecutionPlan() throws DException {
400       throw new UnsupportedOperationException JavaDoc("Method getTablePlans() not supported");
401    }
402
403    public Object JavaDoc run(Object JavaDoc object) throws DException {
404       throw new UnsupportedOperationException JavaDoc();
405    }
406
407    public QueryProperty getStrings() throws com.daffodilwoods.database.resource.DException {
408       /**@todo: Implement this com.daffodilwoods.daffodildb.server.sql99.dql.queryexpression.queryexpressionbody method*/
409       throw new java.lang.UnsupportedOperationException JavaDoc("Method getStrings() not yet implemented.");
410    }
411
412    public TableDetails[] getViewTableDetails() throws DException {
413       /**@todo Implement this com.daffodilwocompaods.daffodildb.server.sql99.dql.queryexpression.queryexpressionbody method*/
414       throw new java.lang.UnsupportedOperationException JavaDoc("Method getViewTableDetails() not yet implemented.");
415    }
416
417    public void setTablesForInsertion(ColumnMappingHandler parm1, _VariableValueOperations parm2) throws com.daffodilwoods.database.resource.DException {
418       /**@todo Implement this com.daffodilwoods.daffodildb.server.sql99.dql.queryexpression.queryexpressionbody method*/
419       throw new java.lang.UnsupportedOperationException JavaDoc("Method setTablesForInsertion() not yet implemented.");
420    }
421
422    public TableDetails[] getTablesForBlankInsert() throws com.daffodilwoods.database.resource.DException {
423       /**@todo Implement this com.daffodilwoods.daffodildb.server.sql99.dql.queryexpression.queryexpressionbody method*/
424       throw new java.lang.UnsupportedOperationException JavaDoc("Method getTablesForBlankInsert() not yet implemented.");
425    }
426
427    public void verifyValues(_VariableValueOperations vv) throws DException {
428       throw new java.lang.UnsupportedOperationException JavaDoc("Method verifyValues() not yet implemented.");
429    }
430
431    public void setFKeyColumnDetails(ColumnDetails[] parm1) throws com.daffodilwoods.database.resource.DException {
432       /**@todo Implement this com.daffodilwoods.daffodildb.server.sql99.dql.queryexpression.queryexpressionbody method*/
433       throw new java.lang.UnsupportedOperationException JavaDoc("Method setFKeyColumnDetails() not yet implemented.");
434    }
435 }
436
Popular Tags