KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > daffodilwoods > daffodildb > server > sql99 > dql > plan > condition > AllColumnPredicates


1 package com.daffodilwoods.daffodildb.server.sql99.dql.plan.condition;
2
3 import java.util.*;
4
5 import com.daffodilwoods.daffodildb.server.datasystem.indexsystem.*;
6 import com.daffodilwoods.daffodildb.server.datasystem.interfaces.*;
7 import com.daffodilwoods.daffodildb.server.serversystem.*;
8 import com.daffodilwoods.daffodildb.server.sessionsystem.*;
9 import com.daffodilwoods.daffodildb.server.sql99.common.*;
10 import com.daffodilwoods.daffodildb.server.sql99.dql.execution.*;
11 import com.daffodilwoods.daffodildb.server.sql99.dql.iterator.*;
12 import com.daffodilwoods.daffodildb.server.sql99.dql.iterator.condition.*;
13 import com.daffodilwoods.daffodildb.server.sql99.dql.plan.table.*;
14 import com.daffodilwoods.daffodildb.server.sql99.expression.booleanvalueexpression.*;
15 import com.daffodilwoods.daffodildb.server.sql99.expression.booleanvalueexpression.predicates.*;
16 import com.daffodilwoods.daffodildb.server.sql99.utils.*;
17 import com.daffodilwoods.daffodildb.utils.comparator.*;
18 import com.daffodilwoods.database.resource.*;
19 import com.daffodilwoods.database.utility.P;
20 import com.daffodilwoods.daffodildb.server.sql99.expression.booleanvalueexpression.booleantest;
21 import com.daffodilwoods.daffodildb.utils.FieldUtility;
22 import com.daffodilwoods.daffodildb.utils.field.FieldBase;
23 import com.daffodilwoods.daffodildb.server.sql99.dql.iterator.table.MultiValueIndexedFilterIterator;
24
25 /**
26  * It represents all predicate present at single Table in selectQuery.It is required
27  * to distinguish those predicate which are solved by index and those which are
28  * not solved by index.This is also required for index selection on single table.
29  * <p>Title: </p>
30  * <p>Description: </p>
31  * <p>Copyright: Copyright (c) 2004</p>
32  * <p>Company: </p>
33  * @author not attributable
34  * @version 1.0
35  */

36 public class AllColumnPredicates implements _AllColumnPredicates {
37
38    /**
39     * Represents the table for which index selection has to perform.
40     */

41
42    private TableDetails tableDetails;
43    /**
44     * It represents list of predicate solved by index
45     */

46    private _SingleColumnPredicate[] singleColumnPredicates;
47    /**
48     * It represents condition which are not solved by index.
49     */

50    private booleanvalueexpression nonIndexedCondition;
51
52    /**
53     * Represent the position of index which is choosen to solve the condition.
54     */

55
56    private int indexPosition;
57    /**
58     * This flag set,when evaluation of condition does not provide any record
59     * e.g a=5 and a!=5 this condition is invalid does not give any record.
60     * In that type of condition norecorditerator flag set true.
61     *
62     */

63    private boolean isNoRecordIterator;
64
65    /**
66     * Represents the comparator for merging of predicates
67     */

68
69    private SuperComparator objectComparator;
70
71    public AllColumnPredicates() {
72       objectComparator = new CPckfduDpnqbsbups();
73    }
74
75    /**
76     * This method is used to add predicate which are solved by index in single
77     * columnpredicate
78     * Algo:
79     * 1) If SingleColumnPredicates contained in this class is null then,
80     * passed are initialized.
81     * 2) Else, Merging of predicates is done.
82     * By Merging of Predicates we mean reWriting of predicates so that
83     * predicates are grouped acc to columnName.
84     * If Predicate passed belongs to the same column then merging of predicate
85     * is performed
86     * Examples:
87     * Predicates === Resultant Predicate
88     * A = 2 and A > 3 === Null
89     * A = 2 and A = 3 === Null
90     * A > 3 and A > 4 === A > 4
91     * A = 2 and A > 1 === A = 2
92     * If Resultant Predicate is Null, then we mean 'false' condition, for
93     * this boolean isNoRecordIterator is initialized to true, for this flag
94     * Iterator is made with no records means whose first() returns false.
95     * 3) After Merging, Merged predicate is added to singleCOlumnPredicates
96     * 4) If Merging is not possible, then predicate is added as such
97     * to singleCOlumnPredicates.
98     * 5) IF isNoRecordIterator is true means 'false' condition, then no use of
99     * merging any more predicates
100     * @param newSingleColumnPredicates
101     * @throws DException
102     */

103    public void addSinglePredicate(_SingleColumnPredicate[] newSingleColumnPredicates) throws DException {
104       if (isNoRecordIterator) {
105          return;
106       }
107       if (singleColumnPredicates == null) {
108          try {
109             singleColumnPredicates = (_SingleColumnPredicate[]) newSingleColumnPredicates;
110          } catch (ClassCastException JavaDoc e) {
111          }
112          return;
113       }
114       ArrayList aList = new ArrayList();
115
116       int len1 = singleColumnPredicates.length, len2 = newSingleColumnPredicates.length;
117
118       for (int j = 0; j < len2; j++) {
119
120          int i = 0;
121          for (; i < len1; i++) {
122
123             if (singleColumnPredicates[i].getColumnName().equalsIgnoreCase(newSingleColumnPredicates[j].getColumnName())) {
124                try {
125
126                  /* Line 137 to 156 done by kaushik on 20/07/2004
127     check for checkForComparisonPredicate() is removed as not required .
128     because notequalto operators are alreday aaded in addToNonIndex
129 To solve testExecution.testFromAndWhere_QualifiedPlanHeirarchicalQualifiedPlan_WhereRandomCondition_1
130                   */

131                  int type = singleColumnPredicates[i].getPredicateType();
132                  int type2 = newSingleColumnPredicates[j].getPredicateType();
133                  predicate _predicate = null;
134                  if(type == OperatorConstants.IN){// if 2nd is in predicate and 1st is comparison then add comparison as single and in as nonIndex
135
addToNonIndex(new booleanfactor(new booleantest(singleColumnPredicates[i].getPredicate())));
136                    _predicate = newSingleColumnPredicates[j].getPredicate();
137                  }else if(type2 == OperatorConstants.IN){ // if first is in predicate and 2nd is comparison then add comparison as single and in as nonIndex
138
addToNonIndex(new booleanfactor(new booleantest(newSingleColumnPredicates[j].getPredicate())));
139                    _predicate = singleColumnPredicates[i].getPredicate();
140                  }
141
142                  else{
143                  _predicate = TablePlanMerger.getMergedPredicate(singleColumnPredicates[i].getPredicate(), newSingleColumnPredicates[j].getPredicate(), objectComparator);
144                  }
145
146                   if (_predicate == null) {
147                      isNoRecordIterator = true;
148                      return;
149                   } else {
150                      singleColumnPredicates[i].setPredicate(_predicate);
151                   }
152                   break;
153                } catch (DException dException) { // questionMarks
154
String JavaDoc code = dException.getDseCode();
155                   if (code.equalsIgnoreCase("DSE1251") || code.equalsIgnoreCase("DSE3804")) {
156                      aList.add(newSingleColumnPredicates[j]);
157                   } else {
158                      throw dException;
159                   }
160                }
161                break;
162             }
163          }
164          if (i == len1) {
165             aList.add(newSingleColumnPredicates[j]);
166          }
167       }
168       aList.addAll(Arrays.asList(singleColumnPredicates));
169       SingleColumnPredicate[] scp = (SingleColumnPredicate[]) aList.toArray(new SingleColumnPredicate[aList.size()]);
170       singleColumnPredicates = scp;
171     }
172
173    /**
174     * Method splits the SingleColumnPredicates into two categories one that is
175     * solved by passed IndexInformation and other which are not solved by passed
176     * index information.
177     * For Solvable by Index
178     * AllColumn IndexPredicates is made which contain the IndexedSingleCOlumn
179     * Predicates
180     * For Not Solvable By Index
181     * AllColumn NonIndexPredicates is made which contain the NonIndexed Condition
182     * IndexPredicate is initialized with these two AllColumnPredicates and returned.
183     * Status of NoRecordIterator is initialized in IndexPredicate.
184     * @param indexInformation0
185     * @param indexPosition0
186     * @return
187     * @throws DException
188     */

189    public _IndexPredicateInterface splitForIndex(_IndexInformation indexInformation0, int indexPosition0) throws DException {
190       IndexPredicate indexPredicate = getIndexPredicatesForIndex(indexInformation0, indexPosition0);
191       indexPredicate.setNoRecordIteratorStatus(isNoRecordIterator);
192       return indexPredicate;
193    }
194    /**
195     * This method is required to merge passed nonindexcondiiton to existing
196     * nonindexcondition with AND logical operator.If existing nonindexcondition
197     * is null then existing nonindexcondition has been initialized wth passed
198     * nonidexcondition.
199     * @param newNonIndexedCondition
200     * @throws DException
201     */

202    public void addToNonIndex(booleanvalueexpression newNonIndexedCondition) throws DException {
203       if (nonIndexedCondition != null) {
204          nonIndexedCondition = BVEPlanMerger.addAndConditions(nonIndexedCondition, newNonIndexedCondition);
205       } else {
206          nonIndexedCondition = newNonIndexedCondition;
207       }
208    }
209
210    /**
211     * Execute Method is used to return the Indexed Iterator.
212     * Iterator is asked from IndexTable for the indexPosition(which is the position of index choosen)
213     * @param sessionObject
214     * @return
215     * @throws DException
216     */

217    public _Iterator execute(Object JavaDoc sessionObject) throws DException {
218       _IndexTable session = (_IndexTable) sessionObject;
219       _ServerSession serverSession = ( (_SessionGetter) session).getServerSession();
220        _Iterator iter = session.getIterator(indexPosition); // Iterator Wrapper
221

222 /* Done by Kaushik on 21/07/2004 for Indexing in InPredicate Line 238 to 262 */
223        if(singleColumnPredicates[0].getPredicate().getPredicateType()==OperatorConstants.IN){
224          inpredicate in =(inpredicate)singleColumnPredicates[0].getPredicate();
225          ArrayList values=new ArrayList();
226          ColumnDetails cd=in.getChilds()[0].getColumnDetails()[0]; // only cd at the left side of in predicate
227
/*Here Create Object of MultiValueIterator by passing obj and return that Object*/
228         MultiValueIndexedFilterIterator mviter = new MultiValueIndexedFilterIterator(iter, null, serverSession, cd,( (pareninvaluelist) in._inpredicatevalue0)._invaluelist0);
229          return mviter;
230        }
231
232        booleanvalueexpression indexedCondition = new BooleanValueExpressionArray(getBVEArray());
233       _IndexPredicate[] indexPredicateArray = (_IndexPredicate[]) getBVEArrayCVV(iter, serverSession);
234       VariableValues variableValues = new VariableValues(indexedCondition.getReferences(new TableDetails[] {tableDetails}), serverSession);
235       variableValues.setIterator(iter);
236       ConditionVariableValue indexPredicates = new ConditionVariableValue(variableValues, indexedCondition);
237       iter = new IndexedFilterIterator(iter, indexPredicates, indexPredicateArray);
238       return iter;
239    }
240
241    /**
242     * This method provides functionality of getting condition array,which contains
243     * all condition presents in SingleColumnPredicate.
244     * @return
245     * @throws DException
246     */

247    private booleanvalueexpression[] getBVEArray() throws DException {
248       int length = singleColumnPredicates.length;
249       booleanvalueexpression[] array = new booleanvalueexpression[length];
250       for (int i = 0; i < length; ++i) {
251          array[i] = BVEPlanMerger.getBooleanFactor(singleColumnPredicates[i].getPredicate());
252       }
253       return array;
254    }
255
256    /**
257     * This method provides functionality of getting list of CoditionVariableValue.
258     * ConditionVariableValue contians condition and VariableValue.VariableValue
259     * contains unknown references present in condition.unknown references of
260     * condition are those refernces which are not solved by passed table details.
261     * @param iter
262     * @return
263     * @throws DException
264     */

265    private ConditionVariableValue[] getBVEArrayCVV(_Iterator iter, _ServerSession serverSession) throws DException {
266       int length = singleColumnPredicates.length;
267       ConditionVariableValue[] cvv = new ConditionVariableValue[length];
268       for (int i = 0; i < length; ++i) {
269          booleanvalueexpression bve = BVEPlanMerger.getBooleanFactor(singleColumnPredicates[i].getPredicate());
270          VariableValues VV = new VariableValues(bve.getReferences(new TableDetails[] {tableDetails}), serverSession);
271          ConditionVariableValue cv = new ConditionVariableValue(VV, bve);
272          cvv[i] = cv;
273       }
274       return cvv;
275    }
276
277    /**
278     * Method extracts the Predicates resolved by passed index and predicate which
279     * are not resolved by index (NonIndex Condition).
280     * @param indexInformation
281     * @return
282     * @throws DException
283     */

284    private IndexPredicate getIndexPredicatesForIndex(_IndexInformation indexInformation, int indexPosition0) throws DException {
285       if (singleColumnPredicates == null) {
286          return initializeIndexPredicate(null, nonIndexedCondition, indexPosition0);
287       }
288       String JavaDoc indexColumns[] = indexInformation.getColumns();
289       Object JavaDoc[] singleColumnPredicatesAndNonIndexedCondition = getIndexedPredicatesAndInitializeNonIndexedCondition(indexColumns, indexInformation.getOrderOfColumns(), singleColumnPredicates);
290       _SingleColumnPredicate[] indexedPredicates = (_SingleColumnPredicate[]) singleColumnPredicatesAndNonIndexedCondition[0];
291       booleanvalueexpression nonIndexedCondition = (booleanvalueexpression) singleColumnPredicatesAndNonIndexedCondition[1];
292       return initializeIndexPredicate(indexedPredicates, nonIndexedCondition, indexPosition0);
293    }
294    /**
295     * This method is used to get indexpredicate which conatin indexedallcolumnpredicate
296     * and nonindexedallcolumnpredicate.indexedallcolumnpredicate conatins singlecolumn
297     * predicate which are solved by indexed condition and nonindexedallcolumn
298     * predicate contain nonindexed condition.
299     * @param singleColumnPredicates0
300     * @param nonIndexedCondition0
301     * @param indexPosition0
302     * @return
303     * @throws DException
304     */

305    private IndexPredicate initializeIndexPredicate(_SingleColumnPredicate[] singleColumnPredicates0, booleanvalueexpression nonIndexedCondition0, int indexPosition0) throws DException {
306       AllColumnPredicates indexedPredicate = null;
307       AllColumnPredicates nonIndexedPredicate = null;
308       if (singleColumnPredicates0 != null) {
309          indexedPredicate = new AllColumnPredicates();
310          indexedPredicate.setIndexPosition(indexPosition0);
311          indexedPredicate.addSinglePredicate(singleColumnPredicates0);
312       }
313       if (nonIndexedCondition0 != null) {
314          nonIndexedPredicate = new AllColumnPredicates();
315          nonIndexedPredicate.addToNonIndex(nonIndexedCondition0);
316       }
317       return new IndexPredicate(indexedPredicate, nonIndexedPredicate);
318    }
319
320    /**
321     * Index Columns are columns belonging to Index
322     * Predicate Columns are columns belonging to Single Column Predicates
323     * Algo:
324     * 1) Boolean Array is used as an indicator which predicates are solved by index and which are not.
325     * False means, not solved by Index
326     * True means, solved by Index
327     * 2) Predicates are choosen with the help of INdexINformation which are solvale and which are not.
328     * 3) NonIndexedCondition is made and IndexPredicates as well as NonINdexedCondition are returned.
329     * @param indexColumns
330     * @param predicateColumns
331     * @return
332     * @throws DException
333     */

334    private Object JavaDoc[] getIndexedPredicatesAndInitializeNonIndexedCondition(String JavaDoc[] indexColumns, boolean[] indexColumnsOrder, _SingleColumnPredicate[] predicateColumns) throws DException {
335       boolean[] indexNonIndex = new boolean[predicateColumns.length]; // false means NonIndexedCondition
336
ArrayList listOfIndexedColumn = new ArrayList();
337       extractIndexedPredicates(0, indexNonIndex, indexColumns, indexColumnsOrder, predicateColumns, listOfIndexedColumn, true);
338       booleanvalueexpression nonIndexedCondition0 = initializeNonIndexCondition(indexNonIndex);
339       if (listOfIndexedColumn.isEmpty()) {
340          return new Object JavaDoc[] {null, nonIndexedCondition0};
341       }
342       return new Object JavaDoc[] { (_SingleColumnPredicate[]) listOfIndexedColumn.toArray(new SingleColumnPredicate[listOfIndexedColumn.size()]), nonIndexedCondition0};
343    }
344
345    /**
346     * Initialize Non Indexed Condition with the predicates not solved by Index and with NonINdexedCodnition over here
347     * False in the position denotes 'not solvable by Index'
348     * @param indexNonIndex
349     * @throws DExceptionA
350     */

351    private booleanvalueexpression initializeNonIndexCondition(boolean[] indexNonIndex) throws DException {
352       booleanvalueexpression nonIndexedCondition0 = nonIndexedCondition;
353       for (int i = 0; i < indexNonIndex.length; ++i) {
354          if (!indexNonIndex[i]) {
355             if (!singleColumnPredicates[i].isLikePredicate()) {
356                nonIndexedCondition0 = BVEPlanMerger.addAndConditions(nonIndexedCondition0, getBooleanValueExpression(singleColumnPredicates[i].getPredicate()));
357             }
358          }
359       }
360       return nonIndexedCondition0;
361    }
362
363    /**
364     * Method is used to extract Predicates in the Order of Index used.
365     * Boolean Array is used to mark the position of array as true if solvable by Index, default is false.
366     * Conditions of combinations of Equal Predicate are allowed to be solvable by Index
367     * Example
368     * Conditions Like
369     * A = 3 and B < 3
370     * A = 5 and B > 4 are allowed
371     * Conditions Like
372     * A = 3 and B < 3 and B > 4
373     * A > 3 and B < 4
374     * A = 3 and B < 4 --> Range Predicate
375     * A > 2 and B < 3 are not allowed
376     * Reason for this is Btree Condition evaluation problem say for example
377     * Predicate is A > 2 and B < 3
378     * and data in Table is (3,1), (3,2), (4,1), (4,2)
379     * At the first let the pointer in BTree is (4,1), now this node satisfies the condition, and we move
380     * on in this tree.
381     * At the end we are wrong on our result as Nodes (3,2) and (3,1) are left to be included in result.
382     */

383    private void extractIndexedPredicates(int indexToStartOn, boolean[] indexNonIndex, String JavaDoc[] indexColumns, boolean[] indexColumnsOrder, _SingleColumnPredicate[] predicateColumns, ArrayList listOfIndexedColumns, boolean flag) throws DException {
384       if (indexToStartOn >= indexColumns.length) {
385          return;
386       }
387       for (int j = 0; j < predicateColumns.length; ++j) {
388          int predicateType = predicateColumns[j].getPredicateType();
389          if (predicateType == OperatorConstants.RANGE_PREDICATE) {
390             if (predicateColumns[j].getColumnName().equalsIgnoreCase(indexColumns[indexToStartOn])) {
391                listOfIndexedColumns.add(predicateColumns[j]);
392                ++indexToStartOn;
393                indexNonIndex[j] = true; // true means Indexed Condition
394
flag = false;
395             }
396             continue;
397          }
398
399 /* Handling of IN predicate done by Kaushik on 20/07/2004 for solving simple inpredicate through index*/
400          if(predicateType == OperatorConstants.IN){
401            if (predicateColumns[j].getColumnName().equalsIgnoreCase(indexColumns[indexToStartOn])) {
402              if(indexToStartOn==0){
403                listOfIndexedColumns.add(predicateColumns[j]);
404                ++indexToStartOn;
405                indexNonIndex[j] = true; // true means Indexed Condition
406
flag = false;
407              }
408              return;
409            }
410          }
411
412          if (indexColumns[indexToStartOn].equalsIgnoreCase(predicateColumns[j].getColumnName()) && (flag || predicateType == OperatorConstants.EQUALTO)) {
413             flag = predicateType != OperatorConstants.EQUALTO && predicateType != OperatorConstants.JOINCOMPARISONPREDICATE ? false : flag;
414             indexNonIndex[j] = true; // true means Indexed Condition
415
listOfIndexedColumns.add(singleColumnPredicates[j]);
416             ++indexToStartOn;
417             if(flag)
418             extractIndexedPredicates(indexToStartOn, indexNonIndex, indexColumns, indexColumnsOrder, predicateColumns, listOfIndexedColumns, flag);
419             return;
420          }
421       }
422    }
423    /**
424     * Note:-For documentation of following method please refers to _AllColumnPredicate
425     * @return
426     * @throws DException
427     */

428    public booleanvalueexpression getNonIndexedCondition() throws DException {
429       return nonIndexedCondition;
430    }
431
432    public _SingleColumnPredicate[] getSingleColumnPredicates() throws DException {
433       return singleColumnPredicates;
434    }
435
436    public void setNonIndexedCondition(booleanvalueexpression nonIndexedCondition0) {
437       nonIndexedCondition = nonIndexedCondition0;
438    }
439
440    public String JavaDoc getTableName() throws DException {
441       return tableDetails.getActualName();
442    }
443
444    /**
445     * This method is used to make cover of boolean factor on passed predicate.
446     * @param Predicate
447     * @return
448     * @throws DException
449     */

450    private booleanvalueexpression getBooleanValueExpression(predicate Predicate) throws DException {
451       return new booleanfactor(new booleantest(Predicate));
452    }
453    /**
454     * This method is used to generate booleanvalueexpression by merging all
455     * singlecolumnpredicate and nonindexed condition with AND logical operator.
456     * @param singleColumnPredicates
457     * @return
458     * @throws DException
459     */

460    private booleanvalueexpression generateBVE(SingleColumnPredicate[] singleColumnPredicates) throws DException {
461       booleanvalueexpression nonIndexedCondition = this.nonIndexedCondition;
462       for (int i = 0, length = singleColumnPredicates.length; i < length; ++i) {
463          nonIndexedCondition = BVEPlanMerger.addAndConditions(nonIndexedCondition, getBooleanValueExpression(singleColumnPredicates[i].getPredicate()));
464       }
465       return nonIndexedCondition;
466    }
467    public void setTableDetails(TableDetails tableDetails0) throws DException {
468       tableDetails = tableDetails0;
469    }
470    /**
471     * This method is used to set position of index through which indexpredicate
472     * is solved. when indexpredicate are made this method is used to set position
473     * of index.
474     * @param indexPosition0
475     * @throws DException
476     */

477    public void setIndexPosition(int indexPosition0) throws DException {
478       indexPosition = indexPosition0;
479    }
480
481    public String JavaDoc toString() {
482       String JavaDoc str = "ALLCOLUMNPREDICATE[";
483       str += "TABLEDETAIL = " + tableDetails + "";
484       if (singleColumnPredicates != null) {
485          for (int i = 0; i < singleColumnPredicates.length; i++) {
486             str += "SINGLECOLPREDICATE[" + singleColumnPredicates[i] + "]";
487          }
488       }
489       if (nonIndexedCondition != null) {
490          str += "NONINDEXEDCONDITION[" + nonIndexedCondition + "]";
491       }
492       return str + "]";
493
494    }
495
496
497    private boolean checkForFunctionalAndScalarColumn(ColumnDetails[] cd) throws DException{
498      for (int i = 0; i < cd.length; i++) {
499        if(cd[i].getType()==TypeConstants.FUNCTIONAL || cd[i].getType()==TypeConstants.SCALARFUNCTION)
500          return true;
501      }
502      return false;
503    }
504
505 /* Returns whether passed value equals to any of following values. NOTEQUALTO not matched as it already been added to NonIndexed Condition */
506
507 }
508
Popular Tags