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

File: [Pegasus] / pegasus / src / Pegasus / CQL / CQLFunctionRep.cpp (download)
Revision: 1.26, Wed Sep 19 19:54:42 2007 UTC (16 years, 9 months ago) by dave.sudlik
Branch: MAIN
CVS Tags: TASK-PEP328_SOLARIS_IX86_CC_PORT-root, TASK-PEP328_SOLARIS_IX86_CC_PORT-branch, TASK-BUG7146_SqlRepositoryPrototype-root, TASK-BUG7146_SqlRepositoryPrototype-merged_out_to_branch, TASK-BUG7146_SqlRepositoryPrototype-merged_out_from_trunk, TASK-BUG7146_SqlRepositoryPrototype-merged_in_to_trunk, TASK-BUG7146_SqlRepositoryPrototype-merged_in_from_branch, TASK-BUG7146_SqlRepositoryPrototype-branch, RELEASE_2_8_0_BETA, RELEASE_2_8_0-FC, RELEASE_2_7_3-RC1, RELEASE_2_7_3, RELEASE_2_7_2-RC1, RELEASE_2_7_2, RELEASE_2_7_1-RC1, RELEASE_2_7_1, RELEASE_2_7_0-RC1, RELEASE_2_7_0, RELEASE_2_7-root, RELEASE_2_7-branch, Makefile
Branch point for: TASK-PEP328_SOLARIS_IX86_CC_PORT-branch-v2
Changes since 1.25: +262 -189 lines
BUG#: 6456
TITLE: Incorrect handling of null values in CQL comparisons

DESCRIPTION: committing approved fix

//%2006////////////////////////////////////////////////////////////////////////
//
// 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.
// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
// EMC Corporation; VERITAS Software Corporation; The Open Group.
// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
// EMC Corporation; Symantec 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.
//
//==============================================================================
//
//%/////////////////////////////////////////////////////////////////////////////

#include <Pegasus/CQL/CQLFunctionRep.h>

// CQL includes
#include <Pegasus/CQL/CQLFactory.h>
#include <Pegasus/CQL/CQLUtilities.h>
#include <Pegasus/CQL/CQLValue.h>
#include <Pegasus/CQL/CQLValueRep.h>

// Common Query includes
#include <Pegasus/Query/QueryCommon/QueryContext.h>

// Common Pegasus includes
#include <Pegasus/Common/CIMName.h>
#include <Pegasus/Common/CIMObjectPath.h>
#include <Pegasus/Common/Tracer.h>

PEGASUS_NAMESPACE_BEGIN

CQLFunctionRep::CQLFunctionRep(): _funcOpType(UNKNOWN), _parms() {}

CQLFunctionRep::CQLFunctionRep(CQLIdentifier inOpType,
        Array<CQLPredicate> inParms)
    : _funcOpType(UNKNOWN), _parms(inParms)
{
    PEG_METHOD_ENTER(TRC_CQL,"CQLFunctionRep::CQLFunctionRep()");
    
    String opType(inOpType.getName().getString());
    
    if(String::compareNoCase(opType,String("DATETIMETOMICROSECOND")) == 0){
        _funcOpType = DATETIMETOMICROSECOND;
    }
    else if(String::compareNoCase(opType, String("STRINGTOUINT")) == 0){
        _funcOpType = STRINGTOUINT;
    }
    else if(String::compareNoCase(opType, String("STRINGTOSINT")) == 0){
        _funcOpType = STRINGTOSINT;
    }
    else if(String::compareNoCase(opType, String("STRINGTOREAL")) == 0){
        _funcOpType = STRINGTOREAL;
    }
    else if(String::compareNoCase(opType, String("STRINGTONUMERIC")) == 0){
        _funcOpType = STRINGTONUMERIC;
    }
    else if(String::compareNoCase(opType, String("UPPERCASE")) == 0){
        _funcOpType = UPPERCASE;
    }
    else if(String::compareNoCase(opType, String("NUMERICTOSTRING")) == 0){
        _funcOpType = NUMERICTOSTRING;
    }
    else if(String::compareNoCase(opType, String("REFERENCETOSTRING")) == 0){
        _funcOpType = REFERENCETOSTRING;
    }
    else if(String::compareNoCase(opType, String("CLASSNAME")) == 0){
        _funcOpType = CLASSNAME;
    }
    else if(String::compareNoCase(opType, String("NAMESPACENAME")) == 0){
        _funcOpType = NAMESPACENAME;
    }
    else if(String::compareNoCase(opType, String("NAMESPACETYPE")) == 0){
        _funcOpType = NAMESPACETYPE;
    }
    else if(String::compareNoCase(opType, String("HOSTPORT")) == 0){
        _funcOpType = HOSTPORT;
    }
    else if(String::compareNoCase(opType, String("MODELPATH")) == 0){
        _funcOpType = MODELPATH;
    }
    else if(String::compareNoCase(opType, String("CLASSPATH")) == 0){
        _funcOpType = CLASSPATH;
    }
    else if(String::compareNoCase(opType, String("OBJECTPATH")) == 0){
        _funcOpType = OBJECTPATH;
    }
    else if(String::compareNoCase(opType, String("INSTANCETOREFERENCE")) == 0){
        _funcOpType = INSTANCETOREFERENCE;
    }
    else if(String::compareNoCase(opType, String("CURRENTDATETIME")) == 0){
        _funcOpType = CURRENTDATETIME;
    }
    else if(String::compareNoCase(opType, String("DATETIME")) == 0){
        _funcOpType = DATETIME;
    }
    else if(String::compareNoCase(opType, 
                                String("MICROSECONDTOTIMESTAMP")) == 0){
        _funcOpType = MICROSECONDTOTIMESTAMP;
    }
    else if(String::compareNoCase(opType, 
                                String("MICROSECONDTOINTERVAL")) == 0){
    _funcOpType = MICROSECONDTOINTERVAL;
    }
    else
    {
        // Unknown function
        MessageLoaderParms mload(
            String("CQL.CQLFunctionRep.INVALID_FUNCTION"),
            String("Function: $0 is not a supported function."),
            opType);
        throw CQLSyntaxErrorException(mload);
    }
    PEG_METHOD_EXIT();
}
CQLFunctionRep::CQLFunctionRep(const CQLFunctionRep* rep) 
    : _funcOpType(rep->_funcOpType), _parms(rep->_parms)
{
}

CQLFunctionRep::~CQLFunctionRep()
{
}

CQLValue CQLFunctionRep::resolveValue(const CIMInstance& CI,
                                      const QueryContext& queryCtx)
{
    switch(_funcOpType)
    {
        case DATETIMETOMICROSECOND:
          return dateTimeToMicrosecond(CI, queryCtx);
        case STRINGTOUINT:
          return stringToUint(CI, queryCtx);
        case STRINGTOSINT:
          return stringToSint(CI, queryCtx);
        case STRINGTOREAL:
          return stringToReal(CI, queryCtx);
        case STRINGTONUMERIC:
          return stringToNumeric(CI, queryCtx);
        case UPPERCASE:
          return upperCase(CI, queryCtx);
        case NUMERICTOSTRING:
          return numericToString(CI, queryCtx);
        case REFERENCETOSTRING:
          return referenceToString(CI, queryCtx);
        case CLASSNAME:
          return className(CI, queryCtx);
        case NAMESPACENAME:
          return nameSpaceName(CI, queryCtx);
        case NAMESPACETYPE:
          return nameSpaceType(CI, queryCtx);
        case HOSTPORT:
          return hostPort(CI, queryCtx);
        case MODELPATH:
          return modelPath(CI, queryCtx);
        case CLASSPATH:
          return classPath(CI, queryCtx);
        case OBJECTPATH:
          return objectPath(CI, queryCtx);
        case INSTANCETOREFERENCE:
          return instanceToReference(CI, queryCtx);
        case CURRENTDATETIME:
          return currentDateTime();
        case DATETIME:
          return dateTime(CI, queryCtx);
        case MICROSECONDTOTIMESTAMP:
          return microsecondToTimestamp(CI, queryCtx);
        case MICROSECONDTOINTERVAL:
          return microsecondToInterval(CI, queryCtx);
        case UNKNOWN:
          {
            // Unknown function
            char buf[10];
            sprintf(buf, "%d", _funcOpType);
            MessageLoaderParms mload(
                String("CQL.CQLFunctionRep.INVALID_FUNCTION_ID"),
                String("Function ID: $0 is not a supported function ID."),
                String(buf));
            throw CQLSyntaxErrorException(mload);
          }
    }
    // Unknown function
    char buf[10];
    sprintf(buf, "%d", _funcOpType);
    MessageLoaderParms mload(
        String("CQL.CQLFunctionRep.INVALID_FUNCTION_ID"),
        String("Function ID: $0 is not a supported function ID."),
        String(buf));
    throw CQLSyntaxErrorException(mload);
}

String CQLFunctionRep::toString() const
{
    String returnStr = functionTypeToString();
    
    returnStr.append("(");
    Uint32 parmSize = _parms.size();
    for(Uint32 i = 0; i < parmSize; ++i)
    {
        returnStr.append(_parms[i].toString());
        if (i+1 < parmSize)
            returnStr.append(", ");
    }
    returnStr.append(")");
    return returnStr;
}

String CQLFunctionRep::functionTypeToString() const
{
    String returnStr;
    
    switch(_funcOpType)
    {
        case DATETIMETOMICROSECOND:
            returnStr.append("DATETIMETOMICROSECOND");
            break;
        case STRINGTOUINT:
            returnStr.append("STRINGTOUINT");
            break;
        case STRINGTOSINT:
            returnStr.append("STRINGTOSINT");
            break;
        case STRINGTOREAL:
            returnStr.append("STRINGTOREAL");
            break;
        case STRINGTONUMERIC:
            returnStr.append("STRINGTONUMERIC");
            break;
        case UPPERCASE:
            returnStr.append("UPPERCASE");
            break;
        case NUMERICTOSTRING:
            returnStr.append("NUMERICTOSTRING");
            break;
        case REFERENCETOSTRING:
            returnStr.append("REFERENCETOSTRING");
            break;
        case CLASSNAME:
            returnStr.append("CLASSNAME");
            break;
        case NAMESPACENAME:
            returnStr.append("NAMESPACENAME");
            break;
        case NAMESPACETYPE:
            returnStr.append("NAMESPACETYPE");
            break;
        case HOSTPORT:
            returnStr.append("HOSTPORT");
            break;
        case MODELPATH:
            returnStr.append("MODELPATH");
            break;
        case CLASSPATH:
            returnStr.append("CLASSPATH");
            break;
        case OBJECTPATH:
            returnStr.append("OBJECTPATH");
            break;
        case INSTANCETOREFERENCE:
            returnStr.append("INSTANCETOREFERENCE");
            break;
        case CURRENTDATETIME:
            returnStr.append("CURRENTDATETIME");
            break;
        case DATETIME:
            returnStr.append("DATETIME");
            break;
        case MICROSECONDTOTIMESTAMP:
            returnStr.append("MICROSECONDTOTIMESTAMP");
            break;
        case MICROSECONDTOINTERVAL:
            returnStr.append("MICROSECONDTOINTERVAL");
            break;
        case UNKNOWN:
            returnStr.append("UNKNOWN");
        default:
            returnStr.append("UNKNOWN");
            break;
    }
    return returnStr;
}

Array<CQLPredicate> CQLFunctionRep::getParms()const
{
    return _parms;
}

FunctionOpType CQLFunctionRep::getFunctionType()const
{
    return _funcOpType;
}
 
void CQLFunctionRep::applyContext(const QueryContext& inContext)
{
    PEG_METHOD_ENTER(TRC_CQL,"CQLFunctionRep::applyContext()");
    
    for(Uint32 i = 0; i < _parms.size(); ++i)
    {
        _parms[i].applyContext(inContext);
    }
    PEG_METHOD_EXIT();
}
/*
Boolean CQLFunctionRep::operator==(const CQLFunctionRep& func)const
{
  if(_funcOpType != func._funcOpType || _parms.size() != func._parms.size())
  {
    return false;
  }

//  for(Uint32 i = 0; i < _parms.size(); ++i)
//  {
//    if(!(_parms[i] == func._parms[i]))
//    {
//      return false;
//    }
//  }

  return true;
}

Boolean CQLFunctionRep::operator!=(const CQLFunctionRep& func)const{
    return (!operator==(func));
}
*/

CQLValue CQLFunctionRep::dateTimeToMicrosecond(const CIMInstance& CI,
                                           const QueryContext& queryCtx) const
{
    PEG_METHOD_ENTER(TRC_CQL,"CQLFunctionRep::dateTimeToMicrosecond()");
    
    if(_parms.size() != 1)
    {
        char buf[10];
        sprintf(buf, "%d", _parms.size());
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_COUNT",
            "Function $0 has $1 parameters.  It must have between"
                " $2 and $3.",
            functionTypeToString(),
            buf,
            "1", "1");
        throw CQLRuntimeException(mload);
    }
    
    // resolve the parameter
    CQLValue cqlVal = _parms[0].getSimplePredicate().getLeftExpression().
        resolveValue(CI,queryCtx);
   
    if(cqlVal.getValueType() != CQLValue::CIMDateTime_type)
    {
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_TYPE",
            "Parameter $0 for function $1 has type $2."
                "  It must be type $3.",
            "1",
            functionTypeToString(),
            CQLValueRep::valueTypeToString(cqlVal.getValueType()),
            CQLValueRep::valueTypeToString(CQLValue::CIMDateTime_type));
        throw CQLRuntimeException(mload);
    }

    if (cqlVal.isNull())
    {
        return CQLValue(CIMValue(CIMTYPE_UINT64, false));
    }  

    PEG_METHOD_EXIT();
    return CQLValue(cqlVal.getDateTime().toMicroSeconds()); 
}

CQLValue CQLFunctionRep::stringToUint(const CIMInstance& CI,
        const QueryContext& queryCtx) const
{
    PEG_METHOD_ENTER(TRC_CQL,"CQLFunctionRep::stringToUint()");
    if(_parms.size() != 1)
    {
        char buf[10];
        sprintf(buf, "%d", _parms.size());
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_COUNT",
            "Function $0 has $1 parameters."
                "  It must have between $2 and $3.",
            functionTypeToString(),
            String(buf),
            "1", "1");
        throw CQLRuntimeException(mload);
    }
    
    CQLValue cqlVal = _parms[0].getSimplePredicate().getLeftExpression().
      resolveValue(CI,queryCtx);

    if(cqlVal.getValueType() != CQLValue::String_type)
    {
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_TYPE",
            "Parameter $0 for function $1 has type $2."
                "  It must be type $3.",
            "1",
            functionTypeToString(),
            CQLValueRep::valueTypeToString(cqlVal.getValueType()),
            CQLValueRep::valueTypeToString(CQLValue::String_type));
        throw CQLRuntimeException(mload);
    }

    if (cqlVal.isNull())
    {
        return CQLValue(CIMValue(CIMTYPE_UINT64, false));
    }

    PEG_METHOD_EXIT();
    return CQLValue(CQLUtilities::stringToUint64(cqlVal.getString()));
}

CQLValue CQLFunctionRep::stringToSint(const CIMInstance& CI,
                                      const QueryContext& queryCtx) const
{
    PEG_METHOD_ENTER(TRC_CQL,"CQLFunctionRep::stringToSint()");
    if(_parms.size() != 1)
    {
        char buf[10];
        sprintf(buf, "%d", _parms.size());
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_COUNT",
            "Function $0 has $1 parameters."
                "  It must have between $2 and $3.",
            functionTypeToString(),
            String(buf),
            "1", "1");
        throw CQLRuntimeException(mload);
    }
    
    CQLValue cqlVal = _parms[0].getSimplePredicate().getLeftExpression().
        resolveValue(CI,queryCtx);
 
    if(cqlVal.getValueType() != CQLValue::String_type)
    {
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_TYPE",
            "Parameter $0 for function $1 has type $2."
                "  It must be type $3.",
            "1",
            functionTypeToString(),
            CQLValueRep::valueTypeToString(cqlVal.getValueType()),
            CQLValueRep::valueTypeToString(CQLValue::String_type));
        throw CQLRuntimeException(mload);
    }
    
    if (cqlVal.isNull())
    {
        return CQLValue(CIMValue(CIMTYPE_SINT64, false));
    }

    PEG_METHOD_EXIT();
    return CQLValue(CQLUtilities::stringToSint64(cqlVal.getString()));
}

CQLValue CQLFunctionRep::stringToReal(const CIMInstance& CI,
                                      const QueryContext& queryCtx) const
{
    PEG_METHOD_ENTER(TRC_CQL,"CQLFunctionRep::stringToReal()");
    if(_parms.size() != 1)
    {
        char buf[10];
        sprintf(buf, "%d", _parms.size());
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_COUNT",
            "Function $0 has $1 parameters."
                "  It must have between $2 and $3.",
            functionTypeToString(),
            String(buf),
            String("1"), String("1"));
        throw CQLRuntimeException(mload);
    }
    
    CQLValue cqlVal = _parms[0].getSimplePredicate().getLeftExpression().
      resolveValue(CI,queryCtx);

    if(cqlVal.getValueType() != CQLValue::String_type)
    {
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_TYPE",
            "Parameter $0 for function $1 has type $2."
                "  It must be type $3.",
            "1",
            functionTypeToString(),
            CQLValueRep::valueTypeToString(cqlVal.getValueType()),
            CQLValueRep::valueTypeToString(CQLValue::String_type));
        throw CQLRuntimeException(mload);
    }

    if (cqlVal.isNull())
    {
        return CQLValue(CIMValue(CIMTYPE_REAL64, false));
    }
        
    PEG_METHOD_EXIT();
    return CQLValue(CQLUtilities::stringToReal64(cqlVal.getString()));
}

CQLValue CQLFunctionRep::stringToNumeric(const CIMInstance& CI,
                                         const QueryContext& queryCtx) const
{
   return stringToReal(CI, queryCtx);
}

CQLValue CQLFunctionRep::upperCase(const CIMInstance& CI,
                                   const QueryContext& queryCtx) const
{
    PEG_METHOD_ENTER(TRC_CQL,"CQLFunctionRep::upperCase()");
    if(_parms.size() != 1)
    {
        char buf[10];
        sprintf(buf, "%d", _parms.size());
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_COUNT",
            "Function $0 has $1 parameters."
                "  It must have between $2 and $3.",
            functionTypeToString(),
            String(buf),
            String("1"), String("1"));
        throw CQLRuntimeException(mload);
    }
    
    CQLValue cqlVal = _parms[0].getSimplePredicate().getLeftExpression().
      resolveValue(CI,queryCtx);

    if(cqlVal.getValueType() != CQLValue::String_type)
    {
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_TYPE",
            "Parameter $0 for function $1 has type $2."
                "  It must be type $3.",
            "1",
            functionTypeToString(),
            CQLValueRep::valueTypeToString(cqlVal.getValueType()),
            CQLValueRep::valueTypeToString(CQLValue::String_type));
        throw CQLRuntimeException(mload);
    }
    
    if (cqlVal.isNull())
    {
        return cqlVal;
    }
    
    String tmpStr = cqlVal.getString();
    tmpStr.toUpper();
    
    PEG_METHOD_EXIT();
    return CQLValue(tmpStr);
}

CQLValue CQLFunctionRep::numericToString(const CIMInstance& CI,
                                         const QueryContext& queryCtx) const
{
    PEG_METHOD_ENTER(TRC_CQL,"CQLFunctionRep::numericToString()");
    char buffer[128];
    
    if(_parms.size() != 1)
    {
        char buf[10];
        sprintf(buf, "%d", _parms.size());
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_COUNT",
            "Function $0 has $1 parameters."
                "  It must have between $2 and $3.",
            functionTypeToString(),
            String(buf),
            String("1"), String("1"));
        throw CQLRuntimeException(mload);
    }
    
    CQLValue cqlVal = _parms[0].getSimplePredicate().getLeftExpression().
        resolveValue(CI,queryCtx);

    CQLValue::CQLValueType valType = cqlVal.getValueType();  

    if (valType != CQLValue::Sint64_type && valType != CQLValue::Uint64_type
        && valType != CQLValue::Real_type)
    {
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_TYPE",
            "Parameter $0 for function $1 has type $2."
                "  It must be type $3.",
            "1",
            functionTypeToString(),
            CQLValueRep::valueTypeToString(cqlVal.getValueType()),
            String("Integer or Real"));
        throw CQLRuntimeException(mload);
    }

    if (cqlVal.isNull())
    {
        return CQLValue(CIMValue(CIMTYPE_STRING, false));
    }

    if (valType == CQLValue::Sint64_type)
    {
        sprintf(buffer, "%" PEGASUS_64BIT_CONVERSION_WIDTH "d", 
                cqlVal.getSint());
    }
    else if (valType == CQLValue::Uint64_type)
    {
        sprintf(buffer, "%" PEGASUS_64BIT_CONVERSION_WIDTH "u", 
                cqlVal.getUint());
    }
    else
    {
        sprintf(buffer, "%.16E", cqlVal.getReal());
    }

    String num(buffer);
    if (valType == CQLValue::Real_type)
    {
        // format the exponent
        num = CQLUtilities::formatRealStringExponent(num);
    }
    
    PEG_METHOD_EXIT();
    return CQLValue(num);
}

CQLValue CQLFunctionRep::referenceToString(const CIMInstance& CI,
                                           const QueryContext& queryCtx) const
{
    PEG_METHOD_ENTER(TRC_CQL,"CQLFunctionRep::referenceToString()");
    if(_parms.size() != 1)
    {
        char buf[10];
        sprintf(buf, "%d", _parms.size());
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_COUNT",
            "Function $0 has $1 parameters."
                "  It must have between $2 and $3.",
            functionTypeToString(),
            String(buf),
            String("1"), String("1"));
        throw CQLRuntimeException(mload);
    }
    
    CQLValue cqlVal = _parms[0].getSimplePredicate().getLeftExpression().
        resolveValue(CI,queryCtx);
   
    CQLValue::CQLValueType valType = cqlVal.getValueType();

    if (valType != CQLValue::CIMReference_type &&
        valType != CQLValue::CIMObject_type)
    {
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_TYPE",
            "Parameter $0 for function $1 has type $2."
                "  It must be type $3.",
            "1",
            functionTypeToString(),
            CQLValueRep::valueTypeToString(valType),
            String("Reference, or Object"));
        throw CQLRuntimeException(mload);
    }

    if (cqlVal.isNull())
    {
        return CQLValue(CIMValue(CIMTYPE_STRING, false));
    }

    if (valType == CQLValue::CIMReference_type)
    {
        PEG_METHOD_EXIT();
        return CQLValue(cqlVal.getReference().toString());
    }

    // We have CIMObject now, convert to string.
    PEG_METHOD_EXIT();
    return CQLValue(cqlVal.getObject().getPath().toString());
}

CQLValue CQLFunctionRep::className(const CIMInstance& CI,
                                   const QueryContext& queryCtx) const
{
    PEG_METHOD_ENTER(TRC_CQL,"CQLFunctionRep::className()");
    int parmSize = _parms.size();
    if(parmSize != 0 && parmSize != 1)
    {
        char buf[10];
        sprintf(buf, "%d", _parms.size());
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_COUNT",
            "Function $0 has $1 parameters."
                "  It must have between $2 and $3.",
            functionTypeToString(),
            String(buf),
            String("0"), String("1"));
        throw CQLRuntimeException(mload);
    }

    // If there are no parameters, the default behavior is to
    // return the class name for the instance being examined (CI).
    if (parmSize == 0)
    {
        PEG_METHOD_EXIT();
        return CQLValue(CI.getClassName().getString());
    }

    // We have a parameter, so resolve it first before we use it.
    CQLValue cqlVal = _parms[0].getSimplePredicate().getLeftExpression().
        resolveValue(CI,queryCtx);

    CQLValue::CQLValueType valType = cqlVal.getValueType();

    if (valType != CQLValue::CIMReference_type &&
        valType != CQLValue::CIMObject_type &&
        valType != CQLValue::String_type)
    {
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_TYPE",
            "Parameter $0 for function $1 has type $2."
                "  It must be type $3.",
            "1",
            functionTypeToString(),
            CQLValueRep::valueTypeToString(valType),
            String("Reference, String, or Object"));
        throw CQLRuntimeException(mload);
    }

    if (cqlVal.isNull())
    {
        return CQLValue(CIMValue(CIMTYPE_STRING, false));
    }

    // If we have a String parameter, then we'll use it to
    //  create a CIMObjectPath in order to verify the format is correct.
    //   We will then get the class from the object path and return it.
    if (cqlVal.getValueType() == CQLValue::String_type)
    {
        CIMObjectPath objPath(cqlVal.getString());
        PEG_METHOD_EXIT();
        return CQLValue(objPath.getClassName().getString());
    }

    // If we have a CIMReference parameter, then we will just get the class
    //  name from the reference and return it.  A refernce is a CIMObjectPath.
    if (cqlVal.getValueType() == CQLValue::CIMReference_type)
    {
        PEG_METHOD_EXIT();
        return CQLValue(cqlVal.getReference().getClassName().getString());
    }

    // We have a CIMObject, then we return the class name of the obejct
    PEG_METHOD_EXIT();
    return CQLValue(cqlVal.getObject().getClassName().getString());
}

CQLValue CQLFunctionRep::nameSpaceName(const CIMInstance& CI,
                                       const QueryContext& queryCtx) const
{
    PEG_METHOD_ENTER(TRC_CQL,"CQLFunctionRep::nameSpaceName()");
    int parmSize = _parms.size();
    if(parmSize != 0 && parmSize != 1)
    {
        char buf[10];
        sprintf(buf, "%d", _parms.size());
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_COUNT",
            "Function $0 has $1 parameters."
                "  It must have between $2 and $3.",
            functionTypeToString(),
            String(buf),
            String("0"), String("1"));
        throw CQLRuntimeException(mload);
    }

    // The default beavior for this function will first look at the object path
    //  of the instance being examined (CI).  If the path contains a namespace,
    //  we will return it.  If it does not, then we will return the default
    //  namespace from the query context.
    // *** NOTE ***  This does not function entirely according to the CQL spec.
    //  The CQL spec says to return the namespace of the instance regardless
    //  if it is set or not.  However, with the current implementation
    //  (CQL phase 1 PEP 193) we only operate a query engine within a single
    //  namespace and so we can assume the default namespace.
    if (parmSize == 0)
    {
        CIMNamespaceName ns = CI.getPath().getNameSpace();
        if (ns.isNull() || String::equal(ns.getString(), String::EMPTY))
            ns = queryCtx.getNamespace();
        PEG_METHOD_EXIT();
        return CQLValue(ns.getString());    
    }

    // We have a parameter, so resolve it first before we use it.
    CQLValue cqlVal = _parms[0].getSimplePredicate().getLeftExpression().
        resolveValue(CI,queryCtx);

    CQLValue::CQLValueType valType = cqlVal.getValueType();

    if (valType != CQLValue::CIMReference_type &&
        valType != CQLValue::CIMObject_type &&
        valType != CQLValue::String_type)
    {
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_TYPE",
            "Parameter $0 for function $1 has type $2."
                "  It must be type $3.",
            "1",
            functionTypeToString(),
            CQLValueRep::valueTypeToString(cqlVal.getValueType()),
            String("Reference, String, or Object"));
        throw CQLRuntimeException(mload);
    }

    if (cqlVal.isNull())
    {
        return CQLValue(CIMValue(CIMTYPE_STRING, false));
    }

    // If we have a String parameter, then we'll use it to create a
    //  CIMObjectPath in order to verify the format is correct.
    //   We will then get the namespace from the object path and return it.
    //   If there is no namespace in the path given, then an empty string will
    //  be returned.
    if (cqlVal.getValueType() == CQLValue::String_type)
    {
        CIMObjectPath objPath(cqlVal.getString());
        PEG_METHOD_EXIT();
        return CQLValue(objPath.getNameSpace().getString());
    }

    // If we have a CIMReference parameter, then we will just get the
    //  namespace name from the reference and return it.  A refernce is a 
    // CIMObjectPath.  If there is no namespace in the path given, then
    //  an empty string will be returned.
    if (cqlVal.getValueType() == CQLValue::CIMReference_type)
    {
        PEG_METHOD_EXIT();
        return CQLValue(cqlVal.getReference().getNameSpace().getString());
    }

    // We have a CIMObject, now we retrieve the path of the obejct and
    //  check to see if it has a namespace set in it.  If the path contains
    //  a namespace, we will return it.  If it does not, then we will
    //  return the default namespace from the query context.
    // *** NOTE ***  This does not function entirely according to the CQL spec.
    //   The CQL spec says to return the namespace of the instance
    //  regardless if it is set or not.  However, with the current
    //  implementation (CQL phase 1 PEP 193) we only operate a query
    //  engine within a single namespace and so we can assume the default 
    //  namespace. 
    CIMNamespaceName ns = cqlVal.getObject().getPath().getNameSpace();
    if (ns.isNull() || String::equal(ns.getString(), String::EMPTY))
        ns = queryCtx.getNamespace();
    PEG_METHOD_EXIT();
    return CQLValue(ns.getString());
}

CQLValue CQLFunctionRep::nameSpaceType(const CIMInstance& CI,
                                       const QueryContext& queryCtx) const
{
    PEG_METHOD_ENTER(TRC_CQL,"CQLFunctionRep::nameSpaceType()");
    // This is currently (as of CQL Phase 1, PEP 193) not supported in 
    // Pegasus since Pegasus does not yet support WEBM URI references.  
    // Nothing in the current object path can be used to represent 
    // the name space type (i.e. the protocol).
    MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_COUNT",
        "Function $0 is not supported.",
        functionTypeToString());
    throw CQLRuntimeException(mload);
    
    PEGASUS_UNREACHABLE
    (
        int parmSize = _parms.size();
        if(parmSize != 0 && parmSize != 1)
        {
            char buf[10];
            sprintf(buf, "%d", _parms.size());
            MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_COUNT",
                "Function $0 has $1 parameters."
                    "  It must have between $2 and $3.",
                functionTypeToString(),
                String(buf),
                String("0"), String("1"));
            throw CQLRuntimeException(mload);
        }
        
        PEG_METHOD_EXIT();
        return CQLValue(Uint64(0));
    ) // End PEGASUS_UNREACHABLE
}

CQLValue CQLFunctionRep::hostPort(const CIMInstance& CI,
                                  const QueryContext& queryCtx) const
{
    PEG_METHOD_ENTER(TRC_CQL,"CQLFunctionRep::hostPort()");
    // Pegasus currently (as of CQL Phase 1, PEP 193) does not 
    // support WEBM URI references, however the current object 
    // path dose have a host on it which we will return.  Until 
    // Pegasus supportse WEBM URI, it is not guaranteed that this 
    // will onform to the format defined in WBEM URI, and therefore
    //  this function is not entirely in accordance with the CQL Specification.
    // In addition, the CQL specification allows for the parameter
    //  to be left off when the query is executed as a result  of 
    // an ExecuteQuery operation.  However, right now
    //  (as of CQL Phase 1, PEP 193) we are only using this for
    //  Indications, and so we are assuming a "Mode" of operation.
    //   For this function to be completely compliant with the CQL
    // specification, it will eventually need to be "mode" aware.
    
    if(_parms.size() != 1)
    {
        char buf[10];
        sprintf(buf, "%d", _parms.size());
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_COUNT",
            "Function $0 has $1 parameters."
                "  It must have between $2 and $3.",
            functionTypeToString(),
            String(buf),
            String("1"), String("1"));
        throw CQLRuntimeException(mload);
    }

    // We have a parameter, so resolve it first before we use it.
    CQLValue cqlVal = _parms[0].getSimplePredicate().getLeftExpression().
      resolveValue(CI,queryCtx);

    CQLValue::CQLValueType valType = cqlVal.getValueType();

    if (valType != CQLValue::CIMReference_type &&
        valType != CQLValue::CIMObject_type &&
        valType != CQLValue::String_type)
    {
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_TYPE",
            "Parameter $0 for function $1 has type $2."
                "  It must be type $3.",
            String("1"),
            functionTypeToString(),
            CQLValueRep::valueTypeToString(valType),
            String("Reference, String, or Object"));
        throw CQLRuntimeException(mload);
    }

    if (cqlVal.isNull())
    {
        return CQLValue(CIMValue(CIMTYPE_STRING, false));
    }
  
    // If we have a String parameter, then we'll use it to create a 
    // CIMObjectPath in order to verify the format is correct.  We will
    //  then get the host from the object path and return it.  If there
    //  is no host in the path given, then an empty string will be returned.
    if (cqlVal.getValueType() == CQLValue::String_type)
    {
        CIMObjectPath objPath(cqlVal.getString());
        PEG_METHOD_EXIT();
        return CQLValue(objPath.getHost());
    }

    // If we have a CIMReference parameter, then we will just get the 
    // host name from the reference and return it.  A reference is a
    //  CIMObjectPath.  If there is no host in the path given, then
    //  an empty string will be returned.
    if (cqlVal.getValueType() == CQLValue::CIMReference_type)
    {
        PEG_METHOD_EXIT();
        return CQLValue(cqlVal.getReference().getHost());
    }

    // We have a CIMObject, now we retrieve the path of the obejct
    //  and return the host from the path.  If there is no host in the
    //  path given, then an empty string will be returned.
    PEG_METHOD_EXIT();
    return CQLValue(cqlVal.getObject().getPath().getHost());
}

CQLValue CQLFunctionRep::modelPath(const CIMInstance& CI,
                                   const QueryContext& queryCtx) const
{
    PEG_METHOD_ENTER(TRC_CQL,"CQLFunctionRep::modelPath()");
    // This method returns the model path portion of an object path. 
    // The model path is the class name and the key bindings (if included)..
    
    int parmSize = _parms.size();
    if(parmSize != 0 && parmSize != 1)
    {
        char buf[10];
        sprintf(buf, "%d", _parms.size());
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_COUNT",
            "Function $0 has $1 parameters."
                "  It must have between $2 and $3.",
            functionTypeToString(),
            String(buf),
            String("0"), String("1"));
        throw CQLRuntimeException(mload);
    }

    // The default behavior for this function will be to retrieve 
    // the object path from the instance being examined (CI) and 
    // then return the model path from that.
    if (parmSize == 0)
    {
        PEG_METHOD_EXIT();
        return buildModelPath(CI.getPath());
    }

    // We have a parameter, so resolve it first before we use it.
    CQLValue cqlVal = _parms[0].getSimplePredicate().getLeftExpression().
      resolveValue(CI,queryCtx);

    CQLValue::CQLValueType valType = cqlVal.getValueType();

    if (valType != CQLValue::CIMReference_type &&
        valType != CQLValue::CIMObject_type &&
        valType != CQLValue::String_type)
    {
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_TYPE",
            "Parameter $0 for function $1 has type $2."
                "  It must be type $3.",
            "1",
            functionTypeToString(),
            CQLValueRep::valueTypeToString(valType),
            String("Reference, String, or Object"));
        throw CQLRuntimeException(mload);
    }

    if (cqlVal.isNull())
    {
        return CQLValue(CIMValue(CIMTYPE_REFERENCE, false));
    }
  
    // If we have a String parameter, then we'll use it to create a 
    // CIMObjectPath in order to verify the format is correct.  
    // We will then get model path from the object path and return it.
    if (cqlVal.getValueType() == CQLValue::String_type)
    {
        CIMObjectPath objPath(cqlVal.getString());
        PEG_METHOD_EXIT();
        return buildModelPath(objPath);
    }

    // If we have a CIMReference parameter, then we will get the model 
    // path from the reference and return it.  A reference is a 
    // CIMObjectPath.
    if (cqlVal.getValueType() == CQLValue::CIMReference_type)
    {
        PEG_METHOD_EXIT();
        return buildModelPath(cqlVal.getReference());
    }

    // We have a CIMObject, now we retrieve the path of the obejct 
    // and return the model path.
    PEG_METHOD_EXIT();
    return buildModelPath(cqlVal.getObject().getPath());
}

CQLValue CQLFunctionRep::buildModelPath(const CIMObjectPath& objPath) const
{
    PEG_METHOD_ENTER(TRC_CQL,"CQLFunctionRep::buildModelPath()");
    // This method will take an existing objet path, pick out the key 
    // bindings and the class name, and use those parts to build a new 
    // object path with just those parts in it.  This is used to 
    // represent the model path.
    CIMObjectPath newPath;
    newPath.setClassName(objPath.getClassName());
    newPath.setKeyBindings(objPath.getKeyBindings());
    //printf("ModelPath --> %s\n", (const char *)newPath.toString().
    // getCString());  
    PEG_METHOD_EXIT();
    return CQLValue(newPath.toString());
}

CQLValue CQLFunctionRep::classPath(const CIMInstance& CI,
                                   const QueryContext& queryCtx) const
{
    PEG_METHOD_ENTER(TRC_CQL,"CQLFunctionRep::classPath()");
    // This method returns a class path.  The class path will only have
    //  a namespace and a class name in it.  All other path information
    //  will be stripped off.  
    int parmSize = _parms.size();
    if(parmSize != 0 && parmSize != 1)
    {
        char buf[10];
        sprintf(buf, "%d", _parms.size());
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_COUNT",
            "Function $0 has $1 parameters."
                "  It must have between $2 and $3.",
            functionTypeToString(),
            String(buf),
            String("0"), String("1"));
        throw CQLRuntimeException(mload);
    }

    // The default behavior for this function will be to retrieve the 
    // object path from the instance being examined (CI) and build the 
    // class path from it.  If the path does not have a namespace, then 
    // the default namespace is used.
    if (parmSize == 0)
    {
        CIMObjectPath objPath(CI.getPath());
        CIMNamespaceName ns = objPath.getNameSpace();
        if (ns.isNull() || String::equal(ns.getString(), String::EMPTY))
          ns = queryCtx.getNamespace();
        PEG_METHOD_EXIT();
        return buildClassPath(objPath, ns);
    }

    // We have a parameter, so resolve it first before we use it.
    CQLValue cqlVal = _parms[0].getSimplePredicate().getLeftExpression().
      resolveValue(CI,queryCtx);

    CQLValue::CQLValueType valType = cqlVal.getValueType();

    if (valType != CQLValue::CIMReference_type &&
        valType != CQLValue::CIMObject_type &&
        valType != CQLValue::String_type)
    {
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_TYPE",
            "Parameter $0 for function $1 has type $2."
                "  It must be type $3.",
            "1",
            functionTypeToString(),
            CQLValueRep::valueTypeToString(cqlVal.getValueType()),
            String("Reference, String, or Object"));
        throw CQLRuntimeException(mload);
    }

    if (cqlVal.isNull())
    {
        return CQLValue(CIMValue(CIMTYPE_REFERENCE, false));
    }
  
    // If we have a String parameter, then we'll use it to create a 
    // CIMObjectPath in order to verify the format is correct.  We will 
    // then build the class path from the object path and return it.  
    // If the namespace is NOT set in the object path, it will remain 
    // unset in the returned reference.
    if (cqlVal.getValueType() == CQLValue::String_type)
    {
        CIMObjectPath objPath(cqlVal.getString());
        PEG_METHOD_EXIT();
        return buildClassPath(objPath, objPath.getNameSpace());
    }

    // If we have a CIMReference parameter, then we will build the class 
    // path from the reference and return it.  If the namespace is NOT 
    // set in the object path, it will remain unset in the returned reference.
    if (cqlVal.getValueType() == CQLValue::CIMReference_type)
    {
        CIMObjectPath objPath = cqlVal.getReference();
        PEG_METHOD_EXIT();
        return buildClassPath(objPath, objPath.getNameSpace());
    }

    // We have a CIMObject, now we retrieve the object path  and 
    // build the class path from it.  If the path does not have a namespace,
    // then the default namespace is used.
    CIMObjectPath objPath = cqlVal.getObject().getPath();
    CIMNamespaceName ns = objPath.getNameSpace();
    if (ns.isNull() || String::equal(ns.getString(), String::EMPTY))
    {
        ns = queryCtx.getNamespace();
    }
    PEG_METHOD_EXIT();
    return buildClassPath(objPath, ns);
}

CQLValue CQLFunctionRep::buildClassPath(const CIMObjectPath& objPath,
                                        const CIMNamespaceName& ns) const
{
    PEG_METHOD_ENTER(TRC_CQL,"CQLFunctionRep::buildClassPath()");
    // This method will take the object path pass in and pick out the host,
    // the class name and the namespace.  The 2 parts are then combined 
    // together into a new object path which will be used as the class 
    // path and returned.
    CIMObjectPath newPath;
    newPath.setHost(objPath.getHost());
    newPath.setClassName(objPath.getClassName());  
    newPath.setNameSpace(ns);
    // printf("ClassPath --> %s\n", (const char *)newPath.toString().
    // getCString());
    PEG_METHOD_EXIT();
    return CQLValue(newPath);
}


CQLValue CQLFunctionRep::objectPath(const CIMInstance& CI,
                                    const QueryContext& queryCtx) const
{
    PEG_METHOD_ENTER(TRC_CQL,"CQLFunctionRep::objectPath()");
    // This method returns an object path.  The object path will only have a
    // namespace, a class name, and key bindings if it is a path to an 
    // instance.  All other path information will be stripped off.
    
    int parmSize = _parms.size();
    if(parmSize != 0 && parmSize != 1)
    {
        char buf[10];
        sprintf(buf, "%d", _parms.size());
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_COUNT",
            "Function $0 has $1 parameters."
                "  It must have between $2 and $3.",
            functionTypeToString(),
            String(buf),
            String("0"), String("1"));
        throw CQLRuntimeException(mload);
    }

    // The default behavior for this function will be to retrieve the
    // object path from the instance being examined (CI) and build the 
    // object path from it.  If the path does not have a namespace, 
    // then the default namespace is used.
    if (parmSize == 0)
    {
        CIMObjectPath objPath(CI.getPath());
        CIMNamespaceName ns = objPath.getNameSpace();
        if (ns.isNull() || String::equal(ns.getString(), String::EMPTY))
          ns = queryCtx.getNamespace();
        PEG_METHOD_EXIT();
        return buildObjectPath(objPath, ns);
    }

    // We have a parameter, so resolve it first before we use it.
    CQLValue cqlVal = _parms[0].getSimplePredicate().getLeftExpression().
      resolveValue(CI,queryCtx);

    CQLValue::CQLValueType valType = cqlVal.getValueType();

    if (valType != CQLValue::CIMReference_type &&
        valType != CQLValue::CIMObject_type &&
        valType != CQLValue::String_type)
    {
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_TYPE",
            "Parameter $0 for function $1 has type $2."
                "  It must be type $3.",
            String("1"),
            functionTypeToString(),
            CQLValueRep::valueTypeToString(cqlVal.getValueType()),
            String("Reference, String, or Object"));
        throw CQLRuntimeException(mload);
    }

    if (cqlVal.isNull())
    {
        return CQLValue(CIMValue(CIMTYPE_REFERENCE, false));
    }
    
    // If we have a String parameter, then we'll use it to create a 
    // CIMObjectPath in order to verify the format is correct.  
    // We will then build the object path from the object path and return it.  
    // If the namespace is NOT set in the object path, it will remain 
    // unset in the returned reference.
    if (cqlVal.getValueType() == CQLValue::String_type)
    {
        CIMObjectPath objPath(cqlVal.getString());
        PEG_METHOD_EXIT();
        return buildObjectPath(objPath, objPath.getNameSpace());
    }
  
    // If we have a CIMReference parameter, then we will build the object 
    // path from the reference and return it.  If the namespace is NOT 
    // set in the object path, it will remain unset in the returned reference.
    if (cqlVal.getValueType() == CQLValue::CIMReference_type)
    {
        CIMObjectPath objPath = cqlVal.getReference();
        PEG_METHOD_EXIT();
        return buildObjectPath(objPath, objPath.getNameSpace());
    }

    // We have a CIMObject, now we retrieve the object path of the 
    // obejct and build the object path from it.  If the path does not 
    // have a namespace, then the default namespace is used.
    CIMObjectPath objPath = cqlVal.getObject().getPath();
    CIMNamespaceName ns = objPath.getNameSpace();
    if (ns.isNull() || String::equal(ns.getString(), String::EMPTY))
    {
        ns = queryCtx.getNamespace();
    }
    PEG_METHOD_EXIT();
    return buildObjectPath(objPath, ns);
}

CQLValue CQLFunctionRep::buildObjectPath(const CIMObjectPath& objPath,
                                         const CIMNamespaceName& ns) const
{
    PEG_METHOD_ENTER(TRC_CQL,"CQLFunctionRep::buildObjectPath()");
    // This method will take the object path passed in and pick out the host,
    // the class name, the namespace, and the key bindings.  The parts are 
    // then combined together into a new object path which will be used 
    // as the object path and returned.
    CIMObjectPath newPath;
    newPath.setHost(objPath.getHost());
    newPath.setClassName(objPath.getClassName());  
    newPath.setNameSpace(ns);
    newPath.setKeyBindings(objPath.getKeyBindings());
    PEG_METHOD_EXIT();
    return CQLValue(newPath);
}

CQLValue CQLFunctionRep::instanceToReference(const CIMInstance& CI,
                                          const QueryContext& queryCtx) const
{
    PEG_METHOD_ENTER(TRC_CQL,"CQLFunctionRep::instanceToReference()");
    // The parameter to this function MUST be an instance object.  
    // We will use buildPath on the instance to make the path.  
    // If there is no namespace on the instance, then the default namespace
    // will be inserted.  The completed path is then returned.  
    // Note, this could, and should be a more complete reference 
    // than the other path functions.
    
    int parmSize = _parms.size();
    if(parmSize != 0 && parmSize != 1)
    {
        char buf[10];
        sprintf(buf, "%d", _parms.size());
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_COUNT",
            "Function $0 has $1 parameters."
                "  It must have between $2 and $3.",
            functionTypeToString(),
            String(buf),
            String("0"), String("1"));
        throw CQLRuntimeException(mload);
    }
    CIMInstance *inst = NULL;
    Boolean cleanup = false;  // whether or not to delete the memory
    CIMObject obj;
    
    // The default behavior is to use the instance being examined 
    // as the source instance (CI).
    if (parmSize == 0)
        inst = (CIMInstance *)&CI;
    else
    {
        // We have a parameter, so resolve it first before we use it.
        CQLValue cqlVal = _parms[0].getSimplePredicate().getLeftExpression().
            resolveValue(CI,queryCtx);

        // Parameter MUST be an instance object
        if (cqlVal.getValueType() != CQLValue::CIMObject_type)
        {
            MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_TYPE",
            "Parameter $0 for function $1 has type $2."
                "  It must be type $3.",
            "1",
            functionTypeToString(),
            CQLValueRep::valueTypeToString(cqlVal.getValueType()),
            CQLValueRep::valueTypeToString(CQLValue::CIMObject_type));
            throw CQLRuntimeException(mload);
        }

        if (cqlVal.isNull())
        {
            return CQLValue(CIMValue(CIMTYPE_REFERENCE, false));
        }
    
        // REVIEW question.  Inefficient since the CIMobject is copied
        //  via the return by value, then it is copied again via the 
        // assignment.  Is there a better way to handle this?
        obj = cqlVal.getObject();
        if (!obj.isInstance())
        {
            MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_OBJECT_TYPE",
            "Parameter $0 for function $1 must be a CIM instance.",
            "1",
            functionTypeToString());
            throw CQLRuntimeException(mload);
        }
        // Make a CIM Instance
        inst = new CIMInstance(obj);
        cleanup = true;
    }
  
    // Get the class and build the path
    CIMConstClass cls = queryCtx.getClass(inst->getClassName());
    CIMObjectPath objPath = inst->buildPath(cls);
    CIMNamespaceName ns = objPath.getNameSpace();

    if (ns.isNull() || String::equal(ns.getString(), String::EMPTY))
        objPath.setNameSpace(queryCtx.getNamespace());
    
    if (cleanup)
    {
        delete inst;
        inst = NULL;
    }
    PEG_METHOD_EXIT();
    return CQLValue(objPath);
}

CQLValue CQLFunctionRep::currentDateTime() const
{
    PEG_METHOD_ENTER(TRC_CQL,"CQLFunctionRep::currentDateTime()");
    if(_parms.size() != 0)
    {
        char buf[10];
        sprintf(buf, "%d", _parms.size());
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_COUNT",
            "Function $0 has $1 parameters."
                "  It must have between $2 and $3.",
            functionTypeToString(),
            String(buf),
            String("0"), String("0"));
        throw CQLRuntimeException(mload);
    }

    PEG_METHOD_EXIT();
    return(CQLValue(CIMDateTime::getCurrentDateTime()));
}

CQLValue CQLFunctionRep::dateTime(const CIMInstance& CI,
                                  const QueryContext& queryCtx) const
{
    PEG_METHOD_ENTER(TRC_CQL,"CQLFunctionRep::dateTime()");
    if(_parms.size() != 1)
    {
        char buf[10];
        sprintf(buf, "%d", _parms.size());
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_COUNT",
            "Function $0 has $1 parameters."
                "  It must have between $2 and $3.",
            functionTypeToString(),
            String(buf),
            String("1"), String("1"));
        throw CQLRuntimeException(mload);
    }
    
    CQLValue cqlVal = _parms[0].getSimplePredicate().getLeftExpression().
        resolveValue(CI,queryCtx);  

    if(cqlVal.getValueType() != CQLValue::String_type)
    {
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_TYPE",
            "Parameter $0 for function $1 has type $2."
                "  It must be type $3.",
            "1",
            functionTypeToString(),
            CQLValueRep::valueTypeToString(cqlVal.getValueType()),
            CQLValueRep::valueTypeToString(CQLValue::String_type));
        throw CQLRuntimeException(mload);
    }

    if (cqlVal.isNull())
    {
        return CQLValue(CIMValue(CIMTYPE_DATETIME, false));
    }
    
    CIMDateTime dt(cqlVal.getString());
    PEG_METHOD_EXIT();
    return(CQLValue(dt));
}

CQLValue CQLFunctionRep::microsecondToTimestamp(const CIMInstance& CI,
                                            const QueryContext& queryCtx) const
{
    PEG_METHOD_ENTER(TRC_CQL,"CQLFunctionRep::microsecondToTimestamp()");
    if(_parms.size() != 1)
    {
        char buf[10];
        sprintf(buf, "%d", _parms.size());
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_COUNT",
            "Function $0 has $1 parameters."
                "  It must have between $2 and $3.",
            functionTypeToString(),
            String(buf),
            String("1"), String("1"));
        throw CQLRuntimeException(mload);
    }

    CQLValue cqlVal = _parms[0].getSimplePredicate().getLeftExpression().
      resolveValue(CI,queryCtx);

    CQLValue::CQLValueType valType = cqlVal.getValueType();  
    if(valType != CQLValue::Uint64_type &&
        valType != CQLValue::Sint64_type)
    {
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_TYPE",
            "Parameter $0 for function $1 has type $2."
                "  It must be type $3.",
            "1",
            functionTypeToString(),
            CQLValueRep::valueTypeToString(valType),
            String("Integer"));
        throw CQLRuntimeException(mload);
    }

    if (cqlVal.isNull())
    {
        return CQLValue(CIMValue(CIMTYPE_UINT64, false));
    }
 
    Uint64 uIntVal = 0;
    if (valType == CQLValue::Sint64_type)
    {
        Sint64 intVal = cqlVal.getSint();
        if (intVal < 0)
        {
          char negVal[100];
          sprintf(negVal, "%" PEGASUS_64BIT_CONVERSION_WIDTH "d", intVal);
          MessageLoaderParms mload("CQL.CQLFunctionRep.NEGATIVE_INT_ERROR",
            "Parameter $0 for function $1 has a value of $2."
                   "  It must be non-negative.",
            "1",
            functionTypeToString(),
            String(negVal));
          throw CQLRuntimeException(mload);
        }
        uIntVal = intVal;
    }
    else
        uIntVal = cqlVal.getUint();
    
    PEG_METHOD_EXIT();
    
    return CQLValue(CIMDateTime(uIntVal, false));
}

CQLValue CQLFunctionRep::microsecondToInterval(const CIMInstance& CI,
                                            const QueryContext& queryCtx) const
{
    PEG_METHOD_ENTER(TRC_CQL,"CQLFunctionRep::microsecondToInterval()");
    if(_parms.size() != 1)
    {
        char buf[10];
        sprintf(buf, "%d", _parms.size());
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_COUNT",
            "Function $0 has $1 parameters."
                "  It must have between $2 and $3.",
            functionTypeToString(),
            String(buf),
            String("1"), String("1"));
        throw CQLRuntimeException(mload);
    }
    
    CQLValue cqlVal = _parms[0].getSimplePredicate().getLeftExpression().
      resolveValue(CI,queryCtx);

    CQLValue::CQLValueType valType = cqlVal.getValueType();  
    if(valType != CQLValue::Uint64_type &&
     valType != CQLValue::Sint64_type)
    {
        MessageLoaderParms mload("CQL.CQLFunctionRep.INVALID_PARM_TYPE",
            "Parameter $0 for function $1 has type $2."
                "  It must be type $3.",
            "1",
            functionTypeToString(),
            CQLValueRep::valueTypeToString(valType),
            String("Integer"));
        throw CQLRuntimeException(mload);
    }

    if (cqlVal.isNull())
    {
        return CQLValue(CIMValue(CIMTYPE_UINT64, false));
    }
    
    Uint64 uIntVal = 0;
    
    if (valType == CQLValue::Sint64_type)
    {
        Sint64 intVal = cqlVal.getSint();
        if (intVal < 0)
        {
            char negVal[100];
            sprintf(negVal, "%" PEGASUS_64BIT_CONVERSION_WIDTH "d", intVal);
            MessageLoaderParms mload("CQL.CQLFunctionRep.NEGATIVE_INT_ERROR",
                "Parameter $0 for function $1 has a value of $2."
                    "  It must be non-negative.",
                "1",
                functionTypeToString(),
                String(negVal));
            throw CQLRuntimeException(mload);
        }
        uIntVal = intVal;
    }
    else
    uIntVal = cqlVal.getUint();
    
    PEG_METHOD_EXIT();
    return CQLValue(CIMDateTime(uIntVal, true));  
}

PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2