KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > daffodilwoods > daffodildb > server > sql99 > dql > plan > table > SingleTablePlan


1 package com.daffodilwoods.daffodildb.server.sql99.dql.plan.table;
2
3 import com.daffodilwoods.daffodildb.client.*;
4 import com.daffodilwoods.daffodildb.server.datasystem.indexsystem.*;
5 import com.daffodilwoods.daffodildb.server.datasystem.interfaces.*;
6 import com.daffodilwoods.daffodildb.server.serversystem.*;
7 import com.daffodilwoods.daffodildb.server.sql99.common.*;
8 import com.daffodilwoods.daffodildb.server.sql99.dql.common.*;
9 import com.daffodilwoods.daffodildb.server.sql99.dql.execution.*;
10 import com.daffodilwoods.daffodildb.server.sql99.dql.iterator.*;
11 import com.daffodilwoods.daffodildb.server.sql99.dql.iterator.table.*;
12 import com.daffodilwoods.daffodildb.server.sql99.dql.plan.*;
13 import com.daffodilwoods.daffodildb.server.sql99.dql.plan.condition.*;
14 import com.daffodilwoods.daffodildb.server.sql99.expression.booleanvalueexpression.*;
15 import com.daffodilwoods.daffodildb.server.sql99.utils.*;
16 import com.daffodilwoods.database.general.*;
17 import com.daffodilwoods.database.resource.*;
18 import com.daffodilwoods.database.sqlinitiator.*;
19 import com.daffodilwoods.database.utility.*;
20 import com.daffodilwoods.daffodildb.server.sql99.fulltext.expression.containsclause;
21
22 /**
23  * This class represents the plan for Single Table. It contains single table level
24  * condition, order , max/min aggregates for optimal execution of the query.
25  * It checks whether index can be used for solving condition, order and aggregates.
26  * It provides the functionality of obtaining resultset for single table.
27  * <p>Title: SingleTablePlan</p>
28  * <p>Description: </p>
29  * <p>Copyright: Copyright (c) 2003</p>
30  * <p>Company: Daffodil S/W Ltd.</p>
31  * @author SelectTeam
32  * @version 1.0
33  */

34
35 public class SingleTablePlan extends PlanAbstract implements TableExpressionConstants, _SingleTablePlan {
36
37    /**
38     * Represents the condition of this table like Orders.OrderId = 11000
39     */

40    private booleanvalueexpression singleTableCondition;
41
42    /**
43     * Represents the order of this table.
44     */

45
46    private _Order order;
47    /**
48     * Represents the table.
49     */

50    private TableDetails tableDetail;
51
52    /**
53     * Represents the columns of this table which are involved in query.
54     */

55
56    private String JavaDoc[] queryColumns;
57    /**
58     * Represents the mapping of join condition and total condition of this table
59     * Detailed documentation is given.
60     * This mapping contains the condition against condition.
61     * It is initialized when getCost with Condition is called.
62     * For eg
63     * Select * from Orders , Order Details where Orders.OrderId = 1 and Orders.OrderId = Order Details.OrderId
64     * the Mapping will contain [Orders.OrderId = Order Details.OrderId] [Orders.OrderId = 1 and Orders.OrderId = Order Details.OrderId]
65     * ie JoinCondition against singleTableCondition And JoinCondition
66     * This is maintained beacuse as we are returning the cost for join
67     * condition, and for calculating the cost we've to evaluate all the condition
68     * so if in future it is selected as optimal cost then we've to execute
69     * according to this join condition. That's why mapping is maintained.
70     */

71
72    private Object JavaDoc conditionMappingArray[][];
73
74    /**
75     * Represents the maping of join condition and total condition of this table.
76     * It is initialized in getCostWithoutOrder with condition method.
77     */

78
79    private Object JavaDoc conditionMappingArrayWithoutOrder[][];
80
81    /**
82     * Represents all the tables present in foreign key column.
83     */

84
85    private _TableAlias[] tablelAliasArray; // For FKey Columns
86

87    /**
88     * Represents whether any chained column is present on this table or not.
89     */

90
91    private boolean isForeignKeyIterator; // Is FKey Columns Involved
92

93    /**
94     * Represents whether 'For Update' option is present in select query.
95     */

96
97    private boolean forUpdate;
98
99    /**
100     * These are the aggregate columns and are placed here when aggregates are
101     * present in Single Table query. For taking the help of Indexing in case of
102     * max/min.
103     */

104    private ColumnDetails[] aggregateColumnsForIndexing;
105
106    /**
107     * Used to represent whether user rights needs to be checked on this table or
108     * not.
109     */

110
111    boolean checkUserRight;
112    boolean isInternalIteratorRequired;
113    private _Reference[] underLyingRefofCondition;
114
115    public SingleTablePlan(String JavaDoc tableName,
116                           booleanvalueexpression singleTableCondition0,
117                           TableDetails tableDetail0, _Order order0,
118                           boolean checkUserRight0, ColumnDetails[] columns) throws DException {
119       order = order0;
120       singleTableCondition = singleTableCondition0;
121       tableDetail = tableDetail0;
122       checkUserRight = checkUserRight0;
123       conditionMappingArray = new Object JavaDoc[1][2];
124       conditionMappingArrayWithoutOrder = new Object JavaDoc[1][2];
125       childPlans = new _TablePlan[] {this};
126       initializeTableDetails();
127       initializeQueryColumns(columns);
128
129
130       /* Done by Kauhsik on 1/06/2004 dest*/
131       if(singleTableCondition!=null){
132          underLyingRefofCondition =
133              GeneralPurposeStaticClass.getUnderLyingReferencesOnly(
134       GeneralPurposeStaticClass.getAllReferences(
135      singleTableCondition.getReferences(new TableDetails[] {tableDetail})),
136     new TableDetails[] {tableDetail});
137
138       }
139    }
140
141    /**
142     * This method is used to initialize the columns of this table present in
143     * query.
144     * @param columns
145     * @throws DException
146     */

147
148    private void initializeQueryColumns(ColumnDetails[] columns) throws DException {
149       if (columns == null) {
150          return;
151       }
152       int length = columns.length;
153       queryColumns = new String JavaDoc[length];
154       for (int i = 0; i < length; i++) {
155          queryColumns[i] = columns[i].getColumn();
156       }
157    }
158
159    /**
160     * Sets the condition for this table.
161     * @param singleTableCondition0
162     * @throws DException
163     */

164
165    public void setCondition(booleanvalueexpression singleTableCondition0) throws
166        DException {
167       singleTableCondition = singleTableCondition0;
168    }
169
170    /**
171     * Returns The Type of Plan
172     * @return
173     * @throws DException
174     */

175    public int getType() throws DException {
176       return SINGLETABLEPLAN;
177    }
178
179    /**
180     * Calculates the cost of the solving this singleTablePlan , It takes
181     * care of the SingleTableOrder and SingleTableCondition invloved in the
182     * Query for this table. When the SingleTableCondition is present
183     * ConditionSingleTableExecuter calculated the cost.
184     * @param session
185     * @return
186     * @throws DException
187     */

188
189    public double getCost(_ServerSession session) throws DException {
190       if (singleTableCondition != null) {
191          double cost = new ConditionSingleTableExecuter(order, tableDetail,
192              session, singleTableCondition,
193              queryColumns, aggregateColumnsForIndexing).getCost(session.
194              getIndexTable(tableDetail.getQualifiedIdentifier()));
195          return cost;
196       }
197       double cost = getCostWhenConditionNull(session);
198       return cost;
199    }
200
201    /**
202     * Calculates the cost of the solving this singleTablePlan , It takes
203     * care of the SingleTableCondition invloved in the Query for this table
204     * but does not take care of SingleTableOrder involved as the name of method
205     * suggests. It was called when In Join Plan Right Seek Left is choosen,
206     * in this case there is no need to solve order at single table level.
207     * When the SingleTableCondition is present ConditionSingleTableExecuter
208     * calculated the cost
209     * @param session
210     * @return
211     * @throws DException
212     */

213
214    public double getCostWithoutOrder(_ServerSession session) throws DException {
215       if (singleTableCondition != null) {
216          double cost = new ConditionSingleTableExecuter(null, tableDetail, session,
217              singleTableCondition,
218              queryColumns, aggregateColumnsForIndexing).getCost(session.getIndexTable(tableDetail.
219              getQualifiedIdentifier()));
220          return cost;
221       }
222       double cost = getCostWithoutOrderWhenConditionNull(session);
223       return cost;
224    }
225
226    /**
227     * Calculates the cost of the solving this when SingleTableCondition is
228     * not invloved in the Query for this table, It does not take care of
229     * SingleTableOrder involved as the name of method suggests.
230     * When the SingleTableCondition is present ConditionSingleTableExecuter calculated the cost
231     * @param session
232     * @return
233     * @throws DException
234     */

235
236    private double getCostWithoutOrderWhenConditionNull(_ServerSession session) throws
237        DException {
238       /*Done by Manoj <Unused variable>*/
239       return new SingleTableExecuter(null, tableDetail, session, queryColumns, aggregateColumnsForIndexing).
240           getCost(session.getIndexTable(tableDetail.getQualifiedIdentifier()));
241    }
242
243    /**
244     * Calculates the cost of the solving this singleTablePlan when no
245     * single Level Condition is Present, It takes care of SingleTableOrder
246     * involved. If Order is present then we calculates the cost using
247     * SingleTableExecuter
248     * @param session
249     * @return
250     * @throws DException
251     */

252    private double getCostWhenConditionNull(_ServerSession session) throws
253        DException {
254      /*Done by Manoj <Unused variable>*/
255       return new SingleTableExecuter(order, tableDetail, session, queryColumns, aggregateColumnsForIndexing).
256           getCost(session.getIndexTable(tableDetail.getQualifiedIdentifier()));
257    }
258
259    /**
260     * Calculates the cost of the solving this singleTablePlan with the
261     * condition passed. It changes the mapping array eg for condition like
262     * Select * from Orders , Order Details where Orders.OrderId = 1 and
263     * Orders.OrderId = Order Details.OrderId
264     * the Mapping will contain [Orders.OrderId = Order Details.OrderId] [Orders.OrderId = 1 and Orders.OrderId = Order Details.OrderId]
265     * i.e. JoinCondition against singleTableCOndition And JoinCondition.
266     * And the part of condition which do not belong to this SingleTableOrderPlan
267     * is treated as parameter whose value is supplied by join plan.
268     * @param session , conditionArg like Orders.OrderId = Order Details.OrderId , Rows Of other Table like in above case
269     * Order Details
270     * @return
271     * @throws DException
272     */

273
274    public double getCost(_ServerSession session,
275                          booleanvalueexpression conditionArg, long estimatedRows) throws
276        DException {
277       booleanvalueexpression bve = changeConditionMappingArray(conditionArg, true);
278       long myRows = tableDetail.getTableType() == TypeConstants.VIEW ? 1000 :
279           ( (_ServerSession) session).getEstimatedRowCount(tableDetail.
280           getQualifiedIdentifier());
281       tableDetail.setRowCount(estimatedRows * (myRows == 0 ? 1 : myRows));
282       double cost = getCostWithBve(session, bve);
283       tableDetail.setRowCount( -1);
284       return cost;
285    }
286
287    /**
288     * It changes the mapping array eg for condition like
289     * Select * from Orders , Order Details where Orders.OrderId = 1 and
290     * Orders.OrderId = Order Details.OrderId
291     * the Mapping will contain [Orders.OrderId = Order Details.OrderId] [Orders.OrderId = 1 and Orders.OrderId = Order Details.OrderId]
292     * ie JoinCondition against singleTableCondition And JoinCondition
293     * @param conditionArg
294     * @param order There are two mappings conditionMappingArray and conditionMappingArrayWithoutOrder
295     * if order is involved then conditionMappingArray is changed else
296     * conditionMappingArrayWithoutOrder.
297     * @return
298     * @throws DException
299     */

300
301    private booleanvalueexpression changeConditionMappingArray(
302        booleanvalueexpression conditionArg, boolean order) throws DException {
303       booleanvalueexpression bve = searchCostCaluledFrom(conditionArg, order);
304       if (bve != null) {
305          return bve;
306       }
307
308       bve = singleTableCondition == null ?
309           BVEPlanMerger.getBooleanFactor(new parenthesizedbooleanvalueexpression(
310           conditionArg))
311           : BVEPlanMerger.addAndConditions(conditionArg, singleTableCondition);
312
313       if (order) {
314          conditionMappingArray = incrementAndAddInMapping(conditionMappingArray,
315              conditionArg, bve);
316       } else {
317          conditionMappingArrayWithoutOrder = incrementAndAddInMapping(
318              conditionMappingArrayWithoutOrder, conditionArg, bve);
319       }
320       return bve;
321    }
322
323    /**
324     * This method is used to add the mapping of both passsed condition in the
325     * passed array of mapping.
326     * @param mapping
327     * @param conditionArg
328     * @param bve
329     * @return
330     * @throws DException
331     */

332
333    private Object JavaDoc[][] incrementAndAddInMapping(Object JavaDoc[][] mapping,
334                                                booleanvalueexpression
335                                                conditionArg,
336                                                booleanvalueexpression bve) throws
337        DException {
338       mapping[mapping.length - 1][0] = conditionArg;
339       mapping[mapping.length - 1][1] = bve;
340       Object JavaDoc[][] newMapping = new Object JavaDoc[mapping.length + 1][2];
341       System.arraycopy(mapping, 0, newMapping, 0, mapping.length);
342       return newMapping;
343    }
344
345    /**
346     * Used to remove unexecutable plans in hierarchy of plan, no practical
347     * significance in SingleTablePlan.
348     * @return
349     */

350
351    public _TablePlan joinMissingLink() {
352       return this;
353    }
354
355    /**
356     * Method returns estimate no. Of Rows for this table. If any singleLevel
357     * condition is present in the TablePlan then it reduces the no of rows
358     * depending upon the type of Condition.
359     * @param serverSession
360     * @return
361     * @throws DException
362     */

363
364    public long getRowCount(_ServerSession serverSession) throws DException {
365       long rowCount = tableDetail.getTableType() ==
366           TypeConstants.VIEW ? 1000 :
367           ( (_ServerSession) serverSession).
368           getEstimatedRowCount(tableDetail.getQualifiedIdentifier());
369       if (singleTableCondition == null) {
370          return rowCount;
371       }
372       return singleTableCondition.getEstimatedRows(rowCount);
373    }
374
375    /**
376     * Returns the Iterator For this singleTablePlan .If order could not be
377     * solved by any index then we make the TemporaryIndexIterator. We also
378     * add the layer of SingleTableIterator for information like TableDetails
379     * on iterator level.
380     * It also take care of chained columns present on this table.
381     * @param session
382     * @return
383     * @throws DException
384     */

385
386    public _Iterator execute(_ServerSession session) throws DException {
387       _SingleTableExecuter singleTableExecuter = getSingleTableExecuter(session,
388           singleTableCondition, order);
389    return isForeignKeyIterator ?
390           wrapSingleTableIteratorAndSolveOrder(session,session.getForeignKeyIterator(tableDetail.getQualifiedIdentifier(), singleTableExecuter, tablelAliasArray))
391           : wrapSingleTableIteratorAndSolveOrder(session,session.getIterator(tableDetail.getQualifiedIdentifier(),singleTableExecuter));
392    }
393
394    /**
395     * This method creates the ConditionSingleTableExecuter. It also sets the
396     * flag for 'For Update' option and need of checking user right on this table.
397     * @param session
398     * @param bve
399     * @param order
400     * @return
401     * @throws DException
402     */

403    private _SingleTableExecuter getSingleTableExecuter(_ServerSession session,
404        booleanvalueexpression bve, _Order order) throws DException {
405
406       ConditionSingleTableExecuter ste = new ConditionSingleTableExecuter(order, tableDetail, session, bve, queryColumns, aggregateColumnsForIndexing);
407       if(bve instanceof containsclause)
408         ste.setContainsClauseFlag(true);
409       ste.setUserRight(checkUserRight);
410       if (forUpdate) {
411          ste.setForUpdate();
412       }
413       ste.isInterIteratorRequired(getInternalIteratorRequired());
414       return ste;
415    }
416
417    /**
418     * Adds the Layer of SingleTableIterator and if order is not solvable by
419     * simple index then we create the TemporayIndexIterator.
420     * @param session
421     * @param iterator
422     * @return
423     * @throws DException
424     */

425
426    private _Iterator wrapSingleTableIteratorAndSolveOrder(_ServerSession session,
427        _Iterator iterator) throws DException {
428       iterator = wrapSingleTableIterator(iterator);
429       if (order != null) {
430          iterator = order.isSolvableByIndex() ? order.isSameOrReverse() ? iterator : new ReverseIterator(iterator)
431              : GeneralPurposeStaticClass.getTemporaryIndexIterator(iterator, this, session, order, getDefaultOrder()); //Done by Sandeep to remove default Order
432
}
433       iterator.setSpecificUnderlyingReferences(underLyingRefofCondition);
434       return iterator;
435    }
436
437    /**
438     * Used to make SingleTableIterator.
439     * @param iterator
440     * @return
441     * @throws DException
442     */

443
444    private _Iterator wrapSingleTableIterator(_Iterator iterator) throws
445        DException {
446       iterator = new SingleTableIterator(iterator, tableDetail,
447                                          tableDetail.getUnderLyingFKeyTables(),
448                                          order);
449       return iterator;
450    }
451
452    /**
453     * This method is used to return the default order present on single table.
454     * By default data of single table is sorted on rowid column. It is needed
455     * by temporary index for making values of order unique, so as it can use
456     * the value of order as its key.
457     * @return
458     * @throws DException
459     */

460
461    private _Order getDefaultOrder() throws DException {
462       ColumnDetails rowIdCd = new ColumnDetails();
463       String JavaDoc catalogName = tableDetail.getCatalogName();
464       String JavaDoc schemaName = tableDetail.getSchemaName();
465       rowIdCd.setColumnName(new String JavaDoc[] {catalogName, schemaName,
466                             SystemFields.systemFields[SystemFields.rowId]});
467       rowIdCd.setTableDetails(tableDetail);
468       rowIdCd.setType(TypeConstants.REFERENCE);
469       rowIdCd.setDatatype(Datatype.LONG);
470       rowIdCd.setSize(Datatype.LONGSIZE);
471       return new SelectOrder(new ColumnDetails[] {rowIdCd});
472    }
473
474    /**
475     * Returns this plan.
476     * @return
477     * @throws DException
478     */

479
480    public _SingleTablePlan[] getSingleTablePlans() throws DException {
481       return new SingleTablePlan[] {
482           this};
483    }
484
485    /**
486     * This method is used to obtain the resultset on the basis of passed
487     * condition. It doesn't take care of order while preparing resultset.
488     * @param session
489     * @param bve
490     * @return
491     * @throws DException
492     */

493
494    private _Iterator executeWithOutOrderWithBve(_ServerSession session,
495                                                 booleanvalueexpression bve) throws
496        DException {
497       _SingleTableExecuter ste = getSingleTableExecuter(session, bve, null);
498       if (isForeignKeyIterator) {
499          _Iterator iterator=new SingleTableIterator(session.getForeignKeyIterator(tableDetail.
500              getQualifiedIdentifier(), ste, tablelAliasArray), tableDetail,
501                                         tableDetail.getUnderLyingFKeyTables(),
502                                         order);
503         iterator.setSpecificUnderlyingReferences(underLyingRefofCondition);
504          return iterator;
505       }
506       _Iterator iterator= new SingleTableIterator(session.getIterator(tableDetail.
507                 getQualifiedIdentifier(), ste), tableDetail,
508                                            tableDetail.getUnderLyingFKeyTables(), order);
509       iterator.setSpecificUnderlyingReferences(underLyingRefofCondition);
510       return iterator;
511    }
512
513    /**
514     * This method returns the SingleTableIterator, based upon the passed
515     * condition but without order. In the getCostWithoutOrder with Bve method
516     * we've maintained a mapping of this join condition against the total
517     * condition to be solved at this level.
518     * It also take care of chained columns present on this table.
519     * @param session
520     * @param conditionArg
521     * @param estimatedRowCount
522     * @return
523     * @throws DException
524     */

525
526
527
528    public _Iterator executeWithOutOrder(_ServerSession session,
529                                         booleanvalueexpression condition) throws
530        DException {
531       booleanvalueexpression bve = ( (booleanvalueexpression)
532                                     searchCostCaluledFrom(condition, false));
533       try {
534          return executeWithOutOrderWithBve(session, bve);
535       } catch (UnsupportedOperationException JavaDoc ex) {
536          throw ex;
537       }
538    }
539
540    /**
541     * This method returns the SingleTableIterator, based upon condition but
542     * without order.
543     * It also take care of chained columns present on this table.
544     * @param session
545     * @param conditionArg
546     * @param estimatedRowCount
547     * @return
548     * @throws DException
549     */

550
551    public _Iterator executeWithoutOrder(_ServerSession session) throws
552        DException {
553       _SingleTableExecuter singleTableExecuter = getSingleTableExecuter(session,
554           singleTableCondition, null);
555       return isForeignKeyIterator ?
556           wrapSingleTableIterator(session.getForeignKeyIterator(tableDetail.
557           getQualifiedIdentifier(), singleTableExecuter, tablelAliasArray))
558           : wrapSingleTableIterator(session.getIterator(tableDetail.getQualifiedIdentifier(),
559           singleTableExecuter));
560    }
561
562    /**
563     * Returns the order present on this table.
564     * @return
565     * @throws DException
566     */

567
568    public _Order getOrder() throws DException {
569       return order;
570    }
571
572    /**
573     * This method is used to prepare resultset with the help of passed condition.
574     * It also take care of chained columns present on this table.
575     * @param session
576     * @param bve
577     * @return
578     * @throws DException
579     */

580
581    private _Iterator executeWithBve(_ServerSession session,
582                                     booleanvalueexpression bve) throws
583        DException {
584       _SingleTableExecuter singleTableExecuter = getSingleTableExecuter(session,
585           bve, null);
586       if (isForeignKeyIterator) {
587          return wrapSingleTableIteratorAndSolveOrder(session,
588              session.getForeignKeyIterator(tableDetail.getQualifiedIdentifier(), singleTableExecuter, tablelAliasArray));
589       }
590       return wrapSingleTableIteratorAndSolveOrder(session, session.getIterator(tableDetail.getQualifiedIdentifier(), singleTableExecuter));
591    }
592
593    /**
594     * This method returns the SingleTableIterator, based upon the passed
595     * condition. In the getCost with Bve method we've maintained a mapping
596     * of this join condition against the total condition to be solved at this
597     * level.
598     * @param session
599     * @param condition
600     * @return
601     * @throws DException
602     */

603
604    public _Iterator execute(_ServerSession session,
605                             booleanvalueexpression condition) throws DException {
606       booleanvalueexpression bve = searchCostCaluledFrom(condition, true);
607       return executeWithBve(session, bve);
608    }
609
610    private booleanvalueexpression searchCostCaluledFrom(booleanvalueexpression
611        conditionArg, boolean order) throws DException {
612       Object JavaDoc[][] actualArray = order ? conditionMappingArray :conditionMappingArrayWithoutOrder;
613       for (int i = 0; i < actualArray.length; i++) {
614          if (actualArray[i][0] == conditionArg) {
615             booleanvalueexpression bve = (booleanvalueexpression) actualArray[i][1];
616             return bve;
617          }
618       }
619       return null;
620    }
621
622    private double getCostWithoutOrderWithBve(_ServerSession session,
623                                              booleanvalueexpression bve,
624                                              long estimatedRows) throws
625        DException {
626       return bve.getCost(null, queryColumns,
627                          session.getIndexTable(tableDetail.getQualifiedIdentifier()),
628                          tableDetail, aggregateColumnsForIndexing).getCost();
629    }
630
631    /**
632     * Calculates the cost of the solving this singleTablePlan , It takes
633     * care of the SingleTableCondition invloved in the Query for this table
634     * but does not take care of SingleTableOrder involved as the name of method
635     * suggests. This method also maintains a mapping of passed joinCondition against
636     * the total condition including passed condition as well as singletablecondition.
637     * Also this method take care of passed rows.
638     * It was called when In Join Plan Right Seek Left is choosen,
639     * in that case we can't solve order at single table level.
640     * When the SingleTableCondition is present ConditionSingleTableExecuter
641     * calculated the cost
642     * @param session
643     * @return
644     * @throws DException
645     */

646
647    public double getCostWithoutOrder(_ServerSession session,
648                                      booleanvalueexpression conditionArg,
649                                      long estimatedRowCount) throws DException {
650       booleanvalueexpression bve = changeConditionMappingArray(conditionArg, false);
651       long myRows = tableDetail.getTableType() == TypeConstants.VIEW ? 1000 :
652           ( (_ServerSession) session).getEstimatedRowCount(tableDetail.
653           getQualifiedIdentifier());
654       tableDetail.setRowCount(estimatedRowCount * myRows);
655       double cost = getCostWithoutOrderWithBve(session, bve, estimatedRowCount);
656       tableDetail.setRowCount( -1);
657       return cost;
658    }
659
660    /**
661     * This method returns the estimate of the rows on the basis of this plan's
662     * condition,rows and passed condition and rows.
663     * @param conditionArg
664     * @param estimatedRowCount
665     * @param serverSession
666     * @return
667     * @throws DException
668     */

669    public long getEstimatedRows(booleanvalueexpression conditionArg,
670                                 long estimatedRowCount,
671                                 _ServerSession serverSession) throws DException {
672       booleanvalueexpression condition1 = BVEPlanMerger.addAndConditions(
673           singleTableCondition, conditionArg);
674       return condition1.getEstimatedRows(estimatedRowCount);
675    }
676
677    /**
678     * This methdo allows user to obtain the cost of solving condition on this
679     * table.
680     * @param session
681     * @param bve
682     * @return
683     * @throws DException
684     */

685
686    private double getCostWithBve(_ServerSession session,
687                                  booleanvalueexpression bve) throws DException {
688       return bve.getCost(order, queryColumns,
689                          session.getIndexTable(tableDetail.getQualifiedIdentifier()),
690                          tableDetail, aggregateColumnsForIndexing).getCost();
691    }
692
693    public String JavaDoc toString() {
694       try {
695          StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
696          buffer.append("SINGLETABLEPLAN[" + tableDetail.getQualifiedTableName() +
697                        "]");
698          if (singleTableCondition != null) {
699             buffer.append("[" + singleTableCondition + "][" +
700                           singleTableCondition.hashCode() + "]");
701          }
702          if (order != null) {
703             buffer.append("[" + order + "]");
704          }
705          if (order == null) {
706             buffer.append("[" + null +"]");
707          }
708          return buffer.toString();
709       } catch (DException d) {
710          return null;
711       }
712
713    }
714
715    /**
716     * This method is used to return table.
717     * @return
718     * @throws DException
719     */

720
721    public TableDetails[] getTableDetails() throws DException {
722
723      return new TableDetails[] {
724          tableDetail};
725    }
726
727    /**
728     * This method is used to return table. It is similar to getTableDetails
729     * method. It differs only when view is present in query.
730     * @return
731     * @throws DException
732     */

733
734    public TableDetails[] getViewTableDetails() throws DException {
735       return getTableDetails();
736    }
737
738    public String JavaDoc getVerifier() {
739       try {
740          StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
741          inc();
742          buffer.append(tabW("[ SINGLE_TABLE_PLAN ]"));
743          inc();
744          buffer.append(tab("[Table = " + tableDetail.getQualifiedTableName() + "]"));
745          if (singleTableCondition != null) {
746             buffer.append("[Condition = " + singleTableCondition + "]");
747          }
748          if (order != null) {
749             buffer.append("[Order = " + order + "]");
750          }
751          if (order == null) {
752             buffer.append("[Order = " + null +"]");
753          }
754          dec();
755          buffer.append(tab("[/ SINGLE_TABLE_PLAN ]"));
756          dec();
757          return buffer.toString();
758       } catch (DException ex) {
759          return null;
760       }
761    }
762
763    /**
764     * Checks whether the tableDetails is present in this SingleTablePlan Passed
765     * @param tableDetails0
766     * @return
767     * @throws DException
768     */

769
770    public boolean ifExists(TableDetails tableDetails0) throws DException {
771       return tableDetails0 == tableDetail;
772    }
773
774    /**
775     * Returns the plan for this table.
776     * @return
777     * @throws DException
778     */

779
780    public _QueryPlan getQueryPlan() throws DException {
781       _QueryPlan[] cplans = null;
782       String JavaDoc cond = singleTableCondition == null ? null :
783           ("" + singleTableCondition);
784       String JavaDoc ord = order == null ? null : ("" + order);
785       return new QueryPlan("SingleTablePlan " + tableDetail.getQualifiedTableName(),
786                            cplans, cond, ord);
787    }
788
789    /**
790     * This method is used to provide underlying plans. But as it is leaf level,
791     * it returns itself.
792     * @return
793     * @throws DException
794     */

795
796    public _TablePlan[] getChildTablePlans() throws DException {
797       return childPlans;
798    }
799
800    /**
801     * Sets the order for this table.
802     * @param order
803     * @throws DException
804     */

805
806    public void setOrder(_Order order) throws DException {
807       this.order = order;
808    }
809
810    /**
811     * This method checks whether passed aggregates columns can be solved with
812     * the help of index.
813     * @param columns
814     * @param session
815     * @return
816     * @throws DException
817     */

818
819    public boolean setAggregateColumnsForIndexing(ColumnDetails[] columns, _ServerSession session) throws
820        DException {
821       _IndexTable indexTable = session.getIndexTable(tableDetail.getQualifiedIdentifier());
822       _IndexInformation[] indexInformations = indexTable.getIndexInformations();
823       for (int i = 0; i < indexInformations.length; i++) {
824          if (TableReferenceMerger.checkForAggregateColumn(columns[0].getExistingColumnDetails()[0], indexInformations[i])) {
825             aggregateColumnsForIndexing = columns;
826             return true;
827          }
828       }
829       return false;
830    }
831
832    /**
833     * This method is used to check whether any unexecutable plan exists in
834     * hierarchy of plan.
835     * @return
836     * @throws com.daffodilwoods.database.resource.DException
837     */

838
839    public boolean containsOrderSequencePlan() throws com.daffodilwoods.database.
840
       resource.DException {
841       return false;
842    }
843
844    /**
845     * Sets 'for update' option is present in query.
846     */

847    public void setForUpdate() {
848       forUpdate = true;
849    }
850    public void setInternalIteratorRequired( boolean isInternal){
851        isInternalIteratorRequired = isInternal;
852    }
853    public boolean getInternalIteratorRequired(){
854      return isInternalIteratorRequired;
855    }
856 }
857
Popular Tags