File D:\maven-qcr-plugin-testsunitaires\qcr4java\h2-1.3.170-sources\target\site\qc\lecode\table\Plan.java.html

1 /*
2 * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
3 * Version 1.0, and under the Eclipse Public License, Version 1.0
4 * (http://h2database.com/html/license.html).
5 * Initial Developer: H2 Group
6 */
7 package org.h2.table;
8
9 import java.util.ArrayList;
10 import java.util.HashMap;
11 import org.h2.engine.Session;
12 import org.h2.expression.Expression;
13 import org.h2.expression.ExpressionVisitor;
14 import org.h2.table.TableFilter.TableFilterVisitor;
15 import org.h2.util.New;
16
17 /**
18 * A possible query execution plan. The time required to execute a query depends
19 * on the order the tables are accessed.
20 */
21 public class Plan {
22
23 private final TableFilter[] filters;
24 private final HashMap<TableFilter, PlanItem> planItems = New.hashMap();
25 private final Expression[] allConditions;
26 private final TableFilter[] allFilters;
27
28 /**
29 * Create a query plan with the given order.
30 *
31 * @param filters the tables of the query
32 * @param count the number of table items
33 * @param condition the condition in the WHERE clause
34 */
35 public Plan(TableFilter[] filters, int count, Expression condition) {
36 this.filters = new TableFilter[count];
37 System.arraycopy(filters, 0, this.filters, 0, count);
38 final ArrayList<Expression> allCond = New.arrayList();
39 final ArrayList<TableFilter> all = New.arrayList();
40 if (condition != null) {
41 allCond.add(condition);
42 }
43 for (int i = 0; i < count; i++) {
44 TableFilter f = filters[i];
45 f.visit(new TableFilterVisitor() {
46 public void accept(TableFilter f) {
47 all.add(f);
48 if (f.getJoinCondition() != null) {
49 allCond.add(f.getJoinCondition());
50 }
51 }
52 });
53 }
54 allConditions = new Expression[allCond.size()];
55 allCond.toArray(allConditions);
56 allFilters = new TableFilter[all.size()];
57 all.toArray(allFilters);
58 }
59
60 /**
61 * Get the plan item for the given table.
62 *
63 * @param filter the table
64 * @return the plan item
65 */
66 public PlanItem getItem(TableFilter filter) {
67 return planItems.get(filter);
68 }
69
70 /**
71 * The the list of tables.
72 *
73 * @return the list of tables
74 */
75 public TableFilter[] getFilters() {
76 return filters;
77 }
78
79 /**
80 * Remove all index conditions that can not be used.
81 */
82 public void removeUnusableIndexConditions() {
83 for (int i = 0; i < allFilters.length; i++) {
84 TableFilter f = allFilters[i];
85 setEvaluatable(f, true);
86 if (i < allFilters.length - 1 || f.getSession().getDatabase().getSettings().earlyFilter) {
87 // the last table doesn't need the optimization,
88 // otherwise the expression is calculated twice unnecessarily
89 // (not that bad but not optimal)
90 f.optimizeFullCondition(false);
91 }
92 f.removeUnusableIndexConditions();
93 }
94 for (TableFilter f : allFilters) {
95 setEvaluatable(f, false);
96 }
97 }
98
99 /**
100 * Calculate the cost of this query plan.
101 *
102 * @param session the session
103 * @return the cost
104 */
105 public double calculateCost(Session session) {
106 double cost = 1;
107 boolean invalidPlan = false;
108 int level = 1;
109 for (TableFilter tableFilter : allFilters) {
110 PlanItem item = tableFilter.getBestPlanItem(session, level++);
111 planItems.put(tableFilter, item);
112 cost += cost * item.cost;
113 setEvaluatable(tableFilter, true);
114 Expression on = tableFilter.getJoinCondition();
115 if (on != null) {
116 if (!on.isEverything(ExpressionVisitor.EVALUATABLE_VISITOR)) {
117 invalidPlan = true;
118 break;
119 }
120 }
121 }
122 if (invalidPlan) {
123 cost = Double.POSITIVE_INFINITY;
124 }
125 for (TableFilter f : allFilters) {
126 setEvaluatable(f, false);
127 }
128 return cost;
129 }
130
131 private void setEvaluatable(TableFilter filter, boolean b) {
132 filter.setEvaluatable(filter, b);
133 for (Expression e : allConditions) {
134 e.setEvaluatable(filter, b);
135 }
136 }
137 }
138