1 martin 1.17 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.18 //
|
3 martin 1.17 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
|
9 martin 1.18 //
|
10 martin 1.17 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
|
16 martin 1.18 //
|
17 martin 1.17 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.18 //
|
20 martin 1.17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.18 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27 martin 1.18 //
|
28 martin 1.17 //////////////////////////////////////////////////////////////////////////
|
29 chuck 1.2 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
32 #include <Pegasus/Common/InternalException.h>
33 #include "CQLSimplePredicate.h"
34 #include "CQLSimplePredicateRep.h"
35 //#include <Pegasus/CQL/CQLExpression.h>
36 #include <Pegasus/CQL/CQLFactory.h>
37 #include <Pegasus/Query/QueryCommon/QueryContext.h>
38 #include <Pegasus/Query/QueryCommon/QueryException.h>
|
39 humberto 1.4 #include <Pegasus/Common/Tracer.h>
|
40 chuck 1.2
41 PEGASUS_NAMESPACE_BEGIN
42
43 CQLSimplePredicateRep::CQLSimplePredicateRep(){
|
44 karl 1.14 _isSimple = true;
45 _operator = NOOP;
|
46 chuck 1.2 }
47
48 CQLSimplePredicateRep::CQLSimplePredicateRep(const CQLExpression& inExpression)
49 {
|
50 karl 1.14 _leftSide = inExpression;
51 _isSimple = true;
52 _operator = NOOP;
|
53 chuck 1.2 }
54
55 CQLSimplePredicateRep::CQLSimplePredicateRep(const CQLExpression& inExpression,
|
56 karl 1.14 ExpressionOpType inOperator)
|
57 chuck 1.2 {
|
58 karl 1.14 _leftSide = inExpression;
59 _operator = inOperator;
60 _isSimple = true;
|
61 chuck 1.2 }
62
|
63 karl 1.14 CQLSimplePredicateRep::CQLSimplePredicateRep(
64 const CQLExpression& leftSideExpression,
65 const CQLExpression& rightSideExpression,
66 ExpressionOpType inOperator)
|
67 chuck 1.2 {
|
68 karl 1.14 _leftSide = leftSideExpression;
69 _rightSide = rightSideExpression;
70 _operator = inOperator;
71 _isSimple = false;
|
72 chuck 1.2 }
73
|
74 karl 1.14 CQLSimplePredicateRep::CQLSimplePredicateRep(const CQLSimplePredicateRep* rep)
75 {
76 _leftSide = rep->_leftSide;
77 _rightSide = rep->_rightSide;
78 _operator = rep->_operator;
79 _isSimple = rep->_isSimple;
|
80 chuck 1.2 }
81
82 Boolean CQLSimplePredicateRep::evaluate(CIMInstance CI, QueryContext& QueryCtx)
83 {
|
84 karl 1.14 PEG_METHOD_ENTER(TRC_CQL, "CQLSimplePredicateRep::evaluate");
85 // Resolve the value of the left side
86 CQLValue leftVal = _leftSide.resolveValue(CI, QueryCtx);
87
88 // If there isn't a right side then operator must by IS_NULL
89 // or IS_NOT_NULL
90 if (isSimple())
91 {
92 PEGASUS_ASSERT(_operator == IS_NULL || _operator == IS_NOT_NULL);
93
94 return (_operator == IS_NULL) ? leftVal.isNull() : !leftVal.isNull();
95 }
96
97 PEGASUS_ASSERT(_operator != IS_NULL && _operator != IS_NOT_NULL);
98
99 if (_operator == ISA)
100 {
101 // Special processing for ISA. The CQLValue on the right side of ISA
102 // has a CQLChainedIdentifier with one element that contains
103 // the class name. We don't want to resolve the right side because
104 // CQLValue would assume that a single element chained identifier
105 karl 1.14 // refers to an instance of the FROM class.
106 if (!_rightSide.isSimpleValue())
107 {
108 MessageLoaderParms parms(
109 "CQL.CQLSimplePredicateRep.RHS_ISA_NOT_SIMPLE",
110 "The expression $0 on the right side of the ISA operator"
111 " must be a simple value.",
112 _rightSide.toString());
113 throw CQLRuntimeException(parms);
114 }
115
116 CQLValue isaRightVal =
117 _rightSide.getTerms()[0].getFactors()[0].getValue();
|
118 chuck 1.2
|
119 karl 1.14 CQLChainedIdentifier isaRightId = isaRightVal.getChainedIdentifier();
120 return leftVal.isa(isaRightId, QueryCtx);
121 }
|
122 chuck 1.2
|
123 karl 1.14 if (_operator == LIKE)
124 {
|
125 chuck 1.2 // Special processing for LIKE. The right side expression must be
126 // a simple CQLValue (ie. not nested, and not a function), and
127 // must be a literal. Note that this code will test whether
128 // the right side is a literal, but not whether it is a string
129 // literal.
130 if (!_rightSide.isSimpleValue())
131 {
|
132 karl 1.14 MessageLoaderParms parms(
133 "CQL.CQLSimplePredicateRep.RHS_LIKE_NOT_SIMPLE",
134 "The expression $0 on the right side of the LIKE operator must "
135 "be a simple value.",
136 _rightSide.toString());
137 throw CQLRuntimeException(parms);
|
138 chuck 1.2 }
|
139 karl 1.14
140 CQLValue likeRightVal =
141 _rightSide.getTerms()[0].getFactors()[0].getValue();
|
142 chuck 1.2 if (!likeRightVal.isResolved())
143 {
|
144 karl 1.14 MessageLoaderParms parms(
145 "CQL.CQLSimplePredicateRep.RHS_LIKE_NOT_LITERAL",
146 "The expression $0 on the right side of the LIKE operator must "
147 "be a literal.",
148 _rightSide.toString());
149 throw CQLRuntimeException(parms);
|
150 chuck 1.2 }
|
151 karl 1.14
|
152 chuck 1.2 return leftVal.like(likeRightVal);
|
153 karl 1.14 }
|
154 chuck 1.2
|
155 karl 1.14 // No special processing needed.
156 // Resolve the value of the right side
157 CQLValue rightVal = _rightSide.resolveValue(CI, QueryCtx);
158
159 switch(_operator)
160 {
161 case LT:
162 return leftVal < rightVal;
163 break;
164
165 case GT:
166 return leftVal > rightVal;
167 break;
168
169 case LE:
170 return leftVal <= rightVal;
171 break;
172
173 case GE:
174 return leftVal >= rightVal;
175 break;
176 karl 1.14
177 case EQ:
178 return leftVal == rightVal;
179 break;
180
181 case NE:
182 return leftVal != rightVal;
183 break;
184
185 case LIKE:
186 case ISA:
187 // Never get here due to special processing above.
188 PEGASUS_ASSERT(false);
189 case IS_NULL:
190 case IS_NOT_NULL:
191 case NOOP:
192 // Never get here due to the assert.
193 break;
194 }
195 PEG_METHOD_EXIT();
196 return true; // keep the compiler happy
|
197 chuck 1.2 }
198
199 CQLExpression CQLSimplePredicateRep::getLeftExpression()const
200 {
|
201 karl 1.14 return _leftSide;
|
202 chuck 1.2 }
203
204 CQLExpression CQLSimplePredicateRep::getRightExpression()const
205 {
206 return _rightSide;
207 }
208
209 enum ExpressionOpType CQLSimplePredicateRep::getOperation()const
210 {
|
211 karl 1.14 return _operator;
|
212 chuck 1.2 }
213
|
214 vijay.eli 1.12 void CQLSimplePredicateRep::applyContext(const QueryContext& queryContext)
|
215 chuck 1.2 {
|
216 karl 1.14 PEG_METHOD_ENTER(TRC_CQL, "CQLSimplePredicateRep::applyContext");
217 CQLIdentifier _id;
218
219 _id = _leftSide.getTerms()[0].getFactors()[0].
|
220 chuck 1.2 getValue().getChainedIdentifier().getLastIdentifier();
|
221 karl 1.14
222 if(_leftSide.isSimpleValue() &&
223 _id.isSymbolicConstant() &&
224 _id.getName().getString().size() == 0)
225 {
226 // We have a standalone symbolic constant.
227 if(!isSimple() &&
|
228 chuck 1.2 _rightSide.isSimpleValue() &&
229 _rightSide.getTerms()[0].getFactors()[0].
230 getValue().getChainedIdentifier().getLastIdentifier().
231 getName().getString().size() > 0)
|
232 karl 1.14 {
233 _rightSide.applyContext(queryContext);
234
235 // We need to add context to the symbolic constant
236 _leftSide.applyContext(queryContext,
237 _rightSide.getTerms()[0].getFactors()[0].
238 getValue().getChainedIdentifier());
239 }
240 else
241 {
242 // There is no valid context for the symbolic constant
243 MessageLoaderParms parms("CQL.CQLSimplePredicateRep."
244 "RIGHT_STANDALONE_SYMCONST_ERROR",
245 "The right side of predicate $0 must be a simple property "
246 "name because a symbolic constant exists on the left side.",
247 toString());
248 throw CQLSyntaxErrorException(parms);
249 }
250 }
251 else
252 {
253 karl 1.14 _leftSide.applyContext(queryContext);
254 }
|
255 chuck 1.2
|
256 karl 1.14 if (!isSimple())
257 {
258 _id = _rightSide.getTerms()[0].getFactors()[0].
|
259 chuck 1.2 getValue().getChainedIdentifier().getLastIdentifier();
260
|
261 karl 1.14 if(_rightSide.isSimpleValue() &&
262 _id.isSymbolicConstant() &&
263 _id.getName().getString().size() == 0)
|
264 chuck 1.2 {
|
265 karl 1.14 // We have a standalone symbolic constant.
266 if(!isSimple() &&
267 _leftSide.isSimpleValue() &&
268 _leftSide.getTerms()[0].getFactors()[0].
269 getValue().getChainedIdentifier().getLastIdentifier().
270 getName().getString().size() > 0)
271 {
272 // We need to add context to the symbolic constant
273 _rightSide.applyContext(queryContext,
274 _leftSide.getTerms()[0].getFactors()[0].
275 getValue().getChainedIdentifier());
276 }
277 else
278 {
279 // There is no valid context for the symbolic constant
280 MessageLoaderParms parms("CQL.CQLSimplePredicateRep."
281 "LEFT_STANDALONE_SYMCONST_ERROR",
282 "The left side of predicate $0 must be a simple property "
283 "name because a symbolic constant exists on"
284 " the right side.",
285 toString());
286 karl 1.14 throw CQLSyntaxErrorException(parms);
287 }
|
288 chuck 1.2 }
|
289 karl 1.14
|
290 chuck 1.2 else
291 {
|
292 karl 1.14 // Right side is not simple OR it is a not a standalone
293 // symbolic constant
294 if (_operator != ISA)
295 {
296 // Not doing an ISA, go ahead and applyContext to right side
297 _rightSide.applyContext(queryContext);
298 }
299 else
300 {
301 // Operation is an ISA.. The right side must be simple.
302 // We don't want to applyContext to the right side because
303 // it could be a classname unrelated to the FROM class.
304 if (!_rightSide.isSimpleValue())
305 {
306 MessageLoaderParms parms("CQL.CQLSimplePredicateRep."
307 "APPLY_CTX_RHS_ISA_NOT_SIMPLE",
308 "The right side expression $0 of the ISA operator "
309 "must be a simple value.",
310 _rightSide.toString());
311 throw CQLSyntaxErrorException(parms);
312 }
313 karl 1.14
314 // Add the right side identifier to the list of WHERE
315 // identifiers in the QueryContext
316 QueryChainedIdentifier isaId = _rightSide.getTerms()[0].
317 getFactors()[0].
318 getValue().getChainedIdentifier();
319
|
320 s.kodali 1.16 queryContext.
|
321 karl 1.14 addWhereIdentifier(isaId);
322 }
|
323 chuck 1.2 }
324 }
|
325 humberto 1.4 PEG_METHOD_EXIT();
|
326 chuck 1.2 }
327
328 String CQLSimplePredicateRep::toString()const
329 {
|
330 karl 1.14 String s = _leftSide.toString();
331 if(!_isSimple)
332 {
333 switch(_operator)
334 {
335 case LT:
336 s.append(" < ");
337 break;
338 case GT:
339 s.append(" > ");
340 break;
341 case LE:
342 s.append(" <= ");
343 break;
344 case GE:
345 s.append(" >= ");
346 break;
347 case EQ:
348 s.append(" = ");
349 break;
350 case NE:
351 karl 1.14 s.append(" <> ");
352 break;
353 case IS_NULL:
354 s.append(" IS NULL ");
355 break;
356 case IS_NOT_NULL:
357 s.append(" IS NOT NULL ");
358 break;
359 case ISA:
360 s.append(" ISA ");
361 break;
362 case LIKE:
363 s.append(" LIKE ");
364 break;
365 case NOOP:
366 break;
367 }
368 s.append(_rightSide.toString());
369 }
370 switch(_operator)
371 {
372 karl 1.14 case IS_NULL:
373 s.append(" IS NULL ");
374 break;
375 case IS_NOT_NULL:
376 s.append(" IS NOT NULL ");
377 break;
378 default:
379 break;
380 }
381 return s;
|
382 chuck 1.2 }
383 Boolean CQLSimplePredicateRep::isSimple()const{
|
384 karl 1.14 return _isSimple;
|
385 chuck 1.2 }
386 Boolean CQLSimplePredicateRep::isSimpleValue()const{
|
387 karl 1.14 return _leftSide.isSimpleValue();
|
388 chuck 1.2 }
389
390 void CQLSimplePredicateRep::setOperation(ExpressionOpType op){
|
391 karl 1.14 _operator = op;
|
392 chuck 1.2 }
393
394 PEGASUS_NAMESPACE_END
|