(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 david.dillard 1.6 // Modified By: David Dillard, VERITAS Software Corp.
 32                   //                  (david.dillard@veritas.com)
 33 chuck         1.2 //
 34                   //%/////////////////////////////////////////////////////////////////////////////
 35                   
 36                   #include <Pegasus/Common/InternalException.h>
 37                   #include "CQLSimplePredicate.h"
 38                   #include "CQLSimplePredicateRep.h"
 39                   //#include <Pegasus/CQL/CQLExpression.h>
 40                   #include <Pegasus/CQL/CQLFactory.h>
 41                   #include <Pegasus/Query/QueryCommon/QueryContext.h>
 42                   #include <Pegasus/Query/QueryCommon/QueryException.h>
 43 humberto      1.4 #include <Pegasus/Common/Tracer.h>
 44 chuck         1.2 
 45                   PEGASUS_NAMESPACE_BEGIN
 46                   
 47                   CQLSimplePredicateRep::CQLSimplePredicateRep(){
 48                   	_isSimple = true;
 49                   }
 50                   
 51                   CQLSimplePredicateRep::CQLSimplePredicateRep(const CQLExpression& inExpression)
 52                   {
 53                   	_leftSide = inExpression;
 54                   	_isSimple = true;
 55                   }
 56                   
 57                   CQLSimplePredicateRep::CQLSimplePredicateRep(const CQLExpression& inExpression, 
 58 david.dillard 1.6 					     ExpressionOpType inOperator)
 59 chuck         1.2 {
 60                   	_leftSide = inExpression;
 61                   	_operator = inOperator;
 62                   	_isSimple = true;
 63                   }
 64                   
 65                   CQLSimplePredicateRep::CQLSimplePredicateRep(const CQLExpression& leftSideExpression, 
 66                   					     const CQLExpression& rightSideExpression,
 67                   					     ExpressionOpType inOperator)
 68                   {
 69                   	_leftSide = leftSideExpression;
 70                   	_rightSide = rightSideExpression;
 71                   	_operator = inOperator;
 72                   	_isSimple = false;
 73                   }
 74                   
 75                   CQLSimplePredicateRep::CQLSimplePredicateRep(const CQLSimplePredicateRep* rep){
 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 humberto      1.4   PEG_METHOD_ENTER(TRC_CQL, "CQLSimplePredicateRep::evaluate");
 85 chuck         1.2   // 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 (leftVal.isNull())
100                     {
101                       // The null contagion rule.  See CQLSelectStatementRep for details.  
102                       MessageLoaderParms parms("CQL.CQLSimplePredicateRep.NULL_CONTAGION",
103                                                "The expression evaluates to NULL.");
104                       throw CQLNullContagionException(parms); 
105                     }
106 chuck         1.2 
107                     if (_operator == ISA)
108                     {
109                       // Special processing for ISA.  The CQLValue on the right side of ISA
110                       // has a CQLChainedIdentifier with one element that contains
111                       // the class name.  We don't want to resolve the right side because
112                       // CQLValue would assume that a single element chained identifier
113                       // refers to an instance of the FROM class.
114                       if (!_rightSide.isSimpleValue())
115                       {
116                         MessageLoaderParms parms("CQL.CQLSimplePredicateRep.RHS_ISA_NOT_SIMPLE",
117 chuck         1.3        "The expression $0 on the right side of the ISA operator must be a simple value.",
118                          _rightSide.toString());
119 chuck         1.2       throw CQLRuntimeException(parms);
120                       }
121                   
122                       CQLValue isaRightVal = _rightSide.getTerms()[0].getFactors()[0].getValue();
123                       CQLChainedIdentifier isaRightId = isaRightVal.getChainedIdentifier();
124                       return leftVal.isa(isaRightId, QueryCtx);
125                     }
126                   
127                     if (_operator == LIKE)
128                     {
129                       // Special processing for LIKE.  The right side expression must be
130                       // a simple CQLValue (ie. not nested, and not a function), and
131                       // must be a literal.  Note that this code will test whether
132                       // the right side is a literal, but not whether it is a string
133                       // literal.
134                       if (!_rightSide.isSimpleValue())
135                       {
136                         MessageLoaderParms parms("CQL.CQLSimplePredicateRep.RHS_LIKE_NOT_SIMPLE",
137 chuck         1.3        "The expression $0 on the right side of the LIKE operator must be a simple value.",
138                          _rightSide.toString());
139 chuck         1.2       throw CQLRuntimeException(parms);
140                       }
141                   
142                       CQLValue likeRightVal = _rightSide.getTerms()[0].getFactors()[0].getValue();
143                       if (!likeRightVal.isResolved())
144                       {
145                         MessageLoaderParms parms("CQL.CQLSimplePredicateRep.RHS_LIKE_NOT_LITERAL",
146 chuck         1.3        "The expression $0 on the right side of the LIKE operator must be a literal.",
147                          _rightSide.toString());
148 chuck         1.2       throw CQLRuntimeException(parms);
149                       }
150                   
151                       return leftVal.like(likeRightVal);
152                     }
153                   
154                     // No special processing needed.
155                     // Resolve the value of the right side
156                     CQLValue rightVal = _rightSide.resolveValue(CI, QueryCtx);
157                   
158 lucier        1.5   // printf("Left Value - %s, Right value - %s\n", (const char *)leftVal.toString().getCString(), (const char *)rightVal.toString().getCString());
159                     
160 chuck         1.2   if (rightVal.isNull())
161                     {
162                       // The null contagion rule.  See CQLSelectStatementRep for details. 
163                       // ATTN - change this to a specific CQLException so that it can
164                       // be caught above
165                       // The null contagion rule.  See CQLSelectStatementRep for details.  
166                       MessageLoaderParms parms("CQL.CQLSimplePredicateRep.NULL_CONTAGION",
167                                                "The expression evaluates to NULL.");
168                       throw CQLNullContagionException(parms); 
169                     }
170                   
171                     switch(_operator)
172                     {
173                     case LT:
174                       return leftVal < rightVal;
175                       break;
176                   
177                     case GT:
178                       return leftVal > rightVal;
179                       break;
180                   
181 chuck         1.2   case LE:
182                       return leftVal <= rightVal;
183                       break;
184                   
185                     case GE:
186                       return leftVal >= rightVal;
187                       break;
188                   
189                     case EQ:
190                       return leftVal == rightVal;
191                       break;
192                   
193                     case NE:
194                       return leftVal != rightVal;
195                       break;
196                   
197                     case LIKE:
198                     case ISA:
199                       // Never get here due to special processing above.
200                       PEGASUS_ASSERT(false);
201                     case IS_NULL:
202 chuck         1.2   case IS_NOT_NULL:
203                       // Never get here due to the assert.
204                       break;
205                     }
206 humberto      1.4   PEG_METHOD_EXIT();
207 chuck         1.2   return true;  // keep the compiler happy
208                   }
209                   
210                   CQLExpression CQLSimplePredicateRep::getLeftExpression()const
211                   {
212                   	return _leftSide;
213                   }
214                   
215                   CQLExpression CQLSimplePredicateRep::getRightExpression()const
216                   {
217                           return _rightSide;
218                   }
219                   
220                   enum ExpressionOpType CQLSimplePredicateRep::getOperation()const
221                   {
222                   	return _operator;
223                   }
224                   
225                   void CQLSimplePredicateRep::applyContext(QueryContext& queryContext)
226                   {
227 humberto      1.4   PEG_METHOD_ENTER(TRC_CQL, "CQLSimplePredicateRep::applyContext");
228 chuck         1.2   CQLIdentifier _id;
229                   
230                      _id = _leftSide.getTerms()[0].getFactors()[0].
231                                     getValue().getChainedIdentifier().getLastIdentifier();
232                   
233                      if(_leftSide.isSimpleValue() &&
234                         _id.isSymbolicConstant() &&
235                            _id.getName().getString().size() == 0)
236                      {
237                         // We have a standalone symbolic constant.
238                         if(!isSimple() && 
239                            _rightSide.isSimpleValue() &&
240                            _rightSide.getTerms()[0].getFactors()[0].
241                                   getValue().getChainedIdentifier().getLastIdentifier().
242                                   getName().getString().size() > 0)
243                         {
244                            _rightSide.applyContext(queryContext);
245                   
246                            // We need to add context to the symbolic constant
247                            _leftSide.applyContext(queryContext,
248                                                   _rightSide.getTerms()[0].getFactors()[0].
249 chuck         1.2                                 getValue().getChainedIdentifier()); 
250                         }
251                         else
252                         {
253                            // There is no valid context for the symbolic constant
254                           MessageLoaderParms parms("CQL.CQLSimplePredicateRep.RIGHT_STANDALONE_SYMCONST_ERROR",
255 chuck         1.3          "The right side of predicate $0 must be a simple property name because a symbolic constant exists on the left side.",
256                            toString());
257 chuck         1.2         throw CQLSyntaxErrorException(parms);
258                         }
259                      }
260                      else
261                      {
262                         _leftSide.applyContext(queryContext);
263                      }
264                   
265                      if (!isSimple())
266                      {
267                         _id = _rightSide.getTerms()[0].getFactors()[0].
268                                        getValue().getChainedIdentifier().getLastIdentifier();
269                   
270                         if(_rightSide.isSimpleValue() &&
271                            _id.isSymbolicConstant() &&
272                            _id.getName().getString().size() == 0)
273                         {
274                            // We have a standalone symbolic constant.
275                            if(!isSimple() && 
276                               _leftSide.isSimpleValue() &&
277                               _leftSide.getTerms()[0].getFactors()[0].
278 chuck         1.2                    getValue().getChainedIdentifier().getLastIdentifier().
279                                      getName().getString().size() > 0)
280                            {
281                               // We need to add context to the symbolic constant
282                               _rightSide.applyContext(queryContext,
283                                                      _leftSide.getTerms()[0].getFactors()[0].
284                                                      getValue().getChainedIdentifier());               
285                            }
286                            else
287                            {
288                               // There is no valid context for the symbolic constant
289                              MessageLoaderParms parms("CQL.CQLSimplePredicateRep.LEFT_STANDALONE_SYMCONST_ERROR",
290 chuck         1.3             "The left side of predicate $0 must be a simple property name because a symbolic constant exists on the right side.",
291                                toString());
292 chuck         1.2            throw CQLSyntaxErrorException(parms);
293                            }
294                         }
295                         else
296                         {
297                           // Right side is not simple OR it is a not a standalone symbolic constant
298                           if (_operator != ISA)
299                           {
300                             // Not doing an ISA, go ahead and applyContext to right side
301                             _rightSide.applyContext(queryContext);
302                           }
303                           else
304                           {
305                             // Operation is an ISA.. The right side must be simple.
306                             // We don't want to applyContext to the right side because
307                             // it could be a classname unrelated to the FROM class.
308                             if (!_rightSide.isSimpleValue())
309                             {
310                               MessageLoaderParms parms("CQL.CQLSimplePredicateRep.APPLY_CTX_RHS_ISA_NOT_SIMPLE",
311 chuck         1.3              "The right side expression $0 of the ISA operator must be a simple value.",
312                                 _rightSide.toString());
313 chuck         1.2             throw CQLSyntaxErrorException(parms);
314                             }
315 chuck         1.3 
316                             // Add the right side identifier to the list of WHERE
317                             // identifiers in the QueryContext
318                             QueryChainedIdentifier isaId = _rightSide.getTerms()[0].
319                               getFactors()[0].
320                               getValue().getChainedIdentifier();
321                             queryContext.addWhereIdentifier(isaId);
322 chuck         1.2         }
323                         }
324                      }
325 humberto      1.4    PEG_METHOD_EXIT();
326 chuck         1.2 }
327                   
328                   String CQLSimplePredicateRep::toString()const
329                   {
330                   	String s = _leftSide.toString();
331                   	if(!_isSimple){
332                   	   switch(_operator){
333                   		case LT:
334                   			s.append(" < ");
335                   			break;
336                   		case GT:
337                   			s.append(" > ");
338                   			break;
339                   		case LE:
340                   			s.append(" <= ");
341                   			break;
342                   		case GE:
343                   			s.append(" >= ");
344                   			break;
345                   		case EQ:
346                   			s.append(" = ");
347 chuck         1.2 			break;
348                   		case NE:
349                   			s.append(" != ");
350                   			break;
351                   		case IS_NULL:
352                   			s.append(" IS NULL ");
353                   			break;
354                   		case IS_NOT_NULL:
355                   			s.append(" IS NOT NULL ");
356                   			break;
357                   		case ISA:
358                   			s.append(" ISA ");
359                   			break;
360                   		case LIKE:
361                   			s.append(" LIKE ");
362                   			break;
363                   	   }
364                   	   s.append(_rightSide.toString());
365                   	}
366                   	switch(_operator){
367                   		case IS_NULL:
368 chuck         1.2         		s.append(" IS NULL ");
369                                           break;
370                                   case IS_NOT_NULL:
371                                           s.append(" IS NOT NULL ");
372                                           break;
373                   		default:
374                   			break;
375                   	}
376                   	return s;
377                   }
378                   Boolean CQLSimplePredicateRep::isSimple()const{
379                           return _isSimple;
380                   }
381                   Boolean CQLSimplePredicateRep::isSimpleValue()const{
382                   	return _leftSide.isSimpleValue();
383                   }
384                    
385                   void CQLSimplePredicateRep::setOperation(ExpressionOpType op){
386                   	_operator = op;
387                   } 
388                   
389 chuck         1.2 PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2