Exemplo n.º 1
0
/**
 * Replace the query with its query descriptor text.
 * The MVQR_LOG_QUERY_DESCRIPTORS CQD was set to 'DUMP', so instead of running
 * this query, we are going to replace it with something that, when executed,
 * will produce the XML text of the query descriptor as its output. This
 * 'something' is a TupleList node that has the text lines of the descriptor 
 * as its tuples.
 * 
 * @param rootExpr The RelExpr tree of the existing query
 * @param xmlText The XML text of the query descriptor
 */
RelRoot* MvQueryRewriteHandler::handleAnalyzeOnlyQuery(RelRoot* rootExpr, NAString* xmlText)
{
  static NAString empty("No descriptor generated.");
  if (xmlText==NULL)
    xmlText = ∅
    
  CollHeap *heap = CmpCommon::statementHeap();
  Int32 maxLen=xmlText->length();
  Int32 pos=0;
  Int32 lastPos=-1;
  ItemExpr* tupleExpr = NULL;  
  
  while (pos<maxLen-1)
  {
    // Find the next CR character
    pos = xmlText->index("\n", 1, pos+1, NAString::exact);
    if (pos==-1) // If this is the last line with no CR.
      pos=maxLen;

    // The next line if from the last CR to this one.
    NASubString line=(*xmlText)(lastPos+1, pos-lastPos-1);
    lastPos=pos;

    // Make a constant character string from it.
    ItemExpr* tuple = new (heap) 
      Convert(new(heap) SystemLiteral(line));
    
    // Collect the tuples in a list
    if (tupleExpr==NULL)
      tupleExpr = tuple;
    else
      tupleExpr = new(heap) ItemList(tuple, tupleExpr);    
  }

  // Construct the TupleList node
  TupleList* tupleListNode = new(heap) TupleList(tupleExpr->reverseTree(), heap); 
  RelRoot* newRoot = new(heap) RelRoot(tupleListNode);
  
  // A RenameTable above it to give a name to the column of text.
  ItemExpr *renExpr = new(heap) 
    RenameCol(NULL, new(heap) ColRefName("Query Descriptor", heap));
  NAString tableName("Descriptor table");
  RelExpr* renameNode = new(heap) 
    RenameTable(TRUE, newRoot, tableName, renExpr, heap);
  
  // And a final RelRoot on top with a SELECT *.
  ItemExpr *starExpr = new(heap) ColReference(new(heap) ColRefName(1));
  RelRoot* topRoot = new(heap) RelRoot(renameNode, REL_ROOT, starExpr);
  topRoot->setRootFlag(TRUE);
  
  // Now bind the new query tree
  BindWA* bindWA = rootExpr->getRETDesc()->getBindWA();
  RelExpr* boundRoot = topRoot->bindNode(bindWA);

  // Transform it. This will eliminate the Rename node and the extraneous root.
  NormWA normWA(CmpCommon::context());
  ExprGroupId eg(boundRoot);
  boundRoot->transformNode(normWA, eg);

  // And Normalize it.
  RelRoot *normRoot = (RelRoot *)eg.getPtr();
  normRoot->normalizeNode(normWA);
  
  return normRoot;
}