]> review.fuel-infra Code Review - packages/trusty/mysql-wsrep-5.6.git/blob
d1820819f98d4d377e91f2474222d70a17e4bb5a
[packages/trusty/mysql-wsrep-5.6.git] /
1 /*
2    Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; version 2 of the License.
7
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12
13    You should have received a copy of the GNU General Public License
14    along with this program; if not, write to the Free Software
15    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
16 */
17
18 package com.mysql.clusterj.core.query;
19
20
21 import com.mysql.clusterj.ClusterJException;
22 import com.mysql.clusterj.ClusterJFatalInternalException;
23 import com.mysql.clusterj.ClusterJUserException;
24
25 import com.mysql.clusterj.core.spi.QueryExecutionContext;
26 import com.mysql.clusterj.core.store.IndexScanOperation;
27 import com.mysql.clusterj.core.store.Operation;
28 import com.mysql.clusterj.core.store.ScanFilter;
29 import com.mysql.clusterj.core.store.ScanOperation;
30
31 import com.mysql.clusterj.core.util.I18NHelper;
32 import com.mysql.clusterj.core.util.Logger;
33 import com.mysql.clusterj.core.util.LoggerFactoryService;
34
35 import com.mysql.clusterj.query.Predicate;
36
37 public abstract class PredicateImpl implements Predicate {
38
39     /** My message translator */
40     static final I18NHelper local = I18NHelper.getInstance(PredicateImpl.class);
41
42     /** My logger */
43     static final Logger logger = LoggerFactoryService.getFactory().getInstance(PredicateImpl.class);
44
45     /** My domain object. */
46     protected QueryDomainTypeImpl<?> dobj;
47
48     /** Scan types. */
49     protected enum ScanType {
50         INDEX_SCAN,
51         TABLE_SCAN,
52         UNIQUE_KEY,
53         PRIMARY_KEY
54     }
55
56     public PredicateImpl(QueryDomainTypeImpl<?> dobj) {
57         this.dobj = dobj;
58     }
59
60     public Predicate or(Predicate other) {
61         assertPredicateImpl(other);
62         PredicateImpl otherPredicateImpl = (PredicateImpl)other;
63         assertIdenticalDomainObject(otherPredicateImpl, "or");
64         return new OrPredicateImpl(this.dobj, this, otherPredicateImpl);
65     }
66
67     public Predicate and(Predicate other) {
68         assertPredicateImpl(other);
69         PredicateImpl predicateImpl = (PredicateImpl)other;
70         assertIdenticalDomainObject(predicateImpl, "and");
71         if (other instanceof AndPredicateImpl) {
72             AndPredicateImpl andPredicateImpl = (AndPredicateImpl)other;
73             return andPredicateImpl.and(this);
74         } else {
75             return new AndPredicateImpl(dobj, this, predicateImpl);
76         }
77     }
78
79     public Predicate not() {
80         return new NotPredicateImpl(this);
81     }
82
83     void markBoundsForCandidateIndices(QueryExecutionContext context, CandidateIndexImpl[] candidateIndices) {
84         throw new ClusterJFatalInternalException(
85                 local.message("ERR_Implementation_Should_Not_Occur"));
86     }
87
88     public void operationSetBounds(QueryExecutionContext context,
89             IndexScanOperation op, boolean lastColumn) {
90         throw new ClusterJFatalInternalException(
91                 local.message("ERR_Implementation_Should_Not_Occur"));
92     }
93
94     public void operationSetLowerBound(QueryExecutionContext context,
95             IndexScanOperation op, boolean lastColumn) {
96         throw new ClusterJFatalInternalException(
97                 local.message("ERR_Implementation_Should_Not_Occur"));
98     }
99
100     public void operationSetUpperBound(QueryExecutionContext context,
101             IndexScanOperation op, boolean lastColumn){
102         throw new ClusterJFatalInternalException(
103                 local.message("ERR_Implementation_Should_Not_Occur"));
104     }
105
106     public void operationEqual(QueryExecutionContext context,
107             Operation op) {
108         throw new ClusterJFatalInternalException(
109                 local.message("ERR_Implementation_Should_Not_Occur"));
110     }
111
112     public void operationEqualFor(QueryExecutionContext context,
113             Operation op, String indexName) {
114         throw new ClusterJFatalInternalException(
115                 local.message("ERR_Implementation_Should_Not_Occur"));
116     }
117
118     public void objectSetValuesFor(QueryExecutionContext context,
119             Object row, String indexName) {
120         throw new ClusterJFatalInternalException(
121                 local.message("ERR_Implementation_Should_Not_Occur"));
122     }
123
124     /** Create a filter for the operation. Set the condition into the
125      * new filter.
126      * @param context the query execution context with the parameter values
127      * @param op the operation
128      */
129     public void filterCmpValue(QueryExecutionContext context,
130             ScanOperation op) {
131         try {
132             ScanFilter filter = op.getScanFilter(context);
133             filter.begin();
134             filterCmpValue(context, op, filter);
135             filter.end();
136         } catch (ClusterJException ex) {
137             throw ex;
138         } catch (Exception ex) {
139             throw new ClusterJException(
140                     local.message("ERR_Get_NdbFilter"), ex);
141         }
142     }
143
144     public void filterCmpValue(QueryExecutionContext context,
145             ScanOperation op, ScanFilter filter) {
146         throw new ClusterJFatalInternalException(
147                 local.message("ERR_Implementation_Should_Not_Occur"));
148     }
149
150     public void assertIdenticalDomainObject(PredicateImpl other, String venue) {
151         QueryDomainTypeImpl<?> otherDomainObject = other.getDomainObject();
152         if (dobj != otherDomainObject) {
153             throw new ClusterJUserException(
154                     local.message("ERR_Wrong_Domain_Object", venue));
155         }
156     }
157
158     /** Mark this predicate as being satisfied. */
159     void setSatisfied() {
160         throw new UnsupportedOperationException("Not yet implemented");
161     }
162
163     /** Mark all parameters as being required. */
164     public abstract void markParameters();
165
166     /** Unmark all parameters as being required. */
167     public abstract void unmarkParameters();
168
169     private void assertPredicateImpl(Predicate other) {
170         if (!(other instanceof PredicateImpl)) {
171             throw new UnsupportedOperationException(
172                     local.message("ERR_NotImplemented"));
173         }
174     }
175
176     private QueryDomainTypeImpl<?> getDomainObject() {
177         return dobj;
178     }
179
180     public CandidateIndexImpl getBestCandidateIndex(QueryExecutionContext context) {
181         return getBestCandidateIndexFor(context, this);
182     }
183
184     /** Get the best candidate index for the query, considering all indices
185      * defined and all predicates in the query.
186      * @param predicates the predicates
187      * @return the best index for the query
188      */
189     protected CandidateIndexImpl getBestCandidateIndexFor(QueryExecutionContext context,
190             PredicateImpl... predicates) {
191         // Create CandidateIndexImpl to decide how to scan.
192         CandidateIndexImpl[] candidateIndices = dobj.createCandidateIndexes();
193         // Iterate over predicates and have each one register with
194         // candidate indexes.
195         for (PredicateImpl predicateImpl : predicates) {
196             predicateImpl.markBoundsForCandidateIndices(context, candidateIndices);
197         }
198         // Iterate over candidate indices to find one that is usable.
199         int highScore = 0;
200         // Holder for the best index; default to the index for null where clause
201         CandidateIndexImpl bestCandidateIndexImpl = 
202                 CandidateIndexImpl.getIndexForNullWhereClause();
203         // Hash index operations require the predicates to have no extra conditions
204         // beyond the index columns.
205         int numberOfConditions = getNumberOfConditionsInPredicate();
206         for (CandidateIndexImpl candidateIndex : candidateIndices) {
207             if (candidateIndex.supportsConditionsOfLength(numberOfConditions)) {
208                 // opportunity for a user-defined plugin to evaluate indices
209                 int score = candidateIndex.getScore();
210                 if (logger.isDetailEnabled()) {
211                     logger.detail("Score: " + score + " from " + candidateIndex);
212                 }
213                 if (score > highScore) {
214                     bestCandidateIndexImpl = candidateIndex;
215                     highScore = score;
216                 }
217             }
218         }
219         if (logger.isDetailEnabled()) logger.detail("High score: " + highScore
220                 + " from " + bestCandidateIndexImpl.getIndexName());
221         return bestCandidateIndexImpl;
222     }
223
224     /** Get the number of conditions in the top level predicate.
225      * This is used to determine whether a hash index can be used. If there
226      * are exactly the number of conditions as index columns, then the
227      * hash index might be used.
228      * By default (for equal, greaterThan, lessThan, greaterEqual, lessEqual)
229      * there is one condition.
230      * AndPredicateImpl overrides this method.
231      * @return the number of conditions
232      */
233     protected int getNumberOfConditionsInPredicate() {
234         return 1;
235     }
236
237 }