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