⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cqlselectstatementrep.cpp

📁 Pegasus is an open-source implementationof the DMTF CIM and WBEM standards. It is designed to be por
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                 allowMissing);}Boolean CQLSelectStatementRep::applyProjection(PropertyNode* node,                                               CIMProperty& nodeProp,                                               Boolean& preservePropsForParent,                                               Boolean allowMissing){  PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::applyProjection(node, nodeProp)");  PEGASUS_ASSERT(node->firstChild.get() != NULL || node->wildcard);  //  // The property passed in must be an embedded instance. It is not  // allowed to project properties on embedded classes.  // Get the embedded instance from the property.  //  // First check that it is an embedded object  CIMValue nodeVal = nodeProp.getValue();  CIMType nodeValType = nodeVal.getType();  if (nodeValType != CIMTYPE_OBJECT#ifdef PEGASUS_EMBEDDED_INSTANCE_SUPPORT    && nodeValType != CIMTYPE_INSTANCE#endif // PEGASUS_EMBEDDED_INSTANCE_SUPPORT    )  {    PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"not emb");    PEG_METHOD_EXIT();    MessageLoaderParms parms("CQL.CQLSelectStatementRep.PROP_NOT_EMB",                             "The property $0 must contain an embedded object.",                             nodeProp.getName().getString());    throw CQLRuntimeException(parms);  }  if (nodeVal.isNull())  {    // Since we will be projecting on the embedded object, it cannot be null    PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"value is null");    PEG_METHOD_EXIT();    MessageLoaderParms parms("CQL.CQLSelectStatementRep.NULL_EMB_OBJ",                             "The embedded object property $0 cannot contain a null value.",                             nodeProp.getName().getString());    throw CQLRuntimeException(parms);  }  if (nodeVal.isArray() &&      (node->firstChild.get() != NULL || node->wildcard))  {    // NOTE - since we are blocking projection of array elements, we can    // assume that if we get here we were told to project a whole array (ie. no index used), as    // an embedded object with properties or wildcard.    // Examples not allowed:  SELECT fromClass.someArrayProp.scope::notAllowedProp FROM fromClass    //                        SELECT fromClass.someArrayProp.* FROM fromClass    PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"array index needed");    PEG_METHOD_EXIT();    MessageLoaderParms parms("CQL.CQLSelectStatementRep.PROJ_WHOLE_ARRAY",                  "CQL requires that array indexing is used on embedded object property $0.",                   nodeProp.getName().getString());    throw CQLRuntimeException(parms);  }  CIMObject nodeObj;  // this starts uninitialized  CIMInstance nodeInst;#ifdef PEGASUS_EMBEDDED_INSTANCE_SUPPORT  if(nodeValType == CIMTYPE_OBJECT)  {#endif // PEGASUS_EMBEDDED_INSTANCE_SUPPORT  nodeVal.get(nodeObj);  if (nodeObj.isUninitialized())  {    // Not allowed to project on an uninitialized object    PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"is uninitialized");    PEG_METHOD_EXIT();    MessageLoaderParms parms("CQL.CQLSelectStatementRep.PROJ_UNINIT",                             "The embedded object property $0 is uninitialized.",                             nodeProp.getName().getString());    throw CQLRuntimeException(parms);  }  if (!nodeObj.isInstance())  {    // Not allowed to project on a Class    PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"is a class");    PEG_METHOD_EXIT();    MessageLoaderParms parms("CQL.CQLSelectStatementRep.PROJ_CLASS",                             "CQL does not allow properties to be projected on class $0.",                             nodeProp.getName().getString());    throw CQLRuntimeException(parms);  }  nodeInst = CIMInstance(nodeObj);#ifdef PEGASUS_EMBEDDED_INSTANCE_SUPPORT  }  else if(nodeValType == CIMTYPE_INSTANCE)  {    nodeVal.get(nodeInst);    if (nodeInst.isUninitialized())    {      // Not allowed to project on an uninitialized object      PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"is uninitialized");      PEG_METHOD_EXIT();      MessageLoaderParms parms("CQL.CQLSelectStatementRep.PROJ_UNINIT",                              "The embedded object property $0 is uninitialized.",                              nodeProp.getName().getString());      throw CQLRuntimeException(parms);    }  }#endif // PEGASUS_EMBEDDED_INSTANCE_SUPPORT  //  // Do the projection.  //  Array<CIMName> requiredProps;  Boolean allPropsRequired = node->wildcard;  // Loop through the children of the node.  // The node represents an embedded instance,  // and the child nodes are the required properties on the embedded instance.  PropertyNode * curChild = node->firstChild.get();  while (curChild != NULL)  {    PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"project childNode = " + curChild->name.getString());    // Determine if the embedded instance meets the class scoping    // rules for the current child node    Boolean filterable = isFilterable(nodeInst, curChild);    // Indicates if the child node is still required after the recursive call.    Boolean childRequired = true;    // If the embedded instance is filterable, and the child node has children,    // or is wildcarded, then the child is assumed to be an embedded instance,    // and we need to recurse to apply the projection on the embedded instance.    // (the check for embedded instance is done in the recursive call)    if (filterable &&        (curChild->firstChild.get() != NULL || curChild->wildcard))    {      // We need to project on an embedded instance property. The steps are to      // remove the embedded instance property from the current instance,      // project on that embedded instance property, and then add the projected      // embedded instance property back to the current instance.      PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"about to recurse: " + curChild->name.getString());      Uint32 index = nodeInst.findProperty(curChild->name);      if (index != PEG_NOT_FOUND)      {        // The current instance has the required embedded instance property.        // Note: embedded instance property missing is caught below.        // Remove the embedded instance property        CIMProperty childProp = nodeInst.getProperty(index);        nodeInst.removeProperty(index);        // Project onto the embedded instance property.        // If the last parameter is true, then the childNode        // will not remove properties when filtering the embedded instance.        // This call returns whether the embedded instance property        // should be added to the required property list.        Boolean preserve =          node->endpoint || allPropsRequired || preservePropsForParent;        childRequired = applyProjection(curChild, childProp, preserve,             allowMissing);        nodeInst.addProperty(childProp);      }    }    // If the embedded instance is filterable,    // then add the current child to the list if it is still required.    if (filterable && childRequired)    {      // The instance is filterable, add the property to the required list.      PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"add req prop: " + curChild->name.getString());      requiredProps.append(curChild->name);    }    curChild = curChild->sibling.get();  }  // Filter the instance.  // This removes unneeded properties, unless this  // embedded instance node was an endpoint (last element)  // in a chained identifier.  // This also checks for missing required properties on the instance.  Boolean preserveProps = node->endpoint || preservePropsForParent;  filterInstance(nodeInst,                 allPropsRequired,                 nodeInst.getClassName(),                 requiredProps,                 preserveProps,                 allowMissing);  // Put the projected instance back into the property.#ifdef PEGASUS_EMBEDDED_INSTANCE_SUPPORT  if(nodeValType == CIMTYPE_INSTANCE)  {    nodeProp.setValue(nodeInst);  }  else#endif  {  CIMObject newNodeObj(nodeInst);  CIMValue newNodeVal(newNodeObj);  nodeProp.setValue(newNodeVal);  }  // Indicate to the caller whether the projected instance  // is still a required property.  It is required if it is an endpoint  // (ie. the last element of a chained identifier)  // OR if it still has properties after being projected  if (node->endpoint || nodeInst.getPropertyCount() > 0)  {    return true;  }  return false;}Boolean CQLSelectStatementRep::isFilterable(const  CIMInstance& inst,                                            PropertyNode* node){  PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::isFilterable");  PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"instance = " + inst.getClassName().getString());  PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"scope = " + node->scope.getString());  //  // Determine if an instance is filterable for a scoped property (ie. its  // type is the scoping class or a subclass of the scoping class where the  // property exists)  //  // Note that an instance that is unfilterable is not considered  // an error.  In CQL, an instance that is not of the required scope  // would cause a NULL to be placed in the result set column for the  // property. However since we are not implementing result set in stage1,  // just skip the property.  This can lead to an instance having  // NO required properties even though it is derived from the FROM class.  // This can easily happen if the scoping operator is used.  //  Boolean filterable = false;  if (inst.getClassName() == node->scope)  {    // The instance's class is the same as the required scope    PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"instance matches scope");    filterable = true;  }  else  {    try    {      if (_ctx->isSubClass(node->scope, inst.getClassName()))      {        // The instance's class is a subclass of the required scope.        PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"instance is subclass of scope");        filterable = true;      }    }    catch (const CIMException& ce)    {      if (ce.getCode() == CIM_ERR_INVALID_CLASS ||          ce.getCode() == CIM_ERR_NOT_FOUND)      {        // The scoping class was not found in the schema.        // Just swallow this error because according to the        // spec we should be putting NULL in the result column,        // which means skipping the property on the instance.        PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"scope class not in schema");      }      else      {        PEG_METHOD_EXIT();        throw;      }    }  }  PEG_METHOD_EXIT();  return filterable;}void CQLSelectStatementRep::filterInstance(CIMInstance& inst,                                           Boolean& allPropsRequired,                                           const CIMName& allPropsClass,                                           Array<CIMName>& requiredProps,                                           Boolean& preserveProps,    Boolean allowMissing){  PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::filterInstance");  PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"instance = " + inst.getClassName().getString());  PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"allPropsClass = " + allPropsClass.getString());  // Implementation note:  // Scoping operator before a wildcard is not allowed:  // Example:  // SELECT fromclass.embobj1.scope1::* FROM fromclass  //  // However, the following are allowed:  // SELECT fromclass.embobj1.* FROM fromclass  // (this means that all the properties on the class of instance embobj1  //  are required)  //  // SELECT fromclass.* FROM fromclass  // (this means that all the properties on class fromclass are required  //  to be on the instance being projected, not including any  //  properties on a subclass of fromclass)  // If all properties are required (ie. wildcarded), then add  // all the properties of allPropsClass to the required list.  // The allPropsClass is either the FROM class or the class of an embedded instance.  if (allPropsRequired)  {    PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"all props required");    CIMClass cls = _ctx->getClass(allPropsClass);    Array<CIMName> clsProps;    for (Uint32 i = 0; i < cls.getPropertyCount(); i++)    {      if (!containsProperty(cls.getProperty(i).getName(), requiredProps))      {        requiredProps.append(cls.getProperty(i).getName());      }    }  }  // Find out what properties are on the instance.  Array<CIMName> supportedProps;  for (Uint32 i = 0; i < inst.getPropertyCount(); i++)  {    supportedProps.append(inst.getProperty(i).getName());  }  // Check that all required properties are on the instance.  if (!allowMissing)  {      for (Uint32 i = 0; i < requiredProps.size(); i++)      {          if (!containsProperty(requiredProps[i], supportedProps))          {              PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"missing:" +                   requiredProps[i].getString());              PEG_METHOD_EXIT();              MessageLoaderParms parms                  ("CQL.CQLSelectStatementRep.PROJ_MISSING_PROP",                  "The property $0 is missing on the instance of class $1.",                  requiredProps[i].getString(),                  inst.getClassName().getString());              throw QueryRuntimePropertyException(parms);          }      }  }  // If requested, remove the properties on the instance that are not required.  if (!preserveProps)  {    for (Uint32 i = 0; i < supportedProps.size(); i++)    {      if (!containsProperty(supportedProps[i], requiredProps))      {        Uint32 index = inst.findProperty(supportedProps[i]);        PEGASUS_ASSERT(index != PEG_NOT_FOUND);        PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"removing:" + supportedProps[i].getString());        inst.removeProperty(index);      }    }  }  PEG_METHOD_EXIT();}//// Validates that all the chained identifiers in the statement meet// the rules in the CQL spec vs.the class definitions in the repository//void CQLSelectStatementRep::validate(){  PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::validate");  if(_ctx == NULL)  {    PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"null QC");    PEG_METHOD_EXIT();    MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL",                             "Trying to process a query with a NULL Query Context.");    throw QueryValidationException(parms);  }  if (!_contextApplied)    applyContext();  for (Uint32 i = 0; i < _selectIdentifiers.size(); i++)  {    validateProperty(_selectIdentifiers[i]);  }  Array<QueryChainedIdentifier> _whereIdentifiers = _ctx->getWhereList();  for (Uint32 i = 0; i < _whereIdentifiers.size(); i++)  {    validateProperty(_whereIdentifiers[i]);  }  PEG_METHOD_EXIT();}//// Validates that the chained identifier meets all the rules in the CQL// spec vs.the class definitions in the repository//void CQLSelectStatementRep::validateProperty(QueryChainedIdentifier& chainId){  PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::validateProperty");  // Note: applyContext has been called beforehand  Array<QueryIdentifier> ids = chainId.getSubIdentifiers();  Uint32 startingPos = 0;  CIMName curContext;  for (Uint32 pos = startingPos; pos < ids.size(); pos++)  {    // Determine the current class context    if (ids[pos].isScoped())    {      // The chain element is scoped.  Use the scoping      // class as the current context.  Note: this depends      // on applyContext resolving the class aliases before we get here.      curContext = CIMName(ids[pos].getScope());    }    else    {      // The chain element is not scoped.  Assume that we are      // before a position that is required to be scoped.      // (applyContext validates that the chained identifier      // has scoped identifiers in the required positions).      // The current context is the name at the first position,      // which must be a classname (ie. right side of ISA where      // the only element in the chain is a classname, or

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -