MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
InPredicateImpl.java
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 import java.util.List;
21 
22 import com.mysql.clusterj.ClusterJException;
23 import com.mysql.clusterj.ClusterJUserException;
24 import com.mysql.clusterj.core.spi.QueryExecutionContext;
25 import com.mysql.clusterj.core.store.IndexScanOperation;
26 import com.mysql.clusterj.core.store.ScanFilter;
27 import com.mysql.clusterj.core.store.ScanOperation;
28 import com.mysql.clusterj.core.store.IndexScanOperation.BoundType;
29 import com.mysql.clusterj.core.store.ScanFilter.BinaryCondition;
30 import com.mysql.clusterj.core.store.ScanFilter.Group;
31 
32 public class InPredicateImpl extends PredicateImpl {
33 
36 
39 
40  public InPredicateImpl(QueryDomainTypeImpl<?> dobj,
42  super(dobj);
43  this.property = property;
44  this.parameter = parameter;
45  parameter.setProperty(property);
46  // mark this property as having complex values
47  property.setComplexParameter();
48  }
49 
50  @Override
51  public void markParameters() {
52  parameter.mark();
53  }
54 
55  @Override
56  public void unmarkParameters() {
57  parameter.unmark();
58  }
59 
60  @Override
61  void markBoundsForCandidateIndices(QueryExecutionContext context,
62  CandidateIndexImpl[] candidateIndices) {
63  if (parameter.getParameterValue(context) == null) {
64  // null parameters cannot be used with index scans
65  return;
66  }
67  property.markInBound(candidateIndices, this);
68  }
69 
77  public void operationSetBound(
78  QueryExecutionContext context, IndexScanOperation op, int index, boolean lastColumn) {
79  if (lastColumn) {
80  // last column can be strict
81  operationSetBound(context, op, index, BoundType.BoundEQ);
82  } else {
83  // not last column cannot be strict
84  operationSetBound(context, op, index, BoundType.BoundLE);
85  operationSetBound(context, op, index, BoundType.BoundGE);
86  }
87  }
88 
89  public void operationSetUpperBound(QueryExecutionContext context, IndexScanOperation op, int index) {
90  operationSetBound(context, op, index, BoundType.BoundGE);
91  }
92 
93  public void operationSetLowerBound(QueryExecutionContext context, IndexScanOperation op, int index) {
94  operationSetBound(context, op, index, BoundType.BoundLE);
95  }
96 
97  private void operationSetBound(
98  QueryExecutionContext context, IndexScanOperation op, int index, BoundType boundType) {
99  Object parameterValue = parameter.getParameterValue(context);
100  if (parameterValue == null) {
101  throw new ClusterJUserException(
102  local.message("ERR_Parameter_Cannot_Be_Null", "operator in", parameter.parameterName));
103  } else if (parameterValue instanceof List<?>) {
104  List<?> parameterList = (List<?>)parameterValue;
105  Object value = parameterList.get(index);
106  property.operationSetBounds(value, boundType, op);
107  if (logger.isDetailEnabled()) logger.detail("InPredicateImpl.operationSetBound for " + property.fmd.getName() + " List index: " + index + " value: " + value + " boundType: " + boundType);
108  } else if (parameterValue.getClass().isArray()) {
109  Object[] parameterArray = (Object[])parameterValue;
110  Object value = parameterArray[index];
111  property.operationSetBounds(value, boundType, op);
112  if (logger.isDetailEnabled()) logger.detail("InPredicateImpl.operationSetBound for " + property.fmd.getName() + " array index: " + index + " value: " + value + " boundType: " + boundType);
113  } else {
114  throw new ClusterJUserException(
115  local.message("ERR_Parameter_Wrong_Type", parameter.parameterName,
116  parameterValue.getClass().getName(), "List<?> or Object[]"));
117  }
118  }
119 
128  IndexScanOperation op) {
129  Object parameterValue = parameter.getParameterValue(context);
130  int index = 0;
131  if (parameterValue == null) {
132  throw new ClusterJUserException(
133  local.message("ERR_Parameter_Cannot_Be_Null", "operator in", parameter.parameterName));
134  } else if (parameterValue instanceof List<?>) {
135  List<?> parameterList = (List<?>)parameterValue;
136  for (Object value: parameterList) {
137  property.operationSetBounds(value, BoundType.BoundEQ, op);
138  if (logger.isDetailEnabled()) logger.detail("InPredicateImpl.operationSetAllBounds for List index: " + index + " value: " + value);
139  op.endBound(index++);
140  }
141  } else if (parameterValue.getClass().isArray()) {
142  Object[] parameterArray = (Object[])parameterValue;
143  for (Object value: parameterArray) {
144  property.operationSetBounds(value, BoundType.BoundEQ, op);
145  if (logger.isDetailEnabled()) logger.detail("InPredicateImpl.operationSetAllBounds for array index: " + index + " value: " + value);
146  op.endBound(index++);
147  }
148  } else {
149  throw new ClusterJUserException(
150  local.message("ERR_Parameter_Wrong_Type", parameter.parameterName,
151  parameterValue.getClass().getName(), "List<?> or Object[]"));
152  }
153  }
154 
161  ScanOperation op) {
162  try {
163  ScanFilter filter = op.getScanFilter(context);
164  filterCmpValue(context, op, filter);
165  } catch (ClusterJException ex) {
166  throw ex;
167  } catch (Exception ex) {
168  throw new ClusterJException(
169  local.message("ERR_Get_NdbFilter"), ex);
170  }
171  }
172 
180  try {
181  filter.begin(Group.GROUP_OR);
182  Object parameterValue = parameter.getParameterValue(context);
183  if (parameterValue == null) {
184  throw new ClusterJUserException(
185  local.message("ERR_Parameter_Cannot_Be_Null", "operator in", parameter.parameterName));
186  } else if (parameterValue instanceof Iterable<?>) {
187  Iterable<?> iterable = (Iterable<?>)parameterValue;
188  for (Object value: iterable) {
189  property.filterCmpValue(value, BinaryCondition.COND_EQ, filter);
190  }
191  } else if (parameterValue.getClass().isArray()) {
192  Object[] parameterArray = (Object[])parameterValue;
193  for (Object parameter: parameterArray) {
194  property.filterCmpValue(parameter, BinaryCondition.COND_EQ, filter);
195  }
196  } else {
197  throw new ClusterJUserException(
198  local.message("ERR_Parameter_Wrong_Type", parameter.parameterName,
199  parameterValue.getClass().getName(), "Iterable<?> or Object[]"));
200  }
201  filter.end();
202  } catch (ClusterJException ex) {
203  throw ex;
204  } catch (Exception ex) {
205  throw new ClusterJException(
206  local.message("ERR_Get_NdbFilter"), ex);
207  }
208  }
209 
210  public int getParameterSize(QueryExecutionContext context) {
211  int result = 1;
212  Object parameterValue = parameter.getParameterValue(context);
213  if (parameterValue instanceof List<?>) {
214  result = ((List<?>)parameterValue).size();
215  }
216  Class<?> cls = parameterValue.getClass();
217  if (cls.isArray()) {
218  if (!Object.class.isAssignableFrom(cls.getComponentType())) {
219  throw new ClusterJUserException(local.message("ERR_Wrong_Parameter_Type_For_In",
220  property.fmd.getName()));
221  }
222  Object[] parameterArray = (Object[])parameterValue;
223  result = parameterArray.length;
224  }
225  if (result > 4096) {
226  throw new ClusterJUserException(local.message("ERR_Parameter_Too_Big_For_In",
227  property.fmd.getName(), result));
228  }
229  // single value parameter
230  return result;
231  }
232 
233 }