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

Diff for /pegasus/src/Pegasus/CQL/CQLSimplePredicateRep.cpp between version 1.1 and 1.2

version 1.1, 2004/09/08 03:52:03 version 1.2, 2004/11/21 12:13:07
Line 0 
Line 1 
   //%2003////////////////////////////////////////////////////////////////////////
   //
   // Copyright (c) 2000, 2001, 2002  BMC Software, Hewlett-Packard Development
   // Company, L. P., IBM Corp., The Open Group, Tivoli Systems.
   // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L. P.;
   // IBM Corp.; EMC Corporation, The Open Group.
   //
   // Permission is hereby granted, free of charge, to any person obtaining a copy
   // of this software and associated documentation files (the "Software"), to
   // deal in the Software without restriction, including without limitation the
   // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   // sell copies of the Software, and to permit persons to whom the Software is
   // furnished to do so, subject to the following conditions:
   //
   // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
   // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
   // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
   // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
   // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
   // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
   // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
   // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   //
   //==============================================================================
   //
   // Authors: David Rosckes (rosckes@us.ibm.com)
   //          Bert Rivero (hurivero@us.ibm.com)
   //          Chuck Carmack (carmack@us.ibm.com)
   //          Brian Lucier (lucier@us.ibm.com)
   //
   // Modified By:
   //
   //%/////////////////////////////////////////////////////////////////////////////
   
   #include <Pegasus/Common/InternalException.h>
   #include "CQLSimplePredicate.h"
   #include "CQLSimplePredicateRep.h"
   //#include <Pegasus/CQL/CQLExpression.h>
   #include <Pegasus/CQL/CQLFactory.h>
   #include <Pegasus/Query/QueryCommon/QueryContext.h>
   #include <Pegasus/Query/QueryCommon/QueryException.h>
   
   PEGASUS_NAMESPACE_BEGIN
   
   CQLSimplePredicateRep::CQLSimplePredicateRep(){
           _isSimple = true;
   }
   
   CQLSimplePredicateRep::CQLSimplePredicateRep(const CQLExpression& inExpression)
   {
           _leftSide = inExpression;
           _isSimple = true;
   }
   
   CQLSimplePredicateRep::CQLSimplePredicateRep(const CQLExpression& inExpression,
                                                const ExpressionOpType inOperator)
   {
           _leftSide = inExpression;
           _operator = inOperator;
           _isSimple = true;
   }
   
   CQLSimplePredicateRep::CQLSimplePredicateRep(const CQLExpression& leftSideExpression,
                                                const CQLExpression& rightSideExpression,
                                                ExpressionOpType inOperator)
   {
           _leftSide = leftSideExpression;
           _rightSide = rightSideExpression;
           _operator = inOperator;
           _isSimple = false;
   }
   
   CQLSimplePredicateRep::CQLSimplePredicateRep(const CQLSimplePredicateRep* rep){
           _leftSide = rep->_leftSide;
           _rightSide = rep->_rightSide;
           _operator = rep->_operator;
           _isSimple = rep->_isSimple;
   }
   
   Boolean CQLSimplePredicateRep::evaluate(CIMInstance CI, QueryContext& QueryCtx)
   {
     // Resolve the value of the left side
     CQLValue leftVal = _leftSide.resolveValue(CI, QueryCtx);
   
     // If there isn't a right side then operator must by IS_NULL
     // or IS_NOT_NULL
     if (isSimple())
     {
       PEGASUS_ASSERT(_operator == IS_NULL || _operator == IS_NOT_NULL);
   
       return (_operator == IS_NULL) ? leftVal.isNull() : !leftVal.isNull();
     }
   
     PEGASUS_ASSERT(_operator != IS_NULL && _operator != IS_NOT_NULL);
   
     if (leftVal.isNull())
     {
       // The null contagion rule.  See CQLSelectStatementRep for details.
       MessageLoaderParms parms("CQL.CQLSimplePredicateRep.NULL_CONTAGION",
                                "The expression evaluates to NULL.");
       throw CQLNullContagionException(parms);
     }
   
     if (_operator == ISA)
     {
       // Special processing for ISA.  The CQLValue on the right side of ISA
       // has a CQLChainedIdentifier with one element that contains
       // the class name.  We don't want to resolve the right side because
       // CQLValue would assume that a single element chained identifier
       // refers to an instance of the FROM class.
       if (!_rightSide.isSimpleValue())
       {
         MessageLoaderParms parms("CQL.CQLSimplePredicateRep.RHS_ISA_NOT_SIMPLE",
                                  "The expression $0 on the right side of the ISA operator must be a simple value.",
                                   _rightSide.toString());
         throw CQLRuntimeException(parms);
       }
   
       CQLValue isaRightVal = _rightSide.getTerms()[0].getFactors()[0].getValue();
       CQLChainedIdentifier isaRightId = isaRightVal.getChainedIdentifier();
       return leftVal.isa(isaRightId, QueryCtx);
     }
   
     if (_operator == LIKE)
     {
       // Special processing for LIKE.  The right side expression must be
       // a simple CQLValue (ie. not nested, and not a function), and
       // must be a literal.  Note that this code will test whether
       // the right side is a literal, but not whether it is a string
       // literal.
       if (!_rightSide.isSimpleValue())
       {
         MessageLoaderParms parms("CQL.CQLSimplePredicateRep.RHS_LIKE_NOT_SIMPLE",
                                  "The expression $0 on the right side of the LIKE operator must be a simple value.",
                                   _rightSide.toString());
         throw CQLRuntimeException(parms);
       }
   
       CQLValue likeRightVal = _rightSide.getTerms()[0].getFactors()[0].getValue();
       if (!likeRightVal.isResolved())
       {
         MessageLoaderParms parms("CQL.CQLSimplePredicateRep.RHS_LIKE_NOT_LITERAL",
                                  "The expression $0 on the right side of the LIKE operator must be a literal.",
                                   _rightSide.toString());
         throw CQLRuntimeException(parms);
       }
   
       return leftVal.like(likeRightVal);
     }
   
     // No special processing needed.
     // Resolve the value of the right side
     CQLValue rightVal = _rightSide.resolveValue(CI, QueryCtx);
   
     if (rightVal.isNull())
     {
       // The null contagion rule.  See CQLSelectStatementRep for details.
       // ATTN - change this to a specific CQLException so that it can
       // be caught above
       // The null contagion rule.  See CQLSelectStatementRep for details.
       MessageLoaderParms parms("CQL.CQLSimplePredicateRep.NULL_CONTAGION",
                                "The expression evaluates to NULL.");
       throw CQLNullContagionException(parms);
     }
   
     switch(_operator)
     {
     case LT:
       return leftVal < rightVal;
       break;
   
     case GT:
       return leftVal > rightVal;
       break;
   
     case LE:
       return leftVal <= rightVal;
       break;
   
     case GE:
       return leftVal >= rightVal;
       break;
   
     case EQ:
       return leftVal == rightVal;
       break;
   
     case NE:
       return leftVal != rightVal;
       break;
   
     case LIKE:
     case ISA:
       // Never get here due to special processing above.
       PEGASUS_ASSERT(false);
     case IS_NULL:
     case IS_NOT_NULL:
       // Never get here due to the assert.
       break;
     }
   
     return true;  // keep the compiler happy
   }
   
   CQLExpression CQLSimplePredicateRep::getLeftExpression()const
   {
           return _leftSide;
   }
   
   CQLExpression CQLSimplePredicateRep::getRightExpression()const
   {
           return _rightSide;
   }
   
   enum ExpressionOpType CQLSimplePredicateRep::getOperation()const
   {
           return _operator;
   }
   
   void CQLSimplePredicateRep::applyContext(QueryContext& queryContext)
   {
     CQLIdentifier _id;
   
      _id = _leftSide.getTerms()[0].getFactors()[0].
                     getValue().getChainedIdentifier().getLastIdentifier();
   
      if(_leftSide.isSimpleValue() &&
         _id.isSymbolicConstant() &&
            _id.getName().getString().size() == 0)
      {
         // We have a standalone symbolic constant.
         if(!isSimple() &&
            _rightSide.isSimpleValue() &&
            _rightSide.getTerms()[0].getFactors()[0].
                   getValue().getChainedIdentifier().getLastIdentifier().
                   getName().getString().size() > 0)
         {
            _rightSide.applyContext(queryContext);
   
            // We need to add context to the symbolic constant
            _leftSide.applyContext(queryContext,
                                   _rightSide.getTerms()[0].getFactors()[0].
                                   getValue().getChainedIdentifier());
         }
         else
         {
            // There is no valid context for the symbolic constant
           MessageLoaderParms parms("CQL.CQLSimplePredicateRep.RIGHT_STANDALONE_SYMCONST_ERROR",
                                  "The right side of predicate $0 must be a simple property name because a symbolic constant exists on the left side.",
                                   toString());
           throw CQLSyntaxErrorException(parms);
         }
      }
      else
      {
         _leftSide.applyContext(queryContext);
      }
   
      if (!isSimple())
      {
         _id = _rightSide.getTerms()[0].getFactors()[0].
                        getValue().getChainedIdentifier().getLastIdentifier();
   
         if(_rightSide.isSimpleValue() &&
            _id.isSymbolicConstant() &&
            _id.getName().getString().size() == 0)
         {
            // We have a standalone symbolic constant.
            if(!isSimple() &&
               _leftSide.isSimpleValue() &&
               _leftSide.getTerms()[0].getFactors()[0].
                      getValue().getChainedIdentifier().getLastIdentifier().
                      getName().getString().size() > 0)
            {
               // We need to add context to the symbolic constant
               _rightSide.applyContext(queryContext,
                                      _leftSide.getTerms()[0].getFactors()[0].
                                      getValue().getChainedIdentifier());
            }
            else
            {
               // There is no valid context for the symbolic constant
              MessageLoaderParms parms("CQL.CQLSimplePredicateRep.LEFT_STANDALONE_SYMCONST_ERROR",
                                  "The left side of predicate $0 must be a simple property name because a symbolic constant exists on the right side.",
                                   toString());
              throw CQLSyntaxErrorException(parms);
            }
         }
         else
         {
           // Right side is not simple OR it is a not a standalone symbolic constant
           if (_operator != ISA)
           {
             // Not doing an ISA, go ahead and applyContext to right side
             _rightSide.applyContext(queryContext);
           }
           else
           {
             // Operation is an ISA.. The right side must be simple.
             // We don't want to applyContext to the right side because
             // it could be a classname unrelated to the FROM class.
             if (!_rightSide.isSimpleValue())
             {
               MessageLoaderParms parms("CQL.CQLSimplePredicateRep.APPLY_CTX_RHS_ISA_NOT_SIMPLE",
                                        "The right side expression $0 of the ISA operator must be a simple value.",
                                        _rightSide.toString());
               throw CQLSyntaxErrorException(parms);
             }
           }
         }
      }
   }
   
   String CQLSimplePredicateRep::toString()const
   {
           String s = _leftSide.toString();
           if(!_isSimple){
              switch(_operator){
                   case LT:
                           s.append(" < ");
                           break;
                   case GT:
                           s.append(" > ");
                           break;
                   case LE:
                           s.append(" <= ");
                           break;
                   case GE:
                           s.append(" >= ");
                           break;
                   case EQ:
                           s.append(" = ");
                           break;
                   case NE:
                           s.append(" != ");
                           break;
                   case IS_NULL:
                           s.append(" IS NULL ");
                           break;
                   case IS_NOT_NULL:
                           s.append(" IS NOT NULL ");
                           break;
                   case ISA:
                           s.append(" ISA ");
                           break;
                   case LIKE:
                           s.append(" LIKE ");
                           break;
              }
              s.append(_rightSide.toString());
           }
           switch(_operator){
                   case IS_NULL:
                           s.append(" IS NULL ");
                           break;
                   case IS_NOT_NULL:
                           s.append(" IS NOT NULL ");
                           break;
                   default:
                           break;
           }
           return s;
   }
   Boolean CQLSimplePredicateRep::isSimple()const{
           return _isSimple;
   }
   Boolean CQLSimplePredicateRep::isSimpleValue()const{
           return _leftSide.isSimpleValue();
   }
   
   void CQLSimplePredicateRep::setOperation(ExpressionOpType op){
           _operator = op;
   }
   
   PEGASUS_NAMESPACE_END


Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2