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

   1 chuck 1.2 //%2003////////////////////////////////////////////////////////////////////////
   2           //
   3           // Copyright (c) 2000, 2001, 2002  BMC Software, Hewlett-Packard Development
   4           // Company, L. P., IBM Corp., The Open Group, Tivoli Systems.
   5           // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L. P.;
   6           // IBM Corp.; EMC Corporation, The Open Group.
   7           //
   8           // Permission is hereby granted, free of charge, to any person obtaining a copy
   9           // of this software and associated documentation files (the "Software"), to
  10           // deal in the Software without restriction, including without limitation the
  11           // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  12           // sell copies of the Software, and to permit persons to whom the Software is
  13           // furnished to do so, subject to the following conditions:
  14           // 
  15           // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
  16           // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
  17           // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
  18           // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  19           // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  20           // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  21           // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  22 chuck 1.2 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23           //
  24           //==============================================================================
  25           //
  26           // Authors: David Rosckes (rosckes@us.ibm.com)
  27           //          Bert Rivero (hurivero@us.ibm.com)
  28           //          Chuck Carmack (carmack@us.ibm.com)
  29           //          Brian Lucier (lucier@us.ibm.com)
  30           //
  31           // Modified By: 
  32           //
  33           //%/////////////////////////////////////////////////////////////////////////////
  34           
  35           #include "CQLSelectStatement.h"
  36           
  37           #include "CQLSelectStatementRep.h"
  38           
  39           #include <iostream>
  40           
  41           #include <Pegasus/Common/CIMValue.h>
  42           #include <Pegasus/Common/CIMInstance.h>
  43 chuck 1.2 #include <Pegasus/Common/CIMProperty.h>
  44           #include <Pegasus/Query/QueryCommon/QueryException.h>
  45           #include <Pegasus/Query/QueryCommon/QueryIdentifier.h>
  46           #include <Pegasus/Query/QueryCommon/QueryChainedIdentifier.h>
  47 chuck 1.3 #include <Pegasus/Common/Tracer.h>
  48 chuck 1.2 #include <Pegasus/Common/InternalException.h>
  49           #include <Pegasus/Common/CIMStatusCode.h>
  50           #include <Pegasus/Common/AutoPtr.h>
  51           #include "CQLValue.h"
  52           #include "CQLIdentifier.h"
  53           #include "CQLChainedIdentifier.h"
  54           #include "Cql2Dnf.h"
  55           
  56           // ATTN: TODOs - 
  57           // optimize
  58           // documentation
  59           
  60           PEGASUS_NAMESPACE_BEGIN
  61           
  62           struct PropertyNode
  63           {
  64             CIMName name;              // property name
  65             CIMName scope;             // class the property is on
  66 chuck 1.3   Boolean wildcard;          // true if this property is wildcarded 
  67             Boolean endpoint;          // true if this property is an endpoint
  68                                        // of a chained identifier
  69 chuck 1.2   AutoPtr<PropertyNode> sibling;
  70             AutoPtr<PropertyNode> firstChild;
  71           
  72             PropertyNode() {/*PEGASUS_STD(cout) << "new " << this << PEGASUS_STD(endl);*/}
  73             ~PropertyNode() {/*PEGASUS_STD(cout) << "delete " << this << PEGASUS_STD(endl);*/}
  74           };
  75           
  76           
  77           CQLSelectStatementRep::CQLSelectStatementRep()
  78             :SelectStatementRep(),
  79              _hasWhereClause(false),
  80              _contextApplied(false)
  81           {
  82 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep()");
  83 chuck 1.2 }
  84           
  85           CQLSelectStatementRep::CQLSelectStatementRep(String& inQlang,
  86                                                        String& inQuery,
  87                                                        QueryContext& inCtx)
  88             :SelectStatementRep(inQlang, inQuery, inCtx),
  89              _hasWhereClause(false),
  90              _contextApplied(false)
  91           {
  92 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep(inQlang,inQuery,inCtx)");
  93 chuck 1.2 }
  94           
  95           CQLSelectStatementRep::CQLSelectStatementRep(String& inQlang,
  96                                                        String& inQuery)
  97                                                        
  98             :SelectStatementRep(inQlang, inQuery),
  99              _hasWhereClause(false),
 100              _contextApplied(false)
 101           {
 102 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep(inQlang,inQuery)");
 103 chuck 1.2 }
 104           
 105           CQLSelectStatementRep::CQLSelectStatementRep(const CQLSelectStatementRep& rep)
 106             :SelectStatementRep(rep),
 107              _selectIdentifiers(rep._selectIdentifiers),
 108              _hasWhereClause(rep._hasWhereClause),
 109              _predicate(rep._predicate),
 110              _contextApplied(rep._contextApplied)
 111           {
 112 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep(rep)");
 113 chuck 1.2 }
 114           
 115           CQLSelectStatementRep::~CQLSelectStatementRep()
 116           {
 117 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "~CQLSelectStatementRep()");
 118 chuck 1.2 }
 119           
 120           CQLSelectStatementRep& CQLSelectStatementRep::operator=(const CQLSelectStatementRep& rhs)
 121           {
 122 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::operator=");
 123           
 124 chuck 1.2   if (this ==  &rhs)
 125 chuck 1.3   {
 126               PEG_METHOD_EXIT();
 127 chuck 1.2     return *this;
 128 chuck 1.3   }
 129 chuck 1.2 
 130             SelectStatementRep::operator=(rhs);
 131           
 132             _selectIdentifiers = rhs._selectIdentifiers;
 133             _predicate = rhs._predicate;
 134             _contextApplied = rhs._contextApplied;
 135             _hasWhereClause = rhs._hasWhereClause;
 136           
 137 chuck 1.3   PEG_METHOD_EXIT();
 138 chuck 1.2   return *this;
 139           }
 140           
 141 chuck 1.3 Boolean CQLSelectStatementRep::evaluate(const CIMInstance& inCI)
 142 chuck 1.2 {
 143 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::evaluate");
 144 chuck 1.2 
 145 chuck 1.3   if(_ctx == NULL)
 146             {
 147               PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"QC not set");
 148               PEG_METHOD_EXIT();
 149 chuck 1.2     MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL",
 150                                        "Trying to process a query with a NULL Query Context.");
 151               throw CQLRuntimeException(parms);
 152             }
 153 chuck 1.3 
 154 chuck 1.2   if (!hasWhereClause())
 155             {
 156 chuck 1.3     PEG_METHOD_EXIT();
 157 chuck 1.2     return true;
 158             }
 159             else
 160             {
 161               if (!_contextApplied)
 162                 applyContext();
 163           
 164               try
 165               {
 166 chuck 1.3       PEG_METHOD_EXIT();
 167 chuck 1.2       return _predicate.evaluate(inCI, *_ctx);
 168               }
 169               catch (CQLNullContagionException& )
 170               {
 171                 // The null contagion rule.
 172 chuck 1.3       PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"null contagion");
 173                 PEG_METHOD_EXIT();
 174 chuck 1.2       return false;
 175               }
 176             }
 177 chuck 1.3 
 178             PEGASUS_ASSERT(false);
 179             PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"should not get here in evaluate");
 180             return true;  //should never get here
 181 chuck 1.2 }
 182           
 183           void CQLSelectStatementRep::applyProjection(CIMInstance& inCI) throw(Exception)
 184           {
 185 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::applyProjection(inCI)");
 186           
 187             if(_ctx == NULL)
 188             {
 189               PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"QC not set");
 190               PEG_METHOD_EXIT();
 191 chuck 1.2     MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL",
 192                                        "Trying to process a query with a NULL Query Context.");
 193               throw CQLRuntimeException(parms);
 194             }
 195           
 196             if (!_contextApplied)
 197               applyContext();
 198           
 199             //
 200             // Build a tree to represent the projected properties from the select list
 201             // of chained identifiers.  This is needed because embedded instances below 
 202             // the FROM class form a tree structure when projected.
 203             //
 204             // The design of the tree is to gather all the required properties for 
 205             // an instance at a node as child nodes.  The root node 
 206             // of the tree represents the instance passed in to this function.  Below the 
 207             // root there can be nodes that are required embedded instance properties. 
 208             // The child nodes of these embedded instance nodes represent the required
 209             // properties on the embedded instance (which may themselves be embedded instances).
 210             //
 211             // Each node has a name, which is in 2 parts -- the property name and the 
 212 chuck 1.2   // scope (ie. the class the property is on).  This allows the scoping
 213             // operator to be handled correctly, so that the parent instance can be
 214             // checked to see if it is the right class to provide the property.
 215             // Note that the scoping is a base class; ie. the parent instance of a node
 216             // may be a subclass of the scope.
 217             //
 218           
 219             // Set up the root node of the tree.  This represents the instance
 220             // passed in.
 221             AutoPtr<PropertyNode> rootNode(new PropertyNode);
 222             Array<QueryIdentifier> fromList = _ctx->getFromList();
 223             rootNode->name = fromList[0].getName();  // not doing joins
 224             rootNode->scope = fromList[0].getName(); // not used on root, just to fill in the var
 225             rootNode->wildcard = false;
 226            
 227             // Build the tree below the root.
 228             for (Uint32 i = 0; i < _selectIdentifiers.size(); i++)
 229             {
 230 chuck 1.3     PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"select chained id = " +
 231                                 _selectIdentifiers[i].toString());
 232           
 233 chuck 1.2     // Get the chain elements
 234               Array<CQLIdentifier> ids = _selectIdentifiers[i].getSubIdentifiers();
 235           
 236               PEGASUS_ASSERT(ids.size() > 1);
 237           
 238               PropertyNode * curNode = rootNode.get();
 239               PropertyNode * curChild = curNode->firstChild.get();
 240           
 241               // Loop through the identifiers in the chain.
 242               // NOTE: this starts at the position *after* the FROM class
 243               // So, the loop index is always one position after the current node,
 244               // ie. it will become a child node of the current node.
 245               for (Uint32 j = 1; j < ids.size(); j++)
 246               {
 247 chuck 1.3       PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"curNode = " + curNode->name.getString());
 248                 PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"id = " + ids[j].toString());
 249           
 250 chuck 1.2       // If the child is wildcarded, then every property exposed by the
 251                 // class of the instance at the current node is required.
 252                 // Mark the current node as wildcarded.
 253                 if (ids[j].isWildcard())
 254                 {
 255 chuck 1.3         PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"id is wildcard");
 256 chuck 1.2         curNode->wildcard = true;
 257                   break;
 258                 }
 259           
 260                 // Determine if this identifier is already a child node of
 261                 // the current node.
 262                 Boolean found = false;
 263                 while (curChild != NULL && !found)
 264                 {
 265                   // The scoping class is either the scope of the identifier
 266                   // or the FROM class if the identifier is not scoped.
 267                   String scope = fromList[0].getName().getString();
 268                   if (ids[j].isScoped())
 269                   {
 270                     scope = ids[j].getScope();
 271                   }
 272           
 273 chuck 1.3         PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"scope to compare = " + scope);
 274           
 275 chuck 1.2         if (curChild->name == ids[j].getName() &&
 276                       String::equalNoCase(curChild->scope.getString(), scope))
 277                   {
 278 chuck 1.3           // Name and scope match.  The identifier is already child node.
 279                     PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"id is already a child node");
 280 chuck 1.2           found = true;
 281                   }
 282                   else
 283                   {
 284                     curChild = curChild->sibling.get();
 285                   }
 286                 }
 287           
 288                 if (!found)
 289                 {
 290 chuck 1.3         // The identifier is not already a child node. 
 291 chuck 1.2         // Create a node and add it as a child to the current node.
 292 chuck 1.3         PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"new child" + 
 293                                     ids[j].getName().getString());
 294 chuck 1.2         curChild = new PropertyNode;
 295                   curChild->sibling = curNode->firstChild;
 296                   curChild->name = ids[j].getName();
 297                   curChild->wildcard = false;
 298 chuck 1.3         curChild->endpoint = false;
 299 chuck 1.2         curNode->firstChild.reset(curChild);  // safer than using the = operator
 300                 }
 301           
 302                 // Set the scope for the child node
 303                 if (ids[j].isScoped())
 304                 {
 305                   // Child node has a scoping class
 306                   PEGASUS_ASSERT(ids[j].getScope().size() > 0);
 307 chuck 1.3         PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"child set with scoping class: " +
 308                                     ids[j].getScope());
 309 chuck 1.2         curChild->scope =  CIMName(ids[j].getScope());
 310                 }
 311                 else
 312                 {
 313                   // Not scoped.  The scope is the FROM class.
 314                   PEGASUS_ASSERT(j == 1);
 315                   PEGASUS_ASSERT(fromList[0].getName().getString().size() > 0);
 316 chuck 1.3         PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"child set with scoping class: " + 
 317                                     fromList[0].getName().getString());
 318 chuck 1.2         curChild->scope = fromList[0].getName();
 319                 }
 320           
 321 chuck 1.3       // If the identifier is the last element of the chain, 
 322                 // then mark it as an endpoint
 323                 if ((ids.size() - 1) == j)
 324                 {
 325                   curChild->endpoint = true;
 326                 }
 327           
 328 chuck 1.2       curNode = curChild;
 329                 curChild = curNode->firstChild.get();
 330               }
 331             }
 332           
 333             //
 334             // Do the projection.
 335             //
 336           
 337             Array<CIMName> requiredProps;
 338             Boolean allPropsRequired = rootNode->wildcard;
 339           
 340             // Loop through the children of the root node.
 341             // The root node represents the FROM class,
 342             // and the child nodes are the required properties on the FROM class.
 343             PropertyNode* childNode = rootNode->firstChild.get();
 344             while (childNode != NULL)
 345             {
 346 chuck 1.3     PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"project childNode = " + childNode->name.getString());
 347           
 348 chuck 1.2     // Determine if the instance passed in meets the class scoping
 349               // rules for the current child node.
 350               Boolean filterable = isFilterable(inCI, childNode);
 351           
 352 chuck 1.3     // Indicates if the child node is still required after the recursive call.
 353               Boolean childRequired = true;
 354           
 355 chuck 1.2     // If the instance is filterable, and the child node has children,
 356               // or is wildcarded, then the child is assumed to be an embedded instance,
 357               // and we need to recurse to apply the projection on the embedded instance.
 358               // (the check for embedded instance is done in the recursive call)
 359               if (filterable && 
 360                   (childNode->firstChild.get() != NULL || childNode->wildcard))
 361               {
 362                 // We need to project on an embedded instance property. The steps are to
 363                 // remove the embedded instance property from the instance passed in,
 364                 // project on that embedded instance property, and then add the projected 
 365                 // embedded instance property back to the instance passed in.
 366 chuck 1.3       PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"about to recurse: " + childNode->name.getString());
 367 chuck 1.2       Uint32 index = inCI.findProperty(childNode->name);
 368                 if (index != PEG_NOT_FOUND)
 369                 {
 370 chuck 1.3         // The instance passed in has the required embedded instance property.
 371                   // Note: embedded instance property missing is caught below.
 372           
 373                   // Remove the embedded instance property
 374 chuck 1.2         CIMProperty childProp = inCI.getProperty(index);
 375                   inCI.removeProperty(index);
 376 chuck 1.3 
 377                   // Project onto the embedded instance property. 
 378                   // If the last parameter is true, then the childNode
 379                   // will not remove properties when filtering the embedded instance.
 380                   // This call returns whether the embedded instance property
 381                   // should be added to the required property list.
 382                   childRequired = applyProjection(childNode, childProp, allPropsRequired);
 383 chuck 1.2         inCI.addProperty(childProp);
 384                 }
 385               }
 386           
 387               // If the node is not wildcarded, and the instance passed in
 388               // is filterable, then add the current child to the list
 389 chuck 1.3     // if it is still required.
 390               if (!allPropsRequired && filterable && childRequired)
 391 chuck 1.2     {
 392 chuck 1.3       PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"add req prop: " + childNode->name.getString());
 393 chuck 1.2       requiredProps.append(childNode->name);
 394               }
 395           
 396               childNode = childNode->sibling.get();
 397             }
 398           
 399             // Remove the properties that are not in the projection.
 400             // This also checks for missing required properties.
 401 chuck 1.3   Boolean preserve = false;
 402             filterInstance(inCI,
 403                            allPropsRequired,
 404                            fromList[0].getName(),
 405                            requiredProps,
 406                            preserve);
 407 chuck 1.2 }
 408           
 409 chuck 1.3 Boolean CQLSelectStatementRep::applyProjection(PropertyNode* node,
 410                                                          CIMProperty& nodeProp,
 411                                                          Boolean& preservePropsForParent)
 412 chuck 1.2 {
 413 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::applyProjection(node, nodeProp)");
 414           
 415             PEGASUS_ASSERT(node->firstChild.get() != NULL || node->wildcard);
 416 chuck 1.2 
 417             //
 418             // The property passed in must be an embedded instance. It is not
 419             // allowed to project properties on embedded classes.
 420             // Get the embedded instance from the property.
 421             //
 422           
 423 chuck 1.3   // First check that it is an embedded object
 424 chuck 1.2   CIMValue nodeVal = nodeProp.getValue();
 425             if (nodeVal.getType() != CIMTYPE_OBJECT)
 426             {
 427 chuck 1.3     PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"not emb");
 428               PEG_METHOD_EXIT();
 429 chuck 1.2     MessageLoaderParms parms("CQL.CQLSelectStatementRep.PROP_NOT_EMB",
 430                                        "The property $0 must contain an embedded object.",
 431                                        nodeProp.getName().getString());
 432               throw CQLRuntimeException(parms);
 433             }
 434 chuck 1.3 
 435             if (nodeVal.isNull())
 436             {
 437               // Since we will be projecting on the embedded object, it cannot be null
 438               PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"value is null");
 439               PEG_METHOD_EXIT();
 440               MessageLoaderParms parms("CQL.CQLSelectStatementRep.NULL_EMB_OBJ",
 441                                        "The embedded object property $0 cannot contain a null value.",
 442                                        nodeProp.getName().getString());
 443               throw CQLRuntimeException(parms);
 444             }
 445 chuck 1.2 
 446             if (nodeVal.isArray() && 
 447                 (node->firstChild.get() != NULL || node->wildcard))
 448             {
 449               // NOTE - since we are blocking projection of array elements, we can
 450               // assume that if we get here we were told to project a whole array (ie. no index used), as
 451               // an embedded object with properties or wildcard.
 452               // Examples not allowed:  SELECT fromClass.someArrayProp.scope::notAllowedProp FROM fromClass
 453               //                        SELECT fromClass.someArrayProp.* FROM fromClass
 454 chuck 1.3     PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"array index needed");
 455               PEG_METHOD_EXIT();
 456 chuck 1.2     MessageLoaderParms parms("CQL.CQLSelectStatementRep.PROJ_WHOLE_ARRAY",
 457 chuck 1.3                   "CQL requires that array indexing is used on embedded object property $0.",
 458                              nodeProp.getName().getString());
 459               throw CQLRuntimeException(parms);
 460             }
 461           
 462             CIMObject nodeObj;  // this starts uninitialized
 463             nodeVal.get(nodeObj);
 464             if (nodeObj.isUninitialized())
 465             {
 466               // Not allowed to project on an uninitialized object
 467               PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"is uninitialized");
 468               PEG_METHOD_EXIT();
 469               MessageLoaderParms parms("CQL.CQLSelectStatementRep.PROJ_UNINIT",
 470                                        "The embedded object property $0 is uninitialized.",
 471 chuck 1.2                              nodeProp.getName().getString());
 472               throw CQLRuntimeException(parms);
 473             }
 474           
 475             if (!nodeObj.isInstance())
 476             {
 477               // Not allowed to project on a Class
 478 chuck 1.3     PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"is a class");
 479               PEG_METHOD_EXIT();
 480 chuck 1.2     MessageLoaderParms parms("CQL.CQLSelectStatementRep.PROJ_CLASS",
 481                                        "CQL does not allow properties to be projected on class $0.",
 482                                        nodeProp.getName().getString());
 483               throw CQLRuntimeException(parms);
 484             }
 485           
 486             CIMInstance nodeInst(nodeObj);  
 487 chuck 1.3 
 488 chuck 1.2   //
 489             // Do the projection.
 490             //
 491           
 492             Array<CIMName> requiredProps;
 493             Boolean allPropsRequired = node->wildcard;
 494           
 495             // Loop through the children of the node.
 496             // The node represents an embedded instance,
 497             // and the child nodes are the required properties on the embedded instance.
 498             PropertyNode * curChild = node->firstChild.get();
 499             while (curChild != NULL)
 500             {
 501 chuck 1.3     PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"project childNode = " + curChild->name.getString());
 502           
 503 chuck 1.2     // Determine if the embedded instance meets the class scoping
 504               // rules for the current child node
 505               Boolean filterable = isFilterable(nodeInst, curChild);
 506           
 507 chuck 1.3     // Indicates if the child node is still required after the recursive call.
 508               Boolean childRequired = true;
 509           
 510 chuck 1.2     // If the embedded instance is filterable, and the child node has children,
 511               // or is wildcarded, then the child is assumed to be an embedded instance,
 512               // and we need to recurse to apply the projection on the embedded instance.
 513               // (the check for embedded instance is done in the recursive call)
 514               if (filterable && 
 515                   (curChild->firstChild.get() != NULL || curChild->wildcard))
 516               {
 517                 // We need to project on an embedded instance property. The steps are to
 518                 // remove the embedded instance property from the current instance,
 519                 // project on that embedded instance property, and then add the projected 
 520                 // embedded instance property back to the current instance.
 521 chuck 1.3       PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"about to recurse: " + curChild->name.getString());
 522 chuck 1.2       Uint32 index = nodeInst.findProperty(curChild->name);
 523                 if (index != PEG_NOT_FOUND)
 524                 {
 525 chuck 1.3         // The current instance has the required embedded instance property.
 526                   // Note: embedded instance property missing is caught below.
 527           
 528                   // Remove the embedded instance property
 529 chuck 1.2         CIMProperty childProp = nodeInst.getProperty(index); 
 530                   nodeInst.removeProperty(index);
 531 chuck 1.3 
 532                   // Project onto the embedded instance property. 
 533                   // If the last parameter is true, then the childNode
 534                   // will not remove properties when filtering the embedded instance.
 535                   // This call returns whether the embedded instance property
 536                   // should be added to the required property list.
 537                   Boolean preserve = 
 538                     node->endpoint || allPropsRequired || preservePropsForParent;
 539                   childRequired = applyProjection(curChild, childProp, preserve);
 540 chuck 1.2         nodeInst.addProperty(childProp);
 541                 }
 542               }
 543           
 544               // If the node is not wildcarded, and the embedded instance
 545               // is filterable, then add the current child to the list
 546 chuck 1.3     // if it is still required.
 547               if (!allPropsRequired && filterable && childRequired)
 548 chuck 1.2     {
 549                 // The instance is filterable, add the property to the required list. 
 550 chuck 1.3       PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"add req prop: " + curChild->name.getString());
 551                 requiredProps.append(curChild->name);
 552 chuck 1.2     }
 553           
 554               curChild = curChild->sibling.get();
 555             }
 556           
 557 chuck 1.3   // Filter the instance.
 558             // This removes unneeded properties, unless this
 559             // embedded instance node was an endpoint (last element)
 560             // in a chained identifier.
 561             // This also checks for missing required properties on the instance.
 562             Boolean preserveProps = node->endpoint || preservePropsForParent;
 563             filterInstance(nodeInst, 
 564                            allPropsRequired,
 565                            nodeInst.getClassName(),
 566                            requiredProps,
 567                            preserveProps);
 568 chuck 1.2 
 569             // Put the projected instance back into the property.
 570 chuck 1.3   CIMObject newNodeObj(nodeInst);
 571             CIMValue newNodeVal(newNodeObj);
 572             nodeProp.setValue(newNodeVal);
 573           
 574             // Indicate to the caller whether the projected instance
 575             // is still a required property.  It is required if it is an endpoint
 576             // (ie. the last element of a chained identifier)
 577             // OR if it still has properties after being projected
 578             if (node->endpoint || nodeInst.getPropertyCount() > 0)
 579             {
 580               return true;
 581             }
 582           
 583             return false;
 584 chuck 1.2 } 
 585           
 586           Boolean CQLSelectStatementRep::isFilterable(const  CIMInstance& inst,
 587                                                       PropertyNode* node)
 588           {
 589 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::isFilterable");
 590             PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"instance = " + inst.getClassName().getString()); 
 591             PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"scope = " + node->scope.getString()); 
 592           
 593 chuck 1.2   //
 594             // Determine if an instance is filterable for a scoped property (ie. its
 595             // type is the scoping class or a subclass of the scoping class where the
 596             // property exists)
 597             //
 598             // Note that an instance that is unfilterable is not considered
 599             // an error.  In CQL, an instance that is not of the required scope
 600             // would cause a NULL to be placed in the result set column for the 
 601             // property. However since we are not implementing result set in stage1,
 602             // just skip the property.  This can lead to an instance having
 603             // NO required properties even though it is derived from the FROM class.
 604             // This can easily happen if the scoping operator is used.
 605             //
 606           
 607             Boolean filterable = false;
 608             if (inst.getClassName() == node->scope)
 609             {
 610               // The instance's class is the same as the required scope
 611 chuck 1.3     PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"instance matches scope");
 612 chuck 1.2     filterable = true;
 613             }
 614             else
 615             {
 616               try 
 617               {
 618                 if (_ctx->isSubClass(node->scope, inst.getClassName()))
 619                 {
 620                   // The instance's class is a subclass of the required scope.
 621 chuck 1.3         PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"instance is subclass of scope");
 622 chuck 1.2         filterable = true;
 623                 }
 624               }
 625               catch (CIMException& ce)
 626               {
 627                 if (ce.getCode() == CIM_ERR_INVALID_CLASS || 
 628                     ce.getCode() == CIM_ERR_NOT_FOUND)
 629                 {
 630                   // The scoping class was not found in the schema.
 631                   // Just swallow this error because according to the
 632                   // spec we should be putting NULL in the result column,
 633                   // which means skipping the property on the instance.
 634 chuck 1.3         PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"scope class not in schema");
 635                 }
 636                 else
 637                 {
 638                   PEG_METHOD_EXIT();
 639                   throw ce;
 640 chuck 1.2       }
 641               }
 642             }
 643             
 644 chuck 1.3   PEG_METHOD_EXIT();
 645 chuck 1.2   return filterable;
 646           } 
 647           
 648 chuck 1.3 void CQLSelectStatementRep::filterInstance(CIMInstance& inst, 
 649                                                      Boolean& allPropsRequired,
 650                                                      const CIMName& allPropsClass,
 651                                                      Array<CIMName>& requiredProps,
 652                                                      Boolean& preserveProps)
 653           {
 654             PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::removeUnneededProperties");
 655             PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"instance = " + inst.getClassName().getString()); 
 656             PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"allPropsClass = " + allPropsClass.getString()); 
 657           
 658 chuck 1.2   // Implementation note:
 659             // Scoping operator before a wildcard is not allowed:
 660             // Example:
 661             // SELECT fromclass.embobj1.scope1::* FROM fromclass
 662             //
 663             // However, the following are allowed:
 664             // SELECT fromclass.embobj1.* FROM fromclass
 665             // (this means that all the properties on the class of instance embobj1
 666             //  are required)
 667             //
 668             // SELECT fromclass.* FROM fromclass
 669             // (this means that all the properties on class fromclass are required
 670             //  to be on the instance being projected, not including any
 671             //  properties on a subclass of fromclass)
 672           
 673             // If all properties are required (ie. wildcarded), then rebuild the 
 674             // required property list from all the properties on the classname passed in  
 675             // This is either the FROM class or the class of an embedded instance.
 676             if (allPropsRequired)
 677             {
 678 chuck 1.3     PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"all props required"); 
 679 chuck 1.2     requiredProps.clear();
 680               CIMClass cls = _ctx->getClass(allPropsClass);
 681               Array<CIMName> clsProps;
 682               for (Uint32 i = 0; i < cls.getPropertyCount(); i++)
 683               {
 684                 requiredProps.append(cls.getProperty(i).getName());
 685               }
 686             }
 687           
 688             // Find out what properties are on the instance.
 689             Array<CIMName> supportedProps;
 690             for (Uint32 i = 0; i < inst.getPropertyCount(); i++)
 691             {
 692               supportedProps.append(inst.getProperty(i).getName());
 693             }
 694             
 695             // Check that all required properties are on the instance.
 696             for (Uint32 i = 0; i < requiredProps.size(); i++)
 697             {
 698               if (!containsProperty(requiredProps[i], supportedProps))
 699               {
 700 chuck 1.3       PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"missing:" + requiredProps[i].getString()); 
 701                 PEG_METHOD_EXIT();
 702                 MessageLoaderParms parms("CQL.CQLSelectStatementRep.PROJ_MISSING_PROP",
 703 chuck 1.2                                "The property $0 is missing on the instance of class $1.",
 704                                          requiredProps[i].getString(), inst.getClassName().getString());
 705 chuck 1.4       throw QueryRuntimePropertyException(parms);
 706 chuck 1.2     }
 707             }
 708           
 709 chuck 1.3   // If requested, remove the properties on the instance that are not required.
 710             if (!preserveProps)
 711 chuck 1.2   {
 712 chuck 1.3     for (Uint32 i = 0; i < supportedProps.size(); i++)
 713 chuck 1.2     {
 714 chuck 1.3       if (!containsProperty(supportedProps[i], requiredProps))
 715                 {
 716                   Uint32 index = inst.findProperty(supportedProps[i]);
 717                   PEGASUS_ASSERT(index != PEG_NOT_FOUND);
 718                   PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"removing:" + supportedProps[i].getString());
 719                   inst.removeProperty(index);
 720                 }
 721 chuck 1.2     }
 722             }
 723 chuck 1.3 
 724             PEG_METHOD_EXIT();
 725 chuck 1.2 }
 726           
 727           //
 728           // Validates that all the chained identifiers in the statement meet
 729           // the rules in the CQL spec vs.the class definitions in the repository
 730           //
 731           void CQLSelectStatementRep::validate() throw(Exception)
 732           {
 733 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::validate");
 734           
 735             if(_ctx == NULL)
 736             {
 737               PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"null QC");
 738               PEG_METHOD_EXIT();
 739 chuck 1.2     MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL",
 740                                        "Trying to process a query with a NULL Query Context.");
 741 chuck 1.4     throw QueryValidationException(parms);
 742 chuck 1.2   }
 743           
 744             if (!_contextApplied)
 745               applyContext();
 746           
 747             for (Uint32 i = 0; i < _selectIdentifiers.size(); i++)
 748             {
 749               validateProperty(_selectIdentifiers[i]);
 750             }
 751           
 752             Array<QueryChainedIdentifier> _whereIdentifiers = _ctx->getWhereList();
 753             for (Uint32 i = 0; i < _whereIdentifiers.size(); i++)
 754             {
 755               validateProperty(_whereIdentifiers[i]);
 756             }
 757 chuck 1.3 
 758             PEG_METHOD_EXIT();
 759 chuck 1.2 }
 760           
 761           //
 762           // Validates that the chained identifier meets all the rules in the CQL
 763           // spec vs.the class definitions in the repository
 764           //
 765           void CQLSelectStatementRep::validateProperty(QueryChainedIdentifier& chainId)
 766           {
 767 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::validateProperty");
 768           
 769 chuck 1.2   // Note: applyContext has been called beforehand
 770             
 771             Array<QueryIdentifier> ids = chainId.getSubIdentifiers();
 772           
 773             Uint32 startingPos = 0;
 774             CIMName curContext;
 775             for (Uint32 pos = startingPos; pos < ids.size(); pos++)
 776             {
 777               // Determine the current class context
 778               if (ids[pos].isScoped())
 779               {
 780                 // The chain element is scoped.  Use the scoping
 781                 // class as the current context.  Note: this depends 
 782                 // on applyContext resolving the class aliases before we get here.
 783                 curContext = CIMName(ids[pos].getScope());
 784               }
 785               else
 786               {
 787                 // The chain element is not scoped.  Assume that we are
 788                 // before a position that is required to be scoped.
 789                 // (applyContext validates that the chained identifier
 790 chuck 1.2       // has scoped identifiers in the required positions).
 791                 // The current context is the name at the first position,
 792                 // which must be a classname (ie. right side of ISA where
 793                 // the only element in the chain is a classname, or
 794                 // cases where the FROM class is the first, and maybe only,
 795                 // element of the chain).
 796                 PEGASUS_ASSERT((pos < startingPos + 2) || ids[pos].isWildcard());
 797                 curContext = ids[0].getName();
 798               }
 799           
 800 chuck 1.3     PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"current context: " +
 801                                  curContext.getString());
 802           
 803 chuck 1.2     // Get the class definition of the current class context
 804 chuck 1.3     // Note: keep this code here so that class existence is always
 805               // checked.  Eg. SELECT * FROM fromClass
 806 chuck 1.2     CIMClass classDef;
 807               try 
 808               {
 809                 classDef = _ctx->getClass(curContext);
 810               }
 811               catch (CIMException& ce)
 812               {
 813 chuck 1.3       PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"repository error");
 814                 PEG_METHOD_EXIT();
 815 chuck 1.2       if (ce.getCode() == CIM_ERR_NOT_FOUND ||
 816                     ce.getCode() == CIM_ERR_INVALID_CLASS)
 817                 {
 818                   MessageLoaderParms parms("CQL.CQLSelectStatementRep.VAL_CLASS_NOT_EXIST",
 819                                          "The class $0 does not exist.",
 820                                           curContext.getString());
 821 chuck 1.4         throw QueryValidationException(parms);
 822 chuck 1.2       }
 823 chuck 1.3       else
 824                 {
 825                   throw ce;
 826                 }
 827 chuck 1.2     }
 828           
 829               // Now do the checks for properties existing on the current class context
 830               // and the class relationship rules in section 5.4.1.
 831               // Only do these checks if the chain id has a property.
 832               if (pos > startingPos)
 833               {
 834                 if (ids[pos].isWildcard())
 835                 {
 836                   // The wildcard is at the end (verified by applyContext), so
 837                   // no checking is required at this position.
 838                   continue;
 839                 }
 840           
 841                 // Determine if the property name at the current position
 842                 // exists on the current class context.
 843                 Uint32 propertyIndex = classDef.findProperty(ids[pos].getName());
 844                 if (propertyIndex == PEG_NOT_FOUND)
 845                 {
 846 chuck 1.3         PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"prop not on context " +
 847                                     ids[pos].getName().getString());
 848                   PEG_METHOD_EXIT();
 849 chuck 1.2         MessageLoaderParms parms("CQL.CQLSelectStatementRep.VAL_PROP_NOT_ON_CLASS",
 850                                          "The property $0 does not exist on class $1.",
 851                                           ids[pos].getName().getString(), classDef.getClassName().getString());
 852 chuck 1.4         throw QueryMissingPropertyException(parms);
 853 chuck 1.2       }
 854           
 855                 // Checking class relationship rules in section 5.4.1.
 856                 // For validateProperties, this only applies to the first
 857                 // property in the chain.  This is because once we get into
 858                 // embedded properties we don't know what the class will be
 859                 // until we have an instance.
 860                 if ((pos == (startingPos+1)) && !curContext.equal(ids[0].getName()))
 861                 {
 862                   // Its the first property, and the class context is not the FROM class.
 863                   // Check the class relationship between the scoping class and the FROM class.
 864                   if (_ctx->getClassRelation(ids[0].getName(), curContext) == QueryContext::NOTRELATED)
 865                   {
 866 chuck 1.3           PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"scope violation for:"+
 867                                       ids[0].getName().getString());
 868                     PEG_METHOD_EXIT();
 869 chuck 1.2           MessageLoaderParms parms("CQL.CQLSelectStatementRep.VAL_SCOPE_VIOLATION",
 870                                          "The class $0 is not a superclass, subclass, or the same class as $1.",
 871                                           curContext.getString(), ids[0].getName().getString());
 872 chuck 1.4           throw QueryValidationException(parms);
 873 chuck 1.2         }
 874                 }
 875           
 876                 // If the current position implies an embedded object, then
 877                 // verify that the property is an embedded object
 878                 if ((pos > startingPos) && (pos < (ids.size() - 1))) 
 879                 {
 880                   CIMProperty embObj = classDef.getProperty(propertyIndex);
 881                   CIMName qual("EmbeddedObject");
 882                   if (embObj.findQualifier(qual) == PEG_NOT_FOUND)
 883                   {
 884 chuck 1.3           PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"prop not emb " +
 885                                       embObj.getName().getString());
 886                     PEG_METHOD_EXIT();
 887 chuck 1.2           MessageLoaderParms parms("CQL.CQLSelectStatementRep.PROP_NOT_EMB",
 888                                        "The property $0 must be an embedded object.",
 889                                        embObj.getName().getString());
 890 chuck 1.4           throw QueryValidationException(parms);
 891 chuck 1.2         }
 892                 }
 893               }
 894             }
 895 chuck 1.3   
 896             PEG_METHOD_EXIT();
 897 chuck 1.2 }
 898           
 899           CIMName CQLSelectStatementRep::lookupFromClass(const String&  lookup)
 900           {
 901 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::lookupFromClass");
 902           
 903 chuck 1.2   QueryIdentifier id = _ctx->findClass(lookup);
 904           
 905 chuck 1.3   PEG_METHOD_EXIT();
 906           
 907 chuck 1.2   return id.getName();
 908           }
 909           
 910           Array<CIMObjectPath> CQLSelectStatementRep::getClassPathList()
 911           {
 912 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::getClassPathList");
 913           
 914 chuck 1.2   if(_ctx == NULL){
 915 chuck 1.3     PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"null QC");
 916               PEG_METHOD_EXIT();
 917 chuck 1.2     MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL",
 918                                        "Trying to process a query with a NULL Query Context.");
 919               throw CQLRuntimeException(parms);
 920             }
 921           
 922             Array<QueryIdentifier> ids = _ctx->getFromList();
 923             PEGASUS_ASSERT(ids.size() == 1);  // no joins yet
 924           
 925             // No wbem-uri support yet.
 926             CIMObjectPath path(String::EMPTY, _ctx->getNamespace(), ids[0].getName());
 927           
 928             Array<CIMObjectPath> paths;
 929             paths.append(path);
 930           
 931 chuck 1.3   PEG_METHOD_EXIT();
 932           
 933 chuck 1.2   return paths;
 934 chuck 1.3 
 935 chuck 1.2 }
 936           
 937           CIMPropertyList CQLSelectStatementRep::getPropertyList(const CIMObjectPath& inClassName)
 938           {
 939 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::getPropertyList");
 940 chuck 1.5   try 
 941             {
 942               return getPropertyListInternal(inClassName, true, true);
 943             }
 944             catch (CIMException& ce)
 945             {
 946               PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"cim exception");
 947               PEG_METHOD_EXIT();
 948               if (ce.getCode() == CIM_ERR_NOT_FOUND ||
 949                   ce.getCode() == CIM_ERR_INVALID_CLASS)
 950               {
 951                 MessageLoaderParms parms("CQL.CQLSelectStatementRep.GPL_CLASS_NOT_EXIST",
 952                                          "A class required to determine the property list was not found.");
 953                 throw CQLRuntimeException(parms);
 954               }
 955               else
 956               {
 957                 throw ce;
 958               }
 959             }
 960 chuck 1.2 }
 961           
 962           CIMPropertyList CQLSelectStatementRep::getSelectPropertyList(const CIMObjectPath& inClassName)
 963           {
 964 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::getSelectPropertyList");
 965 chuck 1.5   try
 966             {
 967               return getPropertyListInternal(inClassName, true, false);
 968             }
 969             catch (CIMException& ce)
 970             {
 971               PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"cim exception");
 972               PEG_METHOD_EXIT();
 973               if (ce.getCode() == CIM_ERR_NOT_FOUND ||
 974                   ce.getCode() == CIM_ERR_INVALID_CLASS)
 975               {
 976                 MessageLoaderParms parms("CQL.CQLSelectStatementRep.GPL_CLASS_NOT_EXIST",
 977                                          "A class required to determine the property list was not found.");
 978                 throw CQLRuntimeException(parms);
 979               }
 980               else
 981               {
 982                 throw ce;
 983               }
 984             }
 985 chuck 1.2 }
 986           
 987           CIMPropertyList CQLSelectStatementRep::getWherePropertyList(const CIMObjectPath& inClassName)
 988           {
 989 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::getWherePropertyList");
 990 chuck 1.5   try
 991             {
 992               return getPropertyListInternal(inClassName, false, true);
 993             }
 994             catch (CIMException& ce)
 995             {
 996               PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"cim exception");
 997               PEG_METHOD_EXIT();
 998               if (ce.getCode() == CIM_ERR_NOT_FOUND ||
 999                   ce.getCode() == CIM_ERR_INVALID_CLASS)
1000               {
1001                 MessageLoaderParms parms("CQL.CQLSelectStatementRep.GPL_CLASS_NOT_EXIST",
1002                                          "A class required to determine the property list was not found.");
1003                 throw CQLRuntimeException(parms);
1004               }
1005               else
1006               {
1007                 throw ce;
1008               }
1009             }
1010 chuck 1.2 }
1011           
1012           CIMPropertyList CQLSelectStatementRep::getPropertyListInternal(const CIMObjectPath& inClassName,
1013                                                                          Boolean includeSelect,
1014                                                                          Boolean includeWhere)
1015           {
1016 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::getPropertyListInternal");
1017           
1018             if(_ctx == NULL)
1019             {
1020               PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"null QC");
1021               PEG_METHOD_EXIT();
1022 chuck 1.2     MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL",
1023                                        "Trying to process a query with a NULL Query Context.");
1024               throw CQLRuntimeException(parms);
1025             }  
1026           
1027             if (!_contextApplied)
1028               applyContext();
1029           
1030 chuck 1.3   // Get the FROM class.
1031             CIMName fromClass = _ctx->getFromList()[0].getName(); 
1032           
1033             // Get the classname passed in.  Note: since wbem-uri is not supported yet,
1034 chuck 1.2   // only use the classname part of the path. 
1035             CIMName className = inClassName.getClassName();
1036             if (className.isNull())
1037             {
1038               // If the caller passed in an empty className, then the 
1039               // FROM class is to be used.
1040 chuck 1.3     className = fromClass;
1041             }
1042             else
1043             {
1044               // The caller passed in some class name.  Verify that it is the FROM
1045               // class or a subclass of the FROM class.
1046               if(!(className == fromClass))
1047               {
1048                 // Check if subclass of the FROM class
1049                 if(!_ctx->isSubClass(fromClass, className))
1050                 {
1051                   MessageLoaderParms parms("CQL.CQLSelectStatementRep.CLASS_NOT_FROM_LIST_CLASS",
1052                               "Class $0 does not match the FROM class or any of its subclasses.",
1053                               className.getString());
1054 chuck 1.4         throw CQLRuntimeException(parms);
1055 chuck 1.3       }
1056 chuck 1.5     } 
1057             }  
1058 chuck 1.2   
1059             Boolean isWildcard;
1060             Array<CIMName> reqProps;
1061             Array<CIMName> matchedScopes;
1062             Array<CIMName> unmatchedScopes;
1063           
1064             // Add required properties from the select list.
1065             if (includeSelect)
1066             {
1067               for (Uint32 i = 0; i < _selectIdentifiers.size(); i++)
1068               {
1069                 isWildcard = addRequiredProperty(reqProps, 
1070                                                  className,
1071                                                  _selectIdentifiers[i],
1072                                                  matchedScopes,
1073                                                  unmatchedScopes);
1074               
1075                 if (isWildcard)
1076                 {
1077 chuck 1.5         // This indicates that a wildcard was found, 
1078                   // and the class passed in was the FROM class.
1079 chuck 1.2         // Return null property list to indicate all properties required.
1080                   return CIMPropertyList();
1081                 }
1082               }
1083             }
1084           
1085             // Add required properties from the WHERE clause.
1086             if (includeWhere)
1087             {
1088               Array<QueryChainedIdentifier> _whereIdentifiers = _ctx->getWhereList();
1089               for (Uint32 i = 0; i < _whereIdentifiers.size(); i++)
1090               {
1091                 isWildcard = addRequiredProperty(reqProps,
1092                                                  className,
1093                                                  _whereIdentifiers[i],
1094                                                  matchedScopes,
1095                                                  unmatchedScopes);                                     
1096           
1097                 // Wildcards are not allowed in the WHERE clause
1098                 PEGASUS_ASSERT(!isWildcard);
1099               }
1100 chuck 1.2   }
1101               
1102             // Check if every property on the class is required.
1103             CIMClass theClass = _ctx->getClass(className);
1104             Uint32 propCnt = theClass.getPropertyCount();
1105             Boolean allProps = true;
1106             for (Uint32 i = 0; i < propCnt; i++)
1107             {
1108               if (!containsProperty(theClass.getProperty(i).getName(), reqProps))
1109               {
1110                 allProps = false;
1111                 break;
1112               }
1113             }
1114           
1115             if (allProps)
1116             {
1117               // Return null property list to indicate all properties are required.
1118 chuck 1.3     PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"all props req");
1119               PEG_METHOD_EXIT();
1120 chuck 1.2     return CIMPropertyList();
1121             }
1122             else
1123             {
1124               // Return the required property list.  Note that it is possible to return
1125               // an empty list in the case of no required properties for the classname
1126               // passed in.  This can happen when the scoping operator is used.
1127 chuck 1.3     PEG_METHOD_EXIT();
1128 chuck 1.2     return CIMPropertyList(reqProps);
1129             }
1130           }
1131           
1132           Boolean CQLSelectStatementRep::addRequiredProperty(Array<CIMName>& reqProps,
1133                                                              CIMName& className,
1134                                                              QueryChainedIdentifier& chainId,
1135                                                              Array<CIMName>& matchedScopes,
1136                                                              Array<CIMName>& unmatchedScopes)
1137           {
1138 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::addRequiredProperty");
1139           
1140 chuck 1.2   //
1141             // Implementation notes:  
1142             // This function does not look for required properties on embedded objects.
1143             // This function assumes that applyContext has been called.
1144             //
1145           
1146             Array<QueryIdentifier> ids = chainId.getSubIdentifiers();
1147           
1148             // After applyContext has been called, a single element
1149             // chained identifier refers to either an instance of the
1150             // FROM class, or is the classname on the right side of ISA.
1151             if (ids.size() == 1)
1152             {
1153               // This identifier is not a property name
1154 chuck 1.3     PEG_METHOD_EXIT();
1155 chuck 1.2     return false;
1156             }
1157           
1158 chuck 1.3   PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"id[1] = " + ids[1].toString());
1159           
1160 chuck 1.2   if (ids[1].isSymbolicConstant())
1161             {
1162               // Non-embedded symbolic constants are not properties
1163               // Note that an embedded symbolic constant like this:
1164               // fromclass.embobj.scope::someprop#'ok'
1165               // implies that embobj is a required property, because 
1166               // embobj could be null, and that affects how the
1167               // identifier is evaluated.
1168 chuck 1.3     PEG_METHOD_EXIT();
1169 chuck 1.2     return false;
1170             }
1171           
1172             // Since applyContext has been called, the first chain element
1173             // will be the FROM class, so go to the 2nd chain element.
1174             if (ids[1].isScoped())
1175             {
1176               // The 2nd chain element is a scoped property.
1177               // Eg. fromclass.someclass::someprop
1178           
1179               // Determine the class that the property is being scoped to.
1180               // This could be the FROM class, or some other class not in the FROM list
1181               CIMName scopingClass = CIMName(ids[1].getScope());
1182           
1183               // Check if the scoping class is the same as the class passed in.
1184               if (scopingClass == className)
1185               {
1186                 // The scoping class is the same as the class passed, 
1187                 // add the property if not already added
1188                 if (!containsProperty(ids[1].getName(), reqProps))
1189                 {  
1190 chuck 1.2         reqProps.append(ids[1].getName());
1191                 }
1192               }
1193               else
1194               {
1195 chuck 1.3       // The scoping class is not the same as the class passed in. 
1196 chuck 1.2       // Check if we already know that the scoping class is a subclass
1197                 // of the class passed in
1198                 if (containsProperty(scopingClass, unmatchedScopes))
1199                 {
1200                   // Scoping class is a subclass.
1201 chuck 1.3         PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"scoping class is a subclass");
1202                   PEG_METHOD_EXIT();
1203 chuck 1.2         return false;
1204                 }
1205                   
1206                 // Check if we already know that the scoping class is a superclass
1207                 // of the class passed in
1208                 Boolean isSuper = false;
1209                 if (containsProperty(scopingClass, matchedScopes))
1210                 {
1211                   // Scoping class is a superclass.
1212                   isSuper = true;
1213                 }
1214           
1215                 // Check if the scoping class is a superclass of the class passed in
1216                 if (isSuper || _ctx->isSubClass(scopingClass, className))
1217                 {
1218 chuck 1.3         PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"scoping class is a superclass");
1219           
1220 chuck 1.2         // Scoping class is a superclass of the class passed in.
1221                   if (!isSuper)
1222                   {
1223                     // Save this information
1224                     matchedScopes.append(scopingClass);
1225                   }
1226           
1227                   // Add to the required property list if not already there.
1228                   if (!containsProperty(ids[1].getName(), reqProps))
1229                   {  
1230                     reqProps.append(ids[1].getName());
1231                   }
1232                 }
1233                 else
1234                 {
1235 chuck 1.3         PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"scoping class is NOT a superclass");
1236           
1237 chuck 1.2         // Scoping class is not superclass of class passed in.
1238                   // Save this information.
1239                   unmatchedScopes.append(scopingClass);
1240                 }
1241               }  // end else scoping class not == class passed in
1242             }  // end if first id is scoped
1243             else
1244             {
1245               // The 2nd chain element is an unscoped property
1246               // Check if it is wildcarded
1247               if (ids[1].isWildcard())
1248               {
1249                 // Wildcard.
1250                 // If the class passed in is the FROM class, then
1251                 // all properties are required on the class passed in.
1252                 CIMName fromClassName = _ctx->getFromList()[0].getName();
1253                 if (fromClassName == className)
1254                 {
1255 chuck 1.3         PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"wildcard and = FROM");
1256                   PEG_METHOD_EXIT();
1257 chuck 1.2         return true;
1258                 }
1259           
1260                 // Add all the properties on the FROM class to
1261                 // the required property list.
1262                 CIMClass fromClass = _ctx->getClass(fromClassName);
1263                 for (Uint32 n = 0; n < fromClass.getPropertyCount(); n++)
1264                 {
1265                   // Add to the required property list if not already there.
1266                   if (!containsProperty(fromClass.getProperty(n).getName(), reqProps))
1267                   {  
1268                     reqProps.append(fromClass.getProperty(n).getName());
1269                   }        
1270                 }
1271           
1272 chuck 1.3       PEG_METHOD_EXIT();
1273 chuck 1.2       return false;
1274               }
1275           
1276               // Implementation note:
1277               // Since this API assumes that the class passed in
1278               // is the FROM class or a subclass of the FROM class,
1279               // AND validateProperties can be called to check if
1280               // unscoped properties are on the FROM class, 
1281               // we can just add the required property because
1282               // it is assumed to be on the FROM class.
1283           
1284               // Add to the required property list if not already there.
1285               if (!containsProperty(ids[1].getName(), reqProps))
1286               {  
1287                 reqProps.append(ids[1].getName());
1288               }
1289             }
1290             
1291             // Indicate the required property is not a wildcard
1292 chuck 1.3   PEG_METHOD_EXIT();
1293 chuck 1.2   return false;
1294           }
1295           
1296           Array<CQLChainedIdentifier> CQLSelectStatementRep::getSelectChainedIdentifiers()
1297           {
1298 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::getSelectChainedIdentifiers");
1299           
1300 chuck 1.2   if (!_contextApplied)
1301               applyContext();
1302           
1303 chuck 1.3   PEG_METHOD_EXIT();
1304           
1305 chuck 1.2   return _selectIdentifiers;
1306           }
1307           
1308           Array<CQLChainedIdentifier> CQLSelectStatementRep::getWhereChainedIdentifiers()
1309           {
1310 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::getWhereChainedIdentifiers");
1311           
1312             if(_ctx == NULL)
1313             {
1314               PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"null QC");
1315               PEG_METHOD_EXIT();
1316 chuck 1.2     MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL",
1317                                        "Trying to process a query with a NULL Query Context.");
1318               throw CQLRuntimeException(parms);
1319             }
1320           
1321             if (!_contextApplied)
1322               applyContext();
1323           
1324             Array<QueryChainedIdentifier> qChainIds = _ctx->getWhereList();
1325             Array<CQLChainedIdentifier> cqlChainIds;
1326             for (Uint32 i = 0; i < qChainIds.size(); i++)
1327             {
1328               Array<QueryIdentifier> qSubs = qChainIds[i].getSubIdentifiers();
1329               CQLChainedIdentifier cqlChainId;
1330               for (Uint32 j = 0; j < qSubs.size(); j++)
1331               {
1332                 cqlChainId.append(qSubs[j]);
1333               }
1334           
1335               cqlChainIds.append(cqlChainId);
1336             }
1337 chuck 1.2 
1338 chuck 1.3   PEG_METHOD_EXIT();
1339           
1340 chuck 1.2   return cqlChainIds;
1341           }
1342           
1343           Boolean CQLSelectStatementRep::containsProperty(const CIMName& name,
1344                                                           const Array<CIMName>& props) 
1345           {
1346 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::containsProperty");
1347           
1348 chuck 1.2   for (Uint32 i = 0; i < props.size(); i++)
1349             {
1350               if (props[i] == name)
1351               {
1352 chuck 1.3       PEG_METHOD_EXIT();
1353 chuck 1.2       return true;
1354               }
1355             }
1356           
1357 chuck 1.3   PEG_METHOD_EXIT();
1358 chuck 1.2   return false;
1359           }
1360           
1361           void CQLSelectStatementRep::appendClassPath(const CQLIdentifier& inIdentifier)
1362           {
1363 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::appendClassPath");
1364           
1365             if(_ctx == NULL)
1366             {
1367               PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"null QC");
1368               PEG_METHOD_EXIT();
1369 chuck 1.2     MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL",
1370                                        "Trying to process a query with a NULL Query Context.");
1371 chuck 1.4     throw QueryValidationException(parms);
1372 chuck 1.2   }
1373             _ctx->insertClassPath(inIdentifier);
1374 chuck 1.3 
1375             PEG_METHOD_EXIT();
1376 chuck 1.2 }
1377           
1378           void CQLSelectStatementRep::setPredicate(const CQLPredicate& inPredicate)
1379           {
1380 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::setPredicate");
1381 chuck 1.2   _predicate = inPredicate;
1382 chuck 1.3   PEG_METHOD_EXIT();
1383 chuck 1.2 }
1384           
1385           CQLPredicate CQLSelectStatementRep::getPredicate() const
1386           {
1387 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::getPredicate");
1388 chuck 1.2   return _predicate;
1389           }
1390           
1391           void CQLSelectStatementRep::insertClassPathAlias(const CQLIdentifier& inIdentifier,
1392                                                            String inAlias)
1393           {
1394 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::insertClassPathAlias");
1395           
1396             if(_ctx == NULL)
1397             {
1398               PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"null QC");
1399               PEG_METHOD_EXIT();
1400 chuck 1.2     MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL",
1401                                        "Trying to process a query with a NULL Query Context.");
1402 chuck 1.4     throw QueryValidationException(parms);
1403 chuck 1.2   }
1404             _ctx->insertClassPath(inIdentifier,inAlias);
1405 chuck 1.3 
1406             PEG_METHOD_EXIT();
1407 chuck 1.2 }
1408           
1409           void CQLSelectStatementRep::appendSelectIdentifier(const CQLChainedIdentifier& x)
1410           {
1411 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::appendSelectIdentifier");
1412 chuck 1.2   _selectIdentifiers.append(x);
1413 chuck 1.3   PEG_METHOD_EXIT();  
1414 chuck 1.2 }
1415           
1416           void CQLSelectStatementRep::applyContext()
1417           {
1418 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::applyContext");
1419           
1420             if(_ctx == NULL)
1421             {
1422               PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"null QC");
1423               PEG_METHOD_EXIT();
1424 chuck 1.2     MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL",
1425                                        "Trying to process a query with a NULL Query Context.");
1426 chuck 1.4     // throw syntax error to be consistent
1427               throw CQLSyntaxErrorException(parms);
1428 chuck 1.2   }
1429           
1430             for (Uint32 i = 0; i < _selectIdentifiers.size(); i++)
1431             {
1432               _selectIdentifiers[i].applyContext(*_ctx);
1433               checkWellFormedIdentifier(_selectIdentifiers[i], true);
1434             }
1435           
1436             if (hasWhereClause())
1437             {
1438               _predicate.applyContext(*_ctx);
1439           
1440               // Note: must be after call to predicate's applyContext
1441               Array<QueryChainedIdentifier> _whereIdentifiers = _ctx->getWhereList();
1442               for (Uint32 i = 0; i < _whereIdentifiers.size(); i++)
1443               {
1444                 checkWellFormedIdentifier(_whereIdentifiers[i], false);
1445               }
1446             }
1447           
1448             _contextApplied = true;
1449 chuck 1.3   PEG_METHOD_EXIT();
1450 chuck 1.2 }
1451           
1452           void CQLSelectStatementRep::checkWellFormedIdentifier(const QueryChainedIdentifier& chainId,
1453                                                                 Boolean isSelectListId)
1454           {
1455 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::checkWellFormedIdentifier");
1456           
1457 chuck 1.2   // This function assumes that applyContext has been called.
1458             Array<QueryIdentifier> ids = chainId.getSubIdentifiers();
1459           
1460             if (ids.size() == 0)
1461             {
1462 chuck 1.3     PEG_METHOD_EXIT();
1463 chuck 1.2     MessageLoaderParms parms("CQL.CQLSelectStatementRep.EMPTY_CHAIN",
1464                                        "An empty chained identifier was found.");
1465               throw CQLSyntaxErrorException(parms);
1466             }
1467           
1468 chuck 1.3   PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"chain =" + chainId.toString());
1469           
1470 chuck 1.2   if (ids.size() == 1 && isSelectListId)
1471             {
1472               // Single element chain ids are not allow in the select list.
1473               // The select list can only have properties.
1474 chuck 1.3     PEG_METHOD_EXIT();
1475 chuck 1.2     MessageLoaderParms parms("CQL.CQLSelectStatementRep.SINGLE_CHID_IN_SELECT",
1476                                        "A property on the FROM class must be selected.");
1477               throw CQLSyntaxErrorException(parms);
1478             }
1479           
1480             if (ids[0].isScoped()
1481                 || ids[0].isWildcard()
1482                 || ids[0].isSymbolicConstant() 
1483                 || ids[0].isArray())
1484             {
1485               // The first identifier must be a classname (it could be the FROM class, or
1486               // some other class for the right side of ISA)
1487 chuck 1.3     PEG_METHOD_EXIT();
1488 chuck 1.2     MessageLoaderParms parms("CQL.CQLSelectStatementRep.FIRST_ID_ILLEGAL",
1489                                        "The chained identifier $0 is illegal.",
1490                                        chainId.toString());
1491               throw CQLSyntaxErrorException(parms);
1492             }
1493              
1494             Uint32 startingPos = 1;
1495             for (Uint32 pos = startingPos; pos < ids.size(); pos++)
1496             {  
1497               if (ids[pos].isArray() && isSelectListId)
1498               {
1499 chuck 1.3       PEG_METHOD_EXIT();
1500 chuck 1.2       MessageLoaderParms parms("CQL.CQLSelectStatementRep.ARRAY_IN_SELECT",
1501                                        "The identifier $0 of $1 in the SELECT list cannot use an array index.",
1502                                        ids[pos].toString(), chainId.toString());
1503                 throw CQLSyntaxErrorException(parms);
1504               }
1505           
1506               if (ids[pos].isSymbolicConstant() && isSelectListId)
1507               {
1508 chuck 1.3       PEG_METHOD_EXIT();
1509 chuck 1.2       MessageLoaderParms parms("CQL.CQLSelectStatementRep.SYMCONST_IN_SELECT",
1510                                        "The identifier $0 of $1 in the SELECT list cannot use a symbolic constant.",
1511                                        ids[pos].toString(), chainId.toString());
1512                 throw CQLSyntaxErrorException(parms);
1513               }
1514           
1515               if (ids[pos].isSymbolicConstant() && pos != (ids.size() -1))
1516               {
1517 chuck 1.3       PEG_METHOD_EXIT();
1518 chuck 1.2       MessageLoaderParms parms("CQL.CQLSelectStatementRep.SYMCONST_NOT_LAST",
1519                                        "The symbolic constant identifier $0 of $1 must be the last element.",
1520                                        ids[pos].toString(), chainId.toString());
1521                 throw CQLSyntaxErrorException(parms);
1522               }
1523           
1524               if (ids[pos].isWildcard())
1525               {
1526                 if ( !isSelectListId)
1527                 {
1528 chuck 1.3         PEG_METHOD_EXIT();
1529 chuck 1.2         MessageLoaderParms parms("CQL.CQLSelectStatementRep.WILD_IN_WHERE",
1530                                        "The identifier $0 of $1 in the WHERE list cannot use a wildcard.",
1531                                        ids[pos].toString(), chainId.toString());
1532                   throw CQLSyntaxErrorException(parms);
1533                 }
1534           
1535                 if ( pos != ids.size() - 1)
1536                 {
1537 chuck 1.3         PEG_METHOD_EXIT();
1538 chuck 1.2         MessageLoaderParms parms("CQL.CQLSelectStatementRep.WILD_NOT_END",
1539                                        "The wildcard identifier $0 of $1 must be the last element.",
1540                                        ids[pos].toString(), chainId.toString());
1541                   throw CQLSyntaxErrorException(parms);
1542                 }
1543               }
1544           
1545               if (pos > startingPos && !ids[pos].isWildcard())
1546               {
1547                 if (!ids[pos].isScoped())
1548                 {
1549 chuck 1.3         PEG_METHOD_EXIT();
1550 chuck 1.2         MessageLoaderParms parms("CQL.CQLSelectStatementRep.EMB_PROP_NOT_SCOPED",
1551                                        "The identifier $0 of $1 must use the scope operator.",
1552                                        ids[pos].toString(), chainId.toString());
1553                   throw CQLSyntaxErrorException(parms);
1554                 }
1555               }
1556             }
1557 chuck 1.3 
1558             PEG_METHOD_EXIT();
1559 chuck 1.2 }
1560           
1561           void CQLSelectStatementRep::normalizeToDOC()
1562           {
1563 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::normalizeToDOC");
1564           
1565 chuck 1.2   if (!_contextApplied)
1566               applyContext();
1567           
1568             if(_hasWhereClause){
1569               Cql2Dnf DNFer(_predicate);
1570               _predicate = DNFer.getDnfPredicate(); 
1571             }
1572 chuck 1.3 
1573             PEG_METHOD_EXIT();
1574 chuck 1.2 }
1575           
1576           String CQLSelectStatementRep::toString()
1577           {
1578 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::toString");
1579           
1580             if(_ctx == NULL)
1581             {
1582               PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"null QC");
1583               PEG_METHOD_EXIT();
1584               MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL",
1585                                        "Trying to process a query with a NULL Query Context.");
1586               throw CQLRuntimeException(parms);
1587             }
1588           
1589             String s("SELECT ");
1590             for(Uint32 i = 0; i < _selectIdentifiers.size(); i++){
1591               if((i > 0) && (i < _selectIdentifiers.size()))
1592               {
1593                 s.append(",");
1594               }
1595               s.append(_selectIdentifiers[i].toString());
1596             }       
1597           
1598             s.append(" ");
1599 chuck 1.3   s.append(_ctx->getFromString());
1600           
1601             if(_hasWhereClause){
1602               s.append(" WHERE ");
1603               s.append(_predicate.toString());
1604             }
1605 chuck 1.2 
1606 chuck 1.3   PEG_METHOD_EXIT();
1607             return s;
1608 chuck 1.2 }
1609           
1610           void CQLSelectStatementRep::setHasWhereClause()
1611           {
1612 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::setHasWhereClause");
1613             _hasWhereClause = true;
1614             PEG_METHOD_EXIT();
1615 chuck 1.2 }
1616           
1617           Boolean CQLSelectStatementRep::hasWhereClause()
1618           {
1619 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::hasWhereClause");
1620             return _hasWhereClause;
1621 chuck 1.2 }
1622           
1623           void  CQLSelectStatementRep::clear()
1624           {
1625 chuck 1.3   PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::clear");
1626           
1627           	if(_ctx == NULL)
1628              {
1629                PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"null QC");
1630                PEG_METHOD_EXIT();
1631 chuck 1.2      MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL",
1632                                         "Trying to process a query with a NULL Query Context.");
1633                throw CQLRuntimeException(parms);
1634             	}
1635           
1636              _ctx->clear();
1637              _hasWhereClause = false;
1638              _contextApplied = false;
1639              _predicate = CQLPredicate();
1640              _selectIdentifiers.clear();
1641 chuck 1.3 
1642              PEG_METHOD_EXIT();
1643 chuck 1.2 }
1644           
1645           PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2