(file) Return to CQLSimplePredicateRep.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / CQL

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2