version 1.2, 2004/11/21 12:13:07
|
version 1.3, 2004/11/29 20:06:57
|
|
|
#include <Pegasus/Query/QueryCommon/QueryException.h> | #include <Pegasus/Query/QueryCommon/QueryException.h> |
#include <Pegasus/Query/QueryCommon/QueryIdentifier.h> | #include <Pegasus/Query/QueryCommon/QueryIdentifier.h> |
#include <Pegasus/Query/QueryCommon/QueryChainedIdentifier.h> | #include <Pegasus/Query/QueryCommon/QueryChainedIdentifier.h> |
|
#include <Pegasus/Common/Tracer.h> |
#include <Pegasus/Common/InternalException.h> | #include <Pegasus/Common/InternalException.h> |
#include <Pegasus/Common/CIMStatusCode.h> | #include <Pegasus/Common/CIMStatusCode.h> |
#include <Pegasus/Common/AutoPtr.h> | #include <Pegasus/Common/AutoPtr.h> |
|
|
// ATTN: TODOs - | // ATTN: TODOs - |
// optimize | // optimize |
// documentation | // documentation |
// trace? but this could be used by provider |
|
| |
PEGASUS_NAMESPACE_BEGIN | PEGASUS_NAMESPACE_BEGIN |
| |
|
|
{ | { |
CIMName name; // property name | CIMName name; // property name |
CIMName scope; // class the property is on | CIMName scope; // class the property is on |
Boolean wildcard; // true if this property is a wildcard |
Boolean wildcard; // true if this property is wildcarded |
|
Boolean endpoint; // true if this property is an endpoint |
|
// of a chained identifier |
AutoPtr<PropertyNode> sibling; | AutoPtr<PropertyNode> sibling; |
AutoPtr<PropertyNode> firstChild; | AutoPtr<PropertyNode> firstChild; |
| |
|
|
_hasWhereClause(false), | _hasWhereClause(false), |
_contextApplied(false) | _contextApplied(false) |
{ | { |
|
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep()"); |
} | } |
| |
CQLSelectStatementRep::CQLSelectStatementRep(String& inQlang, | CQLSelectStatementRep::CQLSelectStatementRep(String& inQlang, |
|
|
_hasWhereClause(false), | _hasWhereClause(false), |
_contextApplied(false) | _contextApplied(false) |
{ | { |
|
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep(inQlang,inQuery,inCtx)"); |
} | } |
| |
CQLSelectStatementRep::CQLSelectStatementRep(String& inQlang, | CQLSelectStatementRep::CQLSelectStatementRep(String& inQlang, |
|
|
_hasWhereClause(false), | _hasWhereClause(false), |
_contextApplied(false) | _contextApplied(false) |
{ | { |
|
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep(inQlang,inQuery)"); |
} | } |
| |
CQLSelectStatementRep::CQLSelectStatementRep(const CQLSelectStatementRep& rep) | CQLSelectStatementRep::CQLSelectStatementRep(const CQLSelectStatementRep& rep) |
|
|
_predicate(rep._predicate), | _predicate(rep._predicate), |
_contextApplied(rep._contextApplied) | _contextApplied(rep._contextApplied) |
{ | { |
|
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep(rep)"); |
} | } |
| |
CQLSelectStatementRep::~CQLSelectStatementRep() | CQLSelectStatementRep::~CQLSelectStatementRep() |
{ | { |
|
PEG_METHOD_ENTER (TRC_CQL, "~CQLSelectStatementRep()"); |
} | } |
| |
CQLSelectStatementRep& CQLSelectStatementRep::operator=(const CQLSelectStatementRep& rhs) | CQLSelectStatementRep& CQLSelectStatementRep::operator=(const CQLSelectStatementRep& rhs) |
{ | { |
|
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::operator="); |
|
|
if (this == &rhs) | if (this == &rhs) |
|
{ |
|
PEG_METHOD_EXIT(); |
return *this; | return *this; |
|
} |
| |
SelectStatementRep::operator=(rhs); | SelectStatementRep::operator=(rhs); |
| |
|
|
_contextApplied = rhs._contextApplied; | _contextApplied = rhs._contextApplied; |
_hasWhereClause = rhs._hasWhereClause; | _hasWhereClause = rhs._hasWhereClause; |
| |
|
PEG_METHOD_EXIT(); |
return *this; | return *this; |
} | } |
| |
void CQLSelectStatementRep::setQueryContext(QueryContext& inCtx) |
Boolean CQLSelectStatementRep::evaluate(const CIMInstance& inCI) |
{ | { |
SelectStatementRep::setQueryContext(inCtx); |
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::evaluate"); |
} |
|
| |
Boolean CQLSelectStatementRep::evaluate(const CIMInstance& inCI) |
if(_ctx == NULL) |
{ | { |
if(_ctx == NULL){ |
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"QC not set"); |
|
PEG_METHOD_EXIT(); |
MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL", |
"Trying to process a query with a NULL Query Context."); | "Trying to process a query with a NULL Query Context."); |
throw CQLRuntimeException(parms); | throw CQLRuntimeException(parms); |
} | } |
|
|
if (!hasWhereClause()) | if (!hasWhereClause()) |
{ | { |
|
PEG_METHOD_EXIT(); |
return true; | return true; |
} | } |
else | else |
|
|
| |
try | try |
{ | { |
|
PEG_METHOD_EXIT(); |
return _predicate.evaluate(inCI, *_ctx); | return _predicate.evaluate(inCI, *_ctx); |
} | } |
catch (CQLNullContagionException& ) | catch (CQLNullContagionException& ) |
{ | { |
// The null contagion rule. | // The null contagion rule. |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"null contagion"); |
|
PEG_METHOD_EXIT(); |
return false; | return false; |
} | } |
} | } |
|
|
|
PEGASUS_ASSERT(false); |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"should not get here in evaluate"); |
|
return true; //should never get here |
} | } |
| |
void CQLSelectStatementRep::applyProjection(CIMInstance& inCI) throw(Exception) | void CQLSelectStatementRep::applyProjection(CIMInstance& inCI) throw(Exception) |
{ | { |
if(_ctx == NULL){ |
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::applyProjection(inCI)"); |
|
|
|
if(_ctx == NULL) |
|
{ |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"QC not set"); |
|
PEG_METHOD_EXIT(); |
MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL", |
"Trying to process a query with a NULL Query Context."); | "Trying to process a query with a NULL Query Context."); |
throw CQLRuntimeException(parms); | throw CQLRuntimeException(parms); |
|
|
// Build the tree below the root. | // Build the tree below the root. |
for (Uint32 i = 0; i < _selectIdentifiers.size(); i++) | for (Uint32 i = 0; i < _selectIdentifiers.size(); i++) |
{ | { |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"select chained id = " + |
|
_selectIdentifiers[i].toString()); |
|
|
// Get the chain elements | // Get the chain elements |
Array<CQLIdentifier> ids = _selectIdentifiers[i].getSubIdentifiers(); | Array<CQLIdentifier> ids = _selectIdentifiers[i].getSubIdentifiers(); |
| |
|
|
// ie. it will become a child node of the current node. | // ie. it will become a child node of the current node. |
for (Uint32 j = 1; j < ids.size(); j++) | for (Uint32 j = 1; j < ids.size(); j++) |
{ | { |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"curNode = " + curNode->name.getString()); |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"id = " + ids[j].toString()); |
|
|
// If the child is wildcarded, then every property exposed by the | // If the child is wildcarded, then every property exposed by the |
// class of the instance at the current node is required. | // class of the instance at the current node is required. |
// Mark the current node as wildcarded. | // Mark the current node as wildcarded. |
if (ids[j].isWildcard()) | if (ids[j].isWildcard()) |
{ | { |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"id is wildcard"); |
curNode->wildcard = true; | curNode->wildcard = true; |
break; | break; |
} | } |
|
|
scope = ids[j].getScope(); | scope = ids[j].getScope(); |
} | } |
| |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"scope to compare = " + scope); |
|
|
if (curChild->name == ids[j].getName() && | if (curChild->name == ids[j].getName() && |
String::equalNoCase(curChild->scope.getString(), scope)) | String::equalNoCase(curChild->scope.getString(), scope)) |
{ | { |
// Name and scope match. The identifier already has a child node. |
// Name and scope match. The identifier is already child node. |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"id is already a child node"); |
found = true; | found = true; |
} | } |
else | else |
|
|
| |
if (!found) | if (!found) |
{ | { |
// The identifier doesn't already have a child node. |
// The identifier is not already a child node. |
// Create a node and add it as a child to the current node. | // Create a node and add it as a child to the current node. |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"new child" + |
|
ids[j].getName().getString()); |
curChild = new PropertyNode; | curChild = new PropertyNode; |
curChild->sibling = curNode->firstChild; | curChild->sibling = curNode->firstChild; |
curChild->name = ids[j].getName(); | curChild->name = ids[j].getName(); |
curChild->wildcard = false; | curChild->wildcard = false; |
|
curChild->endpoint = false; |
curNode->firstChild.reset(curChild); // safer than using the = operator | curNode->firstChild.reset(curChild); // safer than using the = operator |
} | } |
| |
|
|
{ | { |
// Child node has a scoping class | // Child node has a scoping class |
PEGASUS_ASSERT(ids[j].getScope().size() > 0); | PEGASUS_ASSERT(ids[j].getScope().size() > 0); |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"child set with scoping class: " + |
|
ids[j].getScope()); |
curChild->scope = CIMName(ids[j].getScope()); | curChild->scope = CIMName(ids[j].getScope()); |
} | } |
else | else |
|
|
// Not scoped. The scope is the FROM class. | // Not scoped. The scope is the FROM class. |
PEGASUS_ASSERT(j == 1); | PEGASUS_ASSERT(j == 1); |
PEGASUS_ASSERT(fromList[0].getName().getString().size() > 0); | PEGASUS_ASSERT(fromList[0].getName().getString().size() > 0); |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"child set with scoping class: " + |
|
fromList[0].getName().getString()); |
curChild->scope = fromList[0].getName(); | curChild->scope = fromList[0].getName(); |
} | } |
| |
|
// If the identifier is the last element of the chain, |
|
// then mark it as an endpoint |
|
if ((ids.size() - 1) == j) |
|
{ |
|
curChild->endpoint = true; |
|
} |
|
|
curNode = curChild; | curNode = curChild; |
curChild = curNode->firstChild.get(); | curChild = curNode->firstChild.get(); |
} | } |
|
|
PropertyNode* childNode = rootNode->firstChild.get(); | PropertyNode* childNode = rootNode->firstChild.get(); |
while (childNode != NULL) | while (childNode != NULL) |
{ | { |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"project childNode = " + childNode->name.getString()); |
|
|
// Determine if the instance passed in meets the class scoping | // Determine if the instance passed in meets the class scoping |
// rules for the current child node. | // rules for the current child node. |
Boolean filterable = isFilterable(inCI, childNode); | Boolean filterable = isFilterable(inCI, childNode); |
| |
|
// Indicates if the child node is still required after the recursive call. |
|
Boolean childRequired = true; |
|
|
// If the instance is filterable, and the child node has children, | // If the instance is filterable, and the child node has children, |
// or is wildcarded, then the child is assumed to be an embedded instance, | // 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. | // and we need to recurse to apply the projection on the embedded instance. |
|
|
// remove the embedded instance property from the instance passed in, | // remove the embedded instance property from the instance passed in, |
// project on that embedded instance property, and then add the projected | // project on that embedded instance property, and then add the projected |
// embedded instance property back to the instance passed in. | // embedded instance property back to the instance passed in. |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"about to recurse: " + childNode->name.getString()); |
Uint32 index = inCI.findProperty(childNode->name); | Uint32 index = inCI.findProperty(childNode->name); |
if (index != PEG_NOT_FOUND) | if (index != PEG_NOT_FOUND) |
{ | { |
// The embedded instance has the required embedded instance property. |
// The instance passed in has the required embedded instance property. |
|
// Note: embedded instance property missing is caught below. |
|
|
|
// Remove the embedded instance property |
CIMProperty childProp = inCI.getProperty(index); | CIMProperty childProp = inCI.getProperty(index); |
inCI.removeProperty(index); | inCI.removeProperty(index); |
applyProjection(childNode, childProp); |
|
|
// 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. |
|
childRequired = applyProjection(childNode, childProp, allPropsRequired); |
inCI.addProperty(childProp); | inCI.addProperty(childProp); |
} | } |
} | } |
| |
// If the node is not wildcarded, and the instance passed in | // If the node is not wildcarded, and the instance passed in |
// is filterable, then add the current child to the list | // is filterable, then add the current child to the list |
// of required properties on the instance passed in. |
// if it is still required. |
if (!allPropsRequired && filterable) |
if (!allPropsRequired && filterable && childRequired) |
{ | { |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"add req prop: " + childNode->name.getString()); |
requiredProps.append(childNode->name); | requiredProps.append(childNode->name); |
} | } |
| |
|
|
| |
// Remove the properties that are not in the projection. | // Remove the properties that are not in the projection. |
// This also checks for missing required properties. | // This also checks for missing required properties. |
removeUnneededProperties(inCI, |
Boolean preserve = false; |
|
filterInstance(inCI, |
allPropsRequired, | allPropsRequired, |
fromList[0].getName(), | fromList[0].getName(), |
requiredProps); |
requiredProps, |
|
preserve); |
} | } |
| |
void CQLSelectStatementRep::applyProjection(PropertyNode* node, |
Boolean CQLSelectStatementRep::applyProjection(PropertyNode* node, |
CIMProperty& nodeProp) |
CIMProperty& nodeProp, |
|
Boolean& preservePropsForParent) |
{ | { |
PEGASUS_ASSERT(node->firstChild.get() != NULL); |
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 | // The property passed in must be an embedded instance. It is not |
// allowed to project properties on embedded classes. | // allowed to project properties on embedded classes. |
// |
|
// Get the embedded instance from the property. | // Get the embedded instance from the property. |
// | // |
| |
|
// First check that it is an embedded object |
CIMValue nodeVal = nodeProp.getValue(); | CIMValue nodeVal = nodeProp.getValue(); |
// ATTN - UNCOMMENT when emb objs are supported |
|
/* |
|
if (nodeVal.getType() != CIMTYPE_OBJECT) | if (nodeVal.getType() != CIMTYPE_OBJECT) |
{ | { |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"not emb"); |
|
PEG_METHOD_EXIT(); |
MessageLoaderParms parms("CQL.CQLSelectStatementRep.PROP_NOT_EMB", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.PROP_NOT_EMB", |
"The property $0 must contain an embedded object.", | "The property $0 must contain an embedded object.", |
nodeProp.getName().getString()); | nodeProp.getName().getString()); |
throw CQLRuntimeException(parms); | 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() && | if (nodeVal.isArray() && |
(node->firstChild.get() != NULL || node->wildcard)) | (node->firstChild.get() != NULL || node->wildcard)) |
|
|
// an embedded object with properties or wildcard. | // an embedded object with properties or wildcard. |
// Examples not allowed: SELECT fromClass.someArrayProp.scope::notAllowedProp FROM fromClass | // Examples not allowed: SELECT fromClass.someArrayProp.scope::notAllowedProp FROM fromClass |
// SELECT fromClass.someArrayProp.* 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", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.PROJ_WHOLE_ARRAY", |
"CQL requires that array indexing is used on embedded object property $0.", | "CQL requires that array indexing is used on embedded object property $0.", |
nodeProp.getName().getString()); | nodeProp.getName().getString()); |
throw CQLRuntimeException(parms); | throw CQLRuntimeException(parms); |
} | } |
| |
CIMObject nodeObj; |
CIMObject nodeObj; // this starts uninitialized |
// ATTN - UNCOMMENT when emb objs are supported |
nodeVal.get(nodeObj); |
// 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()) | if (!nodeObj.isInstance()) |
{ | { |
// Not allowed to project on a Class | // 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", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.PROJ_CLASS", |
"CQL does not allow properties to be projected on class $0.", | "CQL does not allow properties to be projected on class $0.", |
nodeProp.getName().getString()); | nodeProp.getName().getString()); |
|
|
PropertyNode * curChild = node->firstChild.get(); | PropertyNode * curChild = node->firstChild.get(); |
while (curChild != NULL) | while (curChild != NULL) |
{ | { |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"project childNode = " + curChild->name.getString()); |
|
|
// Determine if the embedded instance meets the class scoping | // Determine if the embedded instance meets the class scoping |
// rules for the current child node | // rules for the current child node |
Boolean filterable = isFilterable(nodeInst, curChild); | 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, | // 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, | // 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. | // and we need to recurse to apply the projection on the embedded instance. |
|
|
// remove the embedded instance property from the current instance, | // remove the embedded instance property from the current instance, |
// project on that embedded instance property, and then add the projected | // project on that embedded instance property, and then add the projected |
// embedded instance property back to the current instance. | // 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); | Uint32 index = nodeInst.findProperty(curChild->name); |
if (index != PEG_NOT_FOUND) | if (index != PEG_NOT_FOUND) |
{ | { |
// The embedded instance has the required embedded instance property. |
// 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); | CIMProperty childProp = nodeInst.getProperty(index); |
nodeInst.removeProperty(index); | nodeInst.removeProperty(index); |
applyProjection(curChild, childProp); |
|
|
// 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); |
nodeInst.addProperty(childProp); | nodeInst.addProperty(childProp); |
} | } |
} | } |
| |
// If the node is not wildcarded, and the embedded instance | // If the node is not wildcarded, and the embedded instance |
// is filterable, then add the current child to the list | // is filterable, then add the current child to the list |
// of required properties on the embedded instance. |
// if it is still required. |
if (!allPropsRequired && filterable) |
if (!allPropsRequired && filterable && childRequired) |
{ | { |
// The instance is filterable, add the property to the required list. | // The instance is filterable, add the property to the required list. |
requiredProps.append(node->name); |
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"add req prop: " + curChild->name.getString()); |
|
requiredProps.append(curChild->name); |
} | } |
| |
curChild = curChild->sibling.get(); | curChild = curChild->sibling.get(); |
} | } |
| |
// Remove the properties that are not in the projection. |
// Filter the instance. |
// This also checks for missing required properties. |
// This removes unneeded properties, unless this |
removeUnneededProperties(nodeInst, |
// 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, | allPropsRequired, |
nodeInst.getClassName(), | nodeInst.getClassName(), |
requiredProps); |
requiredProps, |
|
preserveProps); |
| |
// Put the projected instance back into the property. | // Put the projected instance back into the property. |
// ATTN - UNCOMMENT when emb objs are supported |
CIMObject newNodeObj(nodeInst); |
//CIMValue newNodeVal(nodeInst); |
CIMValue newNodeVal(newNodeObj); |
//nodeProp.setValue(newNodeVal); |
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, | Boolean CQLSelectStatementRep::isFilterable(const CIMInstance& inst, |
PropertyNode* node) | 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 | // 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 | // type is the scoping class or a subclass of the scoping class where the |
|
|
if (inst.getClassName() == node->scope) | if (inst.getClassName() == node->scope) |
{ | { |
// The instance's class is the same as the required scope | // The instance's class is the same as the required scope |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"instance matches scope"); |
filterable = true; | filterable = true; |
} | } |
else | else |
|
|
if (_ctx->isSubClass(node->scope, inst.getClassName())) | if (_ctx->isSubClass(node->scope, inst.getClassName())) |
{ | { |
// The instance's class is a subclass of the required scope. | // 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; | filterable = true; |
} | } |
} | } |
|
|
// Just swallow this error because according to the | // Just swallow this error because according to the |
// spec we should be putting NULL in the result column, | // spec we should be putting NULL in the result column, |
// which means skipping the property on the instance. | // 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 ce; |
} | } |
} | } |
} | } |
| |
|
PEG_METHOD_EXIT(); |
return filterable; | return filterable; |
} | } |
| |
void CQLSelectStatementRep::removeUnneededProperties(CIMInstance& inst, |
void CQLSelectStatementRep::filterInstance(CIMInstance& inst, |
Boolean& allPropsRequired, | Boolean& allPropsRequired, |
const CIMName& allPropsClass, | const CIMName& allPropsClass, |
Array<CIMName>& requiredProps) |
Array<CIMName>& requiredProps, |
|
Boolean& preserveProps) |
{ | { |
|
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::removeUnneededProperties"); |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"instance = " + inst.getClassName().getString()); |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"allPropsClass = " + allPropsClass.getString()); |
|
|
// Implementation note: | // Implementation note: |
// Scoping operator before a wildcard is not allowed: | // Scoping operator before a wildcard is not allowed: |
// Example: | // Example: |
|
|
// This is either the FROM class or the class of an embedded instance. | // This is either the FROM class or the class of an embedded instance. |
if (allPropsRequired) | if (allPropsRequired) |
{ | { |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"all props required"); |
requiredProps.clear(); | requiredProps.clear(); |
CIMClass cls = _ctx->getClass(allPropsClass); | CIMClass cls = _ctx->getClass(allPropsClass); |
Array<CIMName> clsProps; | Array<CIMName> clsProps; |
|
|
{ | { |
if (!containsProperty(requiredProps[i], supportedProps)) | 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", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.PROJ_MISSING_PROP", |
"The property $0 is missing on the instance of class $1.", | "The property $0 is missing on the instance of class $1.", |
requiredProps[i].getString(), inst.getClassName().getString()); | requiredProps[i].getString(), inst.getClassName().getString()); |
|
|
} | } |
} | } |
| |
// Remove the properties on the instance that are not required. |
// If requested, remove the properties on the instance that are not required. |
|
if (!preserveProps) |
|
{ |
for (Uint32 i = 0; i < supportedProps.size(); i++) | for (Uint32 i = 0; i < supportedProps.size(); i++) |
{ | { |
if (!containsProperty(supportedProps[i], requiredProps)) | if (!containsProperty(supportedProps[i], requiredProps)) |
{ | { |
Uint32 index = inst.findProperty(supportedProps[i]); | Uint32 index = inst.findProperty(supportedProps[i]); |
PEGASUS_ASSERT(index != PEG_NOT_FOUND); | PEGASUS_ASSERT(index != PEG_NOT_FOUND); |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"removing:" + supportedProps[i].getString()); |
inst.removeProperty(index); | inst.removeProperty(index); |
} | } |
} | } |
} | } |
| |
|
PEG_METHOD_EXIT(); |
|
} |
|
|
// | // |
// Validates that all the chained identifiers in the statement meet | // Validates that all the chained identifiers in the statement meet |
// the rules in the CQL spec vs.the class definitions in the repository | // the rules in the CQL spec vs.the class definitions in the repository |
// | // |
void CQLSelectStatementRep::validate() throw(Exception) | void CQLSelectStatementRep::validate() throw(Exception) |
{ | { |
if(_ctx == NULL){ |
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", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL", |
"Trying to process a query with a NULL Query Context."); | "Trying to process a query with a NULL Query Context."); |
throw CQLValidationException(parms); | throw CQLValidationException(parms); |
|
|
{ | { |
validateProperty(_whereIdentifiers[i]); | validateProperty(_whereIdentifiers[i]); |
} | } |
|
|
|
PEG_METHOD_EXIT(); |
} | } |
| |
// | // |
|
|
// | // |
void CQLSelectStatementRep::validateProperty(QueryChainedIdentifier& chainId) | void CQLSelectStatementRep::validateProperty(QueryChainedIdentifier& chainId) |
{ | { |
|
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::validateProperty"); |
|
|
// Note: applyContext has been called beforehand | // Note: applyContext has been called beforehand |
| |
Array<QueryIdentifier> ids = chainId.getSubIdentifiers(); | Array<QueryIdentifier> ids = chainId.getSubIdentifiers(); |
|
|
curContext = ids[0].getName(); | curContext = ids[0].getName(); |
} | } |
| |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"current context: " + |
|
curContext.getString()); |
|
|
// Get the class definition of the current class context | // Get the class definition of the current class context |
|
// Note: keep this code here so that class existence is always |
|
// checked. Eg. SELECT * FROM fromClass |
CIMClass classDef; | CIMClass classDef; |
try | try |
{ | { |
|
|
} | } |
catch (CIMException& ce) | catch (CIMException& ce) |
{ | { |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"repository error"); |
|
PEG_METHOD_EXIT(); |
if (ce.getCode() == CIM_ERR_NOT_FOUND || | if (ce.getCode() == CIM_ERR_NOT_FOUND || |
ce.getCode() == CIM_ERR_INVALID_CLASS) | ce.getCode() == CIM_ERR_INVALID_CLASS) |
{ | { |
|
|
curContext.getString()); | curContext.getString()); |
throw CQLValidationException(parms); | throw CQLValidationException(parms); |
} | } |
|
else |
|
{ |
|
throw ce; |
|
} |
} | } |
| |
// Now do the checks for properties existing on the current class context | // Now do the checks for properties existing on the current class context |
|
|
Uint32 propertyIndex = classDef.findProperty(ids[pos].getName()); | Uint32 propertyIndex = classDef.findProperty(ids[pos].getName()); |
if (propertyIndex == PEG_NOT_FOUND) | if (propertyIndex == PEG_NOT_FOUND) |
{ | { |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"prop not on context " + |
|
ids[pos].getName().getString()); |
|
PEG_METHOD_EXIT(); |
MessageLoaderParms parms("CQL.CQLSelectStatementRep.VAL_PROP_NOT_ON_CLASS", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.VAL_PROP_NOT_ON_CLASS", |
"The property $0 does not exist on class $1.", | "The property $0 does not exist on class $1.", |
ids[pos].getName().getString(), classDef.getClassName().getString()); | ids[pos].getName().getString(), classDef.getClassName().getString()); |
|
|
// Check the class relationship between the scoping class and the FROM class. | // Check the class relationship between the scoping class and the FROM class. |
if (_ctx->getClassRelation(ids[0].getName(), curContext) == QueryContext::NOTRELATED) | if (_ctx->getClassRelation(ids[0].getName(), curContext) == QueryContext::NOTRELATED) |
{ | { |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"scope violation for:"+ |
|
ids[0].getName().getString()); |
|
PEG_METHOD_EXIT(); |
MessageLoaderParms parms("CQL.CQLSelectStatementRep.VAL_SCOPE_VIOLATION", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.VAL_SCOPE_VIOLATION", |
"The class $0 is not a superclass, subclass, or the same class as $1.", | "The class $0 is not a superclass, subclass, or the same class as $1.", |
curContext.getString(), ids[0].getName().getString()); | curContext.getString(), ids[0].getName().getString()); |
|
|
CIMName qual("EmbeddedObject"); | CIMName qual("EmbeddedObject"); |
if (embObj.findQualifier(qual) == PEG_NOT_FOUND) | if (embObj.findQualifier(qual) == PEG_NOT_FOUND) |
{ | { |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"prop not emb " + |
|
embObj.getName().getString()); |
|
PEG_METHOD_EXIT(); |
MessageLoaderParms parms("CQL.CQLSelectStatementRep.PROP_NOT_EMB", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.PROP_NOT_EMB", |
"The property $0 must be an embedded object.", | "The property $0 must be an embedded object.", |
embObj.getName().getString()); | embObj.getName().getString()); |
|
|
} | } |
} | } |
} | } |
|
|
|
PEG_METHOD_EXIT(); |
} | } |
| |
CIMName CQLSelectStatementRep::lookupFromClass(const String& lookup) | CIMName CQLSelectStatementRep::lookupFromClass(const String& lookup) |
{ | { |
|
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::lookupFromClass"); |
|
|
QueryIdentifier id = _ctx->findClass(lookup); | QueryIdentifier id = _ctx->findClass(lookup); |
| |
|
PEG_METHOD_EXIT(); |
|
|
return id.getName(); | return id.getName(); |
} | } |
| |
Array<CIMObjectPath> CQLSelectStatementRep::getClassPathList() | Array<CIMObjectPath> CQLSelectStatementRep::getClassPathList() |
{ | { |
|
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::getClassPathList"); |
|
|
if(_ctx == NULL){ | if(_ctx == NULL){ |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"null QC"); |
|
PEG_METHOD_EXIT(); |
MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL", |
"Trying to process a query with a NULL Query Context."); | "Trying to process a query with a NULL Query Context."); |
throw CQLRuntimeException(parms); | throw CQLRuntimeException(parms); |
|
|
Array<CIMObjectPath> paths; | Array<CIMObjectPath> paths; |
paths.append(path); | paths.append(path); |
| |
|
PEG_METHOD_EXIT(); |
|
|
return paths; | return paths; |
|
|
} | } |
| |
CIMPropertyList CQLSelectStatementRep::getPropertyList(const CIMObjectPath& inClassName) | CIMPropertyList CQLSelectStatementRep::getPropertyList(const CIMObjectPath& inClassName) |
{ | { |
|
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::getPropertyList"); |
return getPropertyListInternal(inClassName, true, true); | return getPropertyListInternal(inClassName, true, true); |
} | } |
| |
CIMPropertyList CQLSelectStatementRep::getSelectPropertyList(const CIMObjectPath& inClassName) | CIMPropertyList CQLSelectStatementRep::getSelectPropertyList(const CIMObjectPath& inClassName) |
{ | { |
|
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::getSelectPropertyList"); |
return getPropertyListInternal(inClassName, true, false); | return getPropertyListInternal(inClassName, true, false); |
} | } |
| |
CIMPropertyList CQLSelectStatementRep::getWherePropertyList(const CIMObjectPath& inClassName) | CIMPropertyList CQLSelectStatementRep::getWherePropertyList(const CIMObjectPath& inClassName) |
{ | { |
|
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::getWherePropertyList"); |
return getPropertyListInternal(inClassName, false, true); | return getPropertyListInternal(inClassName, false, true); |
} | } |
| |
|
|
Boolean includeSelect, | Boolean includeSelect, |
Boolean includeWhere) | Boolean includeWhere) |
{ | { |
if(_ctx == NULL){ |
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::getPropertyListInternal"); |
|
|
|
if(_ctx == NULL) |
|
{ |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"null QC"); |
|
PEG_METHOD_EXIT(); |
MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL", |
"Trying to process a query with a NULL Query Context."); | "Trying to process a query with a NULL Query Context."); |
throw CQLRuntimeException(parms); | throw CQLRuntimeException(parms); |
|
|
if (!_contextApplied) | if (!_contextApplied) |
applyContext(); | applyContext(); |
| |
// Get the classname. Note: since wbem-uri is not supported yet, |
// Get the FROM class. |
|
CIMName fromClass = _ctx->getFromList()[0].getName(); |
|
|
|
// Get the classname passed in. Note: since wbem-uri is not supported yet, |
// only use the classname part of the path. | // only use the classname part of the path. |
CIMName className = inClassName.getClassName(); | CIMName className = inClassName.getClassName(); |
if (className.isNull()) | if (className.isNull()) |
{ | { |
// If the caller passed in an empty className, then the | // If the caller passed in an empty className, then the |
// FROM class is to be used. | // FROM class is to be used. |
className = _ctx->getFromList()[0].getName(); |
className = fromClass; |
|
} |
|
else |
|
{ |
|
// The caller passed in some class name. Verify that it is the FROM |
|
// class or a subclass of the FROM class. |
|
if(!(className == fromClass)) |
|
{ |
|
// Check if subclass of the FROM class |
|
if(!_ctx->isSubClass(fromClass, className)) |
|
{ |
|
MessageLoaderParms parms("CQL.CQLSelectStatementRep.CLASS_NOT_FROM_LIST_CLASS", |
|
"Class $0 does not match the FROM class or any of its subclasses.", |
|
className.getString()); |
|
throw QueryException(parms); |
|
} |
|
} |
} | } |
| |
Boolean isWildcard; | Boolean isWildcard; |
|
|
if (allProps) | if (allProps) |
{ | { |
// Return null property list to indicate all properties are required. | // Return null property list to indicate all properties are required. |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"all props req"); |
|
PEG_METHOD_EXIT(); |
return CIMPropertyList(); | return CIMPropertyList(); |
} | } |
else | else |
|
|
// Return the required property list. Note that it is possible to return | // Return the required property list. Note that it is possible to return |
// an empty list in the case of no required properties for the classname | // an empty list in the case of no required properties for the classname |
// passed in. This can happen when the scoping operator is used. | // passed in. This can happen when the scoping operator is used. |
|
PEG_METHOD_EXIT(); |
return CIMPropertyList(reqProps); | return CIMPropertyList(reqProps); |
} | } |
} | } |
|
|
Array<CIMName>& matchedScopes, | Array<CIMName>& matchedScopes, |
Array<CIMName>& unmatchedScopes) | Array<CIMName>& unmatchedScopes) |
{ | { |
|
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::addRequiredProperty"); |
|
|
// | // |
// Implementation notes: | // Implementation notes: |
// This function does not look for required properties on embedded objects. | // This function does not look for required properties on embedded objects. |
|
|
if (ids.size() == 1) | if (ids.size() == 1) |
{ | { |
// This identifier is not a property name | // This identifier is not a property name |
|
PEG_METHOD_EXIT(); |
return false; | return false; |
} | } |
| |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"id[1] = " + ids[1].toString()); |
|
|
if (ids[1].isSymbolicConstant()) | if (ids[1].isSymbolicConstant()) |
{ | { |
// Non-embedded symbolic constants are not properties | // Non-embedded symbolic constants are not properties |
|
|
// implies that embobj is a required property, because | // implies that embobj is a required property, because |
// embobj could be null, and that affects how the | // embobj could be null, and that affects how the |
// identifier is evaluated. | // identifier is evaluated. |
|
PEG_METHOD_EXIT(); |
return false; | return false; |
} | } |
| |
|
|
} | } |
else | else |
{ | { |
// The scoping class is not the same as the class passed. |
// The scoping class is not the same as the class passed in. |
// Check if we already know that the scoping class is a subclass | // Check if we already know that the scoping class is a subclass |
// of the class passed in | // of the class passed in |
if (containsProperty(scopingClass, unmatchedScopes)) | if (containsProperty(scopingClass, unmatchedScopes)) |
{ | { |
// Scoping class is a subclass. | // Scoping class is a subclass. |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"scoping class is a subclass"); |
|
PEG_METHOD_EXIT(); |
return false; | return false; |
} | } |
| |
|
|
// Check if the scoping class is a superclass of the class passed in | // Check if the scoping class is a superclass of the class passed in |
if (isSuper || _ctx->isSubClass(scopingClass, className)) | if (isSuper || _ctx->isSubClass(scopingClass, className)) |
{ | { |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"scoping class is a superclass"); |
|
|
// Scoping class is a superclass of the class passed in. | // Scoping class is a superclass of the class passed in. |
if (!isSuper) | if (!isSuper) |
{ | { |
|
|
} | } |
else | else |
{ | { |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"scoping class is NOT a superclass"); |
|
|
// Scoping class is not superclass of class passed in. | // Scoping class is not superclass of class passed in. |
// Save this information. | // Save this information. |
unmatchedScopes.append(scopingClass); | unmatchedScopes.append(scopingClass); |
|
|
CIMName fromClassName = _ctx->getFromList()[0].getName(); | CIMName fromClassName = _ctx->getFromList()[0].getName(); |
if (fromClassName == className) | if (fromClassName == className) |
{ | { |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"wildcard and = FROM"); |
|
PEG_METHOD_EXIT(); |
return true; | return true; |
} | } |
| |
|
|
} | } |
} | } |
| |
|
PEG_METHOD_EXIT(); |
return false; | return false; |
} | } |
| |
|
|
} | } |
| |
// Indicate the required property is not a wildcard | // Indicate the required property is not a wildcard |
|
PEG_METHOD_EXIT(); |
return false; | return false; |
} | } |
| |
Array<CQLChainedIdentifier> CQLSelectStatementRep::getSelectChainedIdentifiers() | Array<CQLChainedIdentifier> CQLSelectStatementRep::getSelectChainedIdentifiers() |
{ | { |
|
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::getSelectChainedIdentifiers"); |
|
|
if (!_contextApplied) | if (!_contextApplied) |
applyContext(); | applyContext(); |
| |
|
PEG_METHOD_EXIT(); |
|
|
return _selectIdentifiers; | return _selectIdentifiers; |
} | } |
| |
Array<CQLChainedIdentifier> CQLSelectStatementRep::getWhereChainedIdentifiers() | Array<CQLChainedIdentifier> CQLSelectStatementRep::getWhereChainedIdentifiers() |
{ | { |
if(_ctx == NULL){ |
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::getWhereChainedIdentifiers"); |
|
|
|
if(_ctx == NULL) |
|
{ |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"null QC"); |
|
PEG_METHOD_EXIT(); |
MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL", |
"Trying to process a query with a NULL Query Context."); | "Trying to process a query with a NULL Query Context."); |
throw CQLRuntimeException(parms); | throw CQLRuntimeException(parms); |
|
|
cqlChainIds.append(cqlChainId); | cqlChainIds.append(cqlChainId); |
} | } |
| |
|
PEG_METHOD_EXIT(); |
|
|
return cqlChainIds; | return cqlChainIds; |
} | } |
| |
Boolean CQLSelectStatementRep::containsProperty(const CIMName& name, | Boolean CQLSelectStatementRep::containsProperty(const CIMName& name, |
const Array<CIMName>& props) | const Array<CIMName>& props) |
{ | { |
|
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::containsProperty"); |
|
|
for (Uint32 i = 0; i < props.size(); i++) | for (Uint32 i = 0; i < props.size(); i++) |
{ | { |
if (props[i] == name) | if (props[i] == name) |
{ | { |
|
PEG_METHOD_EXIT(); |
return true; | return true; |
} | } |
} | } |
| |
|
PEG_METHOD_EXIT(); |
return false; | return false; |
} | } |
| |
void CQLSelectStatementRep::appendClassPath(const CQLIdentifier& inIdentifier) | void CQLSelectStatementRep::appendClassPath(const CQLIdentifier& inIdentifier) |
{ | { |
if(_ctx == NULL){ |
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::appendClassPath"); |
|
|
|
if(_ctx == NULL) |
|
{ |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"null QC"); |
|
PEG_METHOD_EXIT(); |
MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL", |
"Trying to process a query with a NULL Query Context."); | "Trying to process a query with a NULL Query Context."); |
throw CQLValidationException(parms); | throw CQLValidationException(parms); |
} | } |
_ctx->insertClassPath(inIdentifier); | _ctx->insertClassPath(inIdentifier); |
|
|
|
PEG_METHOD_EXIT(); |
} | } |
| |
void CQLSelectStatementRep::setPredicate(const CQLPredicate& inPredicate) | void CQLSelectStatementRep::setPredicate(const CQLPredicate& inPredicate) |
{ | { |
|
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::setPredicate"); |
_predicate = inPredicate; | _predicate = inPredicate; |
|
PEG_METHOD_EXIT(); |
} | } |
| |
CQLPredicate CQLSelectStatementRep::getPredicate() const | CQLPredicate CQLSelectStatementRep::getPredicate() const |
{ | { |
|
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::getPredicate"); |
return _predicate; | return _predicate; |
} | } |
| |
void CQLSelectStatementRep::insertClassPathAlias(const CQLIdentifier& inIdentifier, | void CQLSelectStatementRep::insertClassPathAlias(const CQLIdentifier& inIdentifier, |
String inAlias) | String inAlias) |
{ | { |
if(_ctx == NULL){ |
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::insertClassPathAlias"); |
|
|
|
if(_ctx == NULL) |
|
{ |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"null QC"); |
|
PEG_METHOD_EXIT(); |
MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL", |
"Trying to process a query with a NULL Query Context."); | "Trying to process a query with a NULL Query Context."); |
throw CQLValidationException(parms); | throw CQLValidationException(parms); |
} | } |
_ctx->insertClassPath(inIdentifier,inAlias); | _ctx->insertClassPath(inIdentifier,inAlias); |
|
|
|
PEG_METHOD_EXIT(); |
} | } |
| |
void CQLSelectStatementRep::appendSelectIdentifier(const CQLChainedIdentifier& x) | void CQLSelectStatementRep::appendSelectIdentifier(const CQLChainedIdentifier& x) |
{ | { |
|
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::appendSelectIdentifier"); |
_selectIdentifiers.append(x); | _selectIdentifiers.append(x); |
|
PEG_METHOD_EXIT(); |
} | } |
| |
void CQLSelectStatementRep::applyContext() | void CQLSelectStatementRep::applyContext() |
{ | { |
if(_ctx == NULL){ |
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::applyContext"); |
|
|
|
if(_ctx == NULL) |
|
{ |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"null QC"); |
|
PEG_METHOD_EXIT(); |
MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL", |
"Trying to process a query with a NULL Query Context."); | "Trying to process a query with a NULL Query Context."); |
throw CQLRuntimeException(parms); | throw CQLRuntimeException(parms); |
|
|
} | } |
| |
_contextApplied = true; | _contextApplied = true; |
|
PEG_METHOD_EXIT(); |
} | } |
| |
void CQLSelectStatementRep::checkWellFormedIdentifier(const QueryChainedIdentifier& chainId, | void CQLSelectStatementRep::checkWellFormedIdentifier(const QueryChainedIdentifier& chainId, |
Boolean isSelectListId) | Boolean isSelectListId) |
{ | { |
|
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::checkWellFormedIdentifier"); |
|
|
// This function assumes that applyContext has been called. | // This function assumes that applyContext has been called. |
Array<QueryIdentifier> ids = chainId.getSubIdentifiers(); | Array<QueryIdentifier> ids = chainId.getSubIdentifiers(); |
| |
if (ids.size() == 0) | if (ids.size() == 0) |
{ | { |
|
PEG_METHOD_EXIT(); |
MessageLoaderParms parms("CQL.CQLSelectStatementRep.EMPTY_CHAIN", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.EMPTY_CHAIN", |
"An empty chained identifier was found."); | "An empty chained identifier was found."); |
throw CQLSyntaxErrorException(parms); | throw CQLSyntaxErrorException(parms); |
} | } |
| |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"chain =" + chainId.toString()); |
|
|
if (ids.size() == 1 && isSelectListId) | if (ids.size() == 1 && isSelectListId) |
{ | { |
// Single element chain ids are not allow in the select list. | // Single element chain ids are not allow in the select list. |
// The select list can only have properties. | // The select list can only have properties. |
|
PEG_METHOD_EXIT(); |
MessageLoaderParms parms("CQL.CQLSelectStatementRep.SINGLE_CHID_IN_SELECT", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.SINGLE_CHID_IN_SELECT", |
"A property on the FROM class must be selected."); | "A property on the FROM class must be selected."); |
throw CQLSyntaxErrorException(parms); | throw CQLSyntaxErrorException(parms); |
|
|
{ | { |
// The first identifier must be a classname (it could be the FROM class, or | // The first identifier must be a classname (it could be the FROM class, or |
// some other class for the right side of ISA) | // some other class for the right side of ISA) |
|
PEG_METHOD_EXIT(); |
MessageLoaderParms parms("CQL.CQLSelectStatementRep.FIRST_ID_ILLEGAL", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.FIRST_ID_ILLEGAL", |
"The chained identifier $0 is illegal.", | "The chained identifier $0 is illegal.", |
chainId.toString()); | chainId.toString()); |
|
|
{ | { |
if (ids[pos].isArray() && isSelectListId) | if (ids[pos].isArray() && isSelectListId) |
{ | { |
|
PEG_METHOD_EXIT(); |
MessageLoaderParms parms("CQL.CQLSelectStatementRep.ARRAY_IN_SELECT", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.ARRAY_IN_SELECT", |
"The identifier $0 of $1 in the SELECT list cannot use an array index.", | "The identifier $0 of $1 in the SELECT list cannot use an array index.", |
ids[pos].toString(), chainId.toString()); | ids[pos].toString(), chainId.toString()); |
|
|
| |
if (ids[pos].isSymbolicConstant() && isSelectListId) | if (ids[pos].isSymbolicConstant() && isSelectListId) |
{ | { |
|
PEG_METHOD_EXIT(); |
MessageLoaderParms parms("CQL.CQLSelectStatementRep.SYMCONST_IN_SELECT", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.SYMCONST_IN_SELECT", |
"The identifier $0 of $1 in the SELECT list cannot use a symbolic constant.", | "The identifier $0 of $1 in the SELECT list cannot use a symbolic constant.", |
ids[pos].toString(), chainId.toString()); | ids[pos].toString(), chainId.toString()); |
|
|
| |
if (ids[pos].isSymbolicConstant() && pos != (ids.size() -1)) | if (ids[pos].isSymbolicConstant() && pos != (ids.size() -1)) |
{ | { |
|
PEG_METHOD_EXIT(); |
MessageLoaderParms parms("CQL.CQLSelectStatementRep.SYMCONST_NOT_LAST", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.SYMCONST_NOT_LAST", |
"The symbolic constant identifier $0 of $1 must be the last element.", | "The symbolic constant identifier $0 of $1 must be the last element.", |
ids[pos].toString(), chainId.toString()); | ids[pos].toString(), chainId.toString()); |
|
|
{ | { |
if ( !isSelectListId) | if ( !isSelectListId) |
{ | { |
|
PEG_METHOD_EXIT(); |
MessageLoaderParms parms("CQL.CQLSelectStatementRep.WILD_IN_WHERE", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.WILD_IN_WHERE", |
"The identifier $0 of $1 in the WHERE list cannot use a wildcard.", | "The identifier $0 of $1 in the WHERE list cannot use a wildcard.", |
ids[pos].toString(), chainId.toString()); | ids[pos].toString(), chainId.toString()); |
|
|
| |
if ( pos != ids.size() - 1) | if ( pos != ids.size() - 1) |
{ | { |
|
PEG_METHOD_EXIT(); |
MessageLoaderParms parms("CQL.CQLSelectStatementRep.WILD_NOT_END", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.WILD_NOT_END", |
"The wildcard identifier $0 of $1 must be the last element.", | "The wildcard identifier $0 of $1 must be the last element.", |
ids[pos].toString(), chainId.toString()); | ids[pos].toString(), chainId.toString()); |
|
|
{ | { |
if (!ids[pos].isScoped()) | if (!ids[pos].isScoped()) |
{ | { |
|
PEG_METHOD_EXIT(); |
MessageLoaderParms parms("CQL.CQLSelectStatementRep.EMB_PROP_NOT_SCOPED", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.EMB_PROP_NOT_SCOPED", |
"The identifier $0 of $1 must use the scope operator.", | "The identifier $0 of $1 must use the scope operator.", |
ids[pos].toString(), chainId.toString()); | ids[pos].toString(), chainId.toString()); |
|
|
} | } |
} | } |
} | } |
|
|
|
PEG_METHOD_EXIT(); |
} | } |
| |
void CQLSelectStatementRep::normalizeToDOC() | void CQLSelectStatementRep::normalizeToDOC() |
{ | { |
|
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::normalizeToDOC"); |
|
|
if (!_contextApplied) | if (!_contextApplied) |
applyContext(); | applyContext(); |
| |
|
|
Cql2Dnf DNFer(_predicate); | Cql2Dnf DNFer(_predicate); |
_predicate = DNFer.getDnfPredicate(); | _predicate = DNFer.getDnfPredicate(); |
} | } |
|
|
|
PEG_METHOD_EXIT(); |
} | } |
| |
String CQLSelectStatementRep::toString() | String CQLSelectStatementRep::toString() |
{ | { |
if(_ctx == NULL){ |
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::toString"); |
|
|
|
if(_ctx == NULL) |
|
{ |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"null QC"); |
|
PEG_METHOD_EXIT(); |
MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL", |
"Trying to process a query with a NULL Query Context."); | "Trying to process a query with a NULL Query Context."); |
throw CQLRuntimeException(parms); | throw CQLRuntimeException(parms); |
|
|
| |
String s("SELECT "); | String s("SELECT "); |
for(Uint32 i = 0; i < _selectIdentifiers.size(); i++){ | for(Uint32 i = 0; i < _selectIdentifiers.size(); i++){ |
if((i > 0) && (i < _selectIdentifiers.size())){ |
if((i > 0) && (i < _selectIdentifiers.size())) |
|
{ |
s.append(","); | s.append(","); |
} | } |
s.append(_selectIdentifiers[i].toString()); | s.append(_selectIdentifiers[i].toString()); |
|
|
s.append(" WHERE "); | s.append(" WHERE "); |
s.append(_predicate.toString()); | s.append(_predicate.toString()); |
} | } |
|
|
|
PEG_METHOD_EXIT(); |
return s; | return s; |
} | } |
| |
void CQLSelectStatementRep::setHasWhereClause() | void CQLSelectStatementRep::setHasWhereClause() |
{ | { |
|
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::setHasWhereClause"); |
_hasWhereClause = true; | _hasWhereClause = true; |
|
PEG_METHOD_EXIT(); |
} | } |
| |
Boolean CQLSelectStatementRep::hasWhereClause() | Boolean CQLSelectStatementRep::hasWhereClause() |
{ | { |
|
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::hasWhereClause"); |
return _hasWhereClause; | return _hasWhereClause; |
} | } |
| |
void CQLSelectStatementRep::clear() | void CQLSelectStatementRep::clear() |
{ | { |
if(_ctx == NULL){ |
PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::clear"); |
|
|
|
if(_ctx == NULL) |
|
{ |
|
PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"null QC"); |
|
PEG_METHOD_EXIT(); |
MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL", | MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL", |
"Trying to process a query with a NULL Query Context."); | "Trying to process a query with a NULL Query Context."); |
throw CQLRuntimeException(parms); | throw CQLRuntimeException(parms); |
|
|
_contextApplied = false; | _contextApplied = false; |
_predicate = CQLPredicate(); | _predicate = CQLPredicate(); |
_selectIdentifiers.clear(); | _selectIdentifiers.clear(); |
|
|
|
PEG_METHOD_EXIT(); |
} | } |
| |
PEGASUS_NAMESPACE_END | PEGASUS_NAMESPACE_END |