/**********************************************************************
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
**********************************************************************/
/* -*-C++-*-
******************************************************************************
*
* File:         RelCache.cpp
* Description:  All the RelExpr methods introduced by query caching
* Created:      2/23/2001
* Language:     C++
*
*
******************************************************************************
*/
#include "AllRelExpr.h"
#include "CacheWA.h"
#include "CmpMain.h"
#include "GroupAttr.h"
#include "OptHints.h"
#include "QRDescGenerator.h"
#include "HDFSHook.h"

// append an ascii-version of GenericUpdate into cachewa.qryText_
void GenericUpdate::generateCacheKey(CacheWA& cwa) const
  // NB: This comment applies to all generateCacheKey methods. 
  // generateCacheKey is used to generate a string representation s of the
  // "parameterized" query. Since this string s is used by QCache::lookUp
  // to determine if a query is in the cache, it is essential that:
  //   (1) two different queries have different string representations
  //   (2) two queries that differ only in their query literals should
  //       have the same string representations
  // One possible implementation of generateCacheKey is to use the query's
  // original query text. But, original query text does not satisfy (2). 
  // To get (2), we call generateCacheKey() from RelRoot::normalizeForCache
  // which, by definition, replaced query literals with constant parameters.
  // However, generateCacheKey must also satisfy (1). generateCacheKey must
  // generate two different strings for two logically different queries.
  //
  // To satisfy requirements (1) and (2), generateCacheKey and
  // normalizeForCache must be in sync -- every user-specified expr that 
  // generateCacheKey emits into cwa.qryText_ must be examined by 
  // normalizeForCache for possible replacement of any literal there into 
  // a constant parameter. 
  //
  // In order for the literal-into-constantparameter replacement to be safe,
  // isCacheableExpr must visit all user-specified exprs to make sure that
  // only constants that can be safely cast into the query's target types
  // are considered cacheable. For example, given this update query
  //   update t set a = 'xyz' where pk = 1;
  // isCacheableeExpr, normalizeForCache, and generateCacheKey must cooperate
  // so that:
  // 1) isCacheableExpr rejects the query as noncacheble if 'xyz' cannot be
  //    safely cast into a's target type, eg, 'xyz' may be too long if a's
  //    type is char(1).
  // 2) normalizeForCache must visit and replace both 'xyz' and 1 with
  //    appropriate constant parameters.
  // 3) generateCacheKey must emit some string representation of the
  //    parameterized query, eg, "update t set a = % where pk = %".
  //    generateCacheKey can emit more stuff, eg, internally specified
  //    begin/end-key predicates, but it must emit a string representation
  //    of all user-specified parts of the query.
{
  // append to cwa.qryText_ GenericUpdate's "essential" data members
  RelExpr::generateCacheKey(cwa);
  // An extension of the fix to 10-010618-3505, 10-010619-3515: 
  // for "after bind" Insert/Update/Delete queries, include table's 
  // RedefTime into cwa.qryText_ to make sure we get a cache hit only on 
  // query that reference table(s) that have not changed since the query's 
  // addition to the cache. The queries that reference altered table(s) 
  // will never be hit again and will eventually age out of the cache.
  // This is not strictly necessary, but it speeds up the processing
  // of insert/update/delete queries on altered tables.
  const NATable *tbl;
  if (cwa.getPhase() >= CmpMain::BIND && 
      getTableDesc() && (tbl=getTableDesc()->getNATable()) != NULL) {
    char redefTime[40];
    convertInt64ToAscii(tbl->getRedefTime(), redefTime);
    cwa += " redef:";
    cwa += redefTime;
  }
  ItemExpr *newExpr = newRecExprTree_ ? newRecExprTree_ :
    newRecExpr_.rebuildExprTree(ITM_ITEM_LIST);
  if (newExpr) { 
    cwa += " newRecExpr:"; 
    newExpr->generateCacheKey(cwa); 
  }
  // make sure cache key can distinguish these 2 queries:
  // prepare s from select * from (update t042qT8 set b=7 where a=2) as t;
  // prepare s from select * from (update t042qT8 set b=7 set on rollback c=2 
  //                               where a=2) as t;
  ItemExpr *setOnRollback;
  if (newRecBeforeExpr_.entries() > 0 &&
      (setOnRollback=newRecBeforeExpr_.rebuildExprTree(ITM_ITEM_LIST))) {
    cwa += " setOnRollback:"; 
    setOnRollback->generateCacheKey(cwa); 
  }
  ItemExpr *execPred = executorPredTree_ ? executorPredTree_ :
    executorPred_.rebuildExprTree();
  if (execPred) { 
    cwa += " execPred:"; 
    execPred->generateCacheKey(cwa); 
  }

  // MVs --
  // The NOLOG parameter is essential.
  if (isNoLogOperation()) { 
    cwa += " NOLOG"; 
  }

  // "current of cursor/hostvar" is essential
  if (currOfCursorName_) {
    currOfCursorName_->generateCacheKey(cwa); 
  }

  // not sure if the following are essential, but better to be safe & 
  // slightly inefficient than to deliver a false hit (ie, wrong plan)
  cwa += mtsStatement_ ? "m1" : "m0";
  cwa += noFlow_ ? "n1" : "n0";
  cwa += noRollback_ ? "o1" : "o0";
  cwa += noCheck_ ? "nc" : "dc";

  // not sure if the following are essential, but we don't know how
  // to quickly & cheaply include them into our cachekey:
  //   updatedTableName_, tabId_, updateToSelectMap_, indexDesc_,
  //   newRecExprArray_, usedColumns_, newRecBeforeExpr_,
  //   newRecBeforeExprArray_, usedBeforeColumns_, potentialOutputs_
  //   indexNumberArray_, scanIndexDesc_, rowsAffected_, stoi_,
  //   oldToNewMap_

  // The following data members are not "essential" to generateCacheKey
  // (at least "after bind") because they are either covered by other
  // data members (eg, beginKeyPred and endKeyPred_ are covered by the
  // selection pred in RelExpr) or they are not yet defined until later
  // (eg, after the optimize phase):
  //   indexNewRecExprArrays_, beginKeyPred_, endKeyPred_,
  //   pathKeys_, partKeys_, indexBeginKeyPredArray_,
  //   indexEndKeyPredArray_, checkConstraints_
}

// is this entire expression cacheable after this phase?
NABoolean GenericUpdate::isCacheableExpr(CacheWA& cwa)
{
  // descend to scans early to get cwa.numberOfScans_ 
  if (!RelExpr::isCacheableExpr(cwa)) {
    return FALSE;
  }

  // Make "{update|delete} ... where current of cursor" non-cacheable
  // so that stale cache will not lead to timestamp mismatch error at
  // runtime.  AQR attempts to handle this error, but only after the 
  // referenced cursor is closed due to transaction rollback.  This is
  // Solution 10-100425-9755.
  if (currOfCursorName()) { 
    return FALSE; 
  }

  if (cwa.getPhase() >= CmpMain::BIND) {
    // make sure any literals in the assignment clause can be safely
    // cast and assigned to their target types at plan-backpatch-time
    ItemExpr *newExpr = newRecExprTree_ ? newRecExprTree_ :
      newRecExpr_.rebuildExprTree(ITM_ITEM_LIST);
    if (newExpr && !newExpr->isSafelyCoercible(cwa)) { 
      return FALSE; 
    }
    // reject as non-cacheable queries such as
    //   prepare s from select * from (update t042qT8 set b=7 
    //   set on rollback c=12345678901234567890 where a=2) as t;
    ItemExpr *setOnRollback;
    if (newRecBeforeExpr_.entries() > 0 &&
        (setOnRollback=newRecBeforeExpr_.rebuildExprTree(ITM_ITEM_LIST)) 
        && !setOnRollback->isSafelyCoercible(cwa)) {
      return FALSE; 
    }
    // make sure any executor predicate is cacheable
    ItemExpr *execPred = executorPredTree_ ? executorPredTree_ :
      executorPred_.rebuildExprTree();
    if (execPred) {
      cwa.setHasPredicate();
      if (execPred->hasNoLiterals(cwa)) {
        // predicate with no literals is cacheable
      }
      else {
        cwa.setPredHasNoLit(FALSE);
        return execPred->isCacheableExpr(cwa);
      }
    }

    // at this time, not cacheable if subquery is specified in 
    // UPDATE SET clause.
    // This could be enabled later.
    if (subqInUpdateAssign()) {
      return FALSE;
    }
  }
  else {
    if ((getTableName().isPartitionNameSpecified()) ||
	(getTableName().isLocationNameSpecified()) ||
	(getTableName().isPartitionRangeSpecified()))
      return FALSE; // If PartnClause is used no cache hit before bind stage.
  }
  return TRUE; // may be cacheable
}

RelExpr* Scan::normalizeForCache(CacheWA& cwa, BindWA& bindWA)
{
  if (nodeIsNormalizedForCache()) { 
    return this; 
  }

  if (CmpCommon::getDefault(QUERY_CACHE_TABLENAME) == DF_OFF) {
    // replace descendants' literals into ConstantParameters
    return RelExpr::normalizeForCache(cwa, bindWA);
  }

  // replace tablename with a prototyped tablename.
  TableDesc * td = getTableDesc();
  CorrName &origName = td->getCorrNameObj();
  if (origName.getPrototype() == NULL)
    {
      Lng32 CACHED_MAX_ANSI_NAME_EXTERNAL_LEN = 128;
      NAString hvName("dummy_name");
      HostVar * hv = 
	new(bindWA.wHeap()) 
	HostVar(hvName, 
		new(bindWA.wHeap()) SQLChar(bindWA.wHeap(), CACHED_MAX_ANSI_NAME_EXTERNAL_LEN));
      hv->setPrototypeValue(origName.getQualifiedNameAsString());
      hv->synthTypeAndValueId();
      hv->setIsCachedParam(TRUE);

      CorrName cn("HostVar$", 
		  bindWA.wHeap(),
		  hv->getName(),   // debugging ease
		  "$bogus");

      cn.setPrototype(hv);
      NAString *tmpName =
	new (bindWA.wHeap()) 
	NAString(hv->getPrototypeValue(), bindWA.wHeap());
      cn.setUgivenName(*tmpName);
      cn.applyDefaults(&bindWA, bindWA.getDefaultSchema());

      td->setCorrName(cn);
      setTableName(cn);

      char * strval = 
	new(bindWA.wHeap()) char[CACHED_MAX_ANSI_NAME_EXTERNAL_LEN];
      strcpy(strval, origName.getQualifiedNameAsString().data());
      CharType * typ = 
	new(bindWA.wHeap()) SQLChar(bindWA.wHeap(), CACHED_MAX_ANSI_NAME_EXTERNAL_LEN, FALSE);
      ConstValue * cv = 
	new(bindWA.wHeap()) ConstValue(typ, strval, CACHED_MAX_ANSI_NAME_EXTERNAL_LEN);

      ConstantParameter* result = new(bindWA.wHeap()) ConstantParameter
	(*cv, bindWA.wHeap(), cwa.getPhase() == CmpMain::PARSE);
      result->synthTypeAndValueId();
      cwa.addConstParam(result, bindWA);
      hv->setPMOrdPosAndIndex(COM_UNKNOWN_DIRECTION,
			      -1,
			      (Int32)cwa.getConstParams().entries());
    }

  // replace descendants' literals into ConstantParameters
  return RelExpr::normalizeForCache(cwa, bindWA);
}

// change literals of a cacheable query into ConstantParameters 
RelExpr* GenericUpdate::normalizeForCache(CacheWA& cwa, BindWA& bindWA)
{
  if (nodeIsNormalizedForCache()) { 
    return this; 
  }
  if (cwa.getPhase() >= CmpMain::BIND) {
    if (currOfCursorName_) {
      // do NOT parameterize the assignment clause(s) of positioned updates
      // because "update t051t22 set b = -1 where current of c1" in esqlc
      // program such as core/etest051.sql generates an assertion clause:
      // "...if_then_else(b= :hv0),return_true,return_true(raiserror())"
      // (see BindItemExpr.cpp Scan::bindUpdateCurrentOf) as part of
      // GenericUpdate::bindNode. Otherwise, the result is an error 8106.
      // The root cause is incomplete parameterization -- the update 
      // becomes "update t051t22 set b = 0-? where current of c1" but 
      // "...if_then_else(b= :hv0),return_true,return_true(raiserror())"
      // is untouched causing an error 8106 at runtime.
    }
    else {
      if (newRecExprTree_) {
        newRecExprTree_->normalizeForCache(cwa, bindWA);
      }
      else {
        newRecExpr_.normalizeForCache(cwa, bindWA);
      }
      // parameterize "set on rollback" clause for queries such as
      //   prepare s from select * from (update t042qT8 set b=7 
      //   set on rollback c=2 where a=2) as t;
      newRecBeforeExpr_.normalizeForCache(cwa, bindWA); 
    }
    if (executorPredTree_) {
      executorPredTree_->normalizeForCache(cwa, bindWA);
    }
    else {
      executorPred_.normalizeForCache(cwa, bindWA);
    }
  }

  // Solution: 10-060327-5370 and 10-060418-5903
  // Record the context-wide isolation_level_for_updates value in 
  // CacheWA when procssing an IDU stmt. Use ISOLATION_LEVEL_FOR_UPDATES 
  // if it is specified. Otherwise, use ISOLATION_LEVEL. The initial value
  // in cwa is IL_NOT_SPECIFIED_.
  if ( cwa.getIsoLvlForUpdates() == TransMode::IL_NOT_SPECIFIED_ ) {
    TransMode::IsolationLevel il;

    ActiveSchemaDB()->getDefaults().getIsolationLevel (il,
         CmpCommon::getDefault(ISOLATION_LEVEL_FOR_UPDATES));

    if ( il == TransMode::IL_NOT_SPECIFIED_ ) {
       ActiveSchemaDB()->getDefaults().getIsolationLevel (il,
            CmpCommon::getDefault(ISOLATION_LEVEL));
    }
    cwa.setIsoLvlForUpdates(il);
  }

  // replace descendants' literals into ConstantParameters
  return RelExpr::normalizeForCache(cwa, bindWA);
}

// append an ascii-version of IsolatedScalarUDF into cachewa.qryText_
void IsolatedScalarUDF::generateCacheKey(CacheWA &cwa) const
{
  NARoutine *routine = NULL;
  NARoutine *action = NULL;

  RelExpr::generateCacheKey(cwa);

  cwa += " UDFname:";
  cwa += getRoutineName().getQualifiedNameAsAnsiString().data();
  if (cwa.getPhase() >= CmpMain::BIND &&
      getRoutineDesc() &&
      (routine=getRoutineDesc()->getNARoutine()) != NULL)
  {
    char redefTime[40];
    convertInt64ToAscii(routine->getRedefTime(), redefTime);
    cwa += " redef:";
    cwa += redefTime;
  }

  if (getRoutineDesc() != NULL && getRoutineDesc()->isUUDFRoutine())
  {
    cwa += " action:";
    cwa += getRoutineDesc()->getActionNameAsGiven();

    if (cwa.getPhase() >= CmpMain::BIND &&
       getRoutineDesc() &&
       (action=getRoutineDesc()->getActionNARoutine()) != NULL)
    {
       char redefTime[40];
       convertInt64ToAscii(action->getRedefTime(), redefTime);
       cwa += " actredef:";
       cwa += redefTime;
    }
  }

  const ItemExpr *paramExpr = (getProcAllParamsTree() == NULL) ? 
                      getProcInputParamsVids().rebuildExprTree(ITM_ITEM_LIST) :
                      getProcAllParamsTree(); 
  if (paramExpr)
  { 
    cwa += " arg:(";
    paramExpr->generateCacheKey(cwa); 
    cwa += ")";
  }
}

// append an ascii-version of CallSP into cachewa.qryText_
void CallSP::generateCacheKey(CacheWA &cwa) const
{
  RelExpr::generateCacheKey(cwa);

  cwa += " CallSPname:";
  cwa += getRoutineName().getQualifiedNameAsAnsiString().data();

  const ItemExpr *paramExpr = (getProcAllParamsTree() == NULL) ? 
                      getProcInputParamsVids().rebuildExprTree(ITM_ITEM_LIST) :
                      getProcAllParamsTree(); 
  if (paramExpr)
  { 
    cwa += " arg:";
    paramExpr->generateCacheKey(cwa); 
  }
}

// append an ascii-version of GroupByAgg into cachewa.qryText_
void GroupByAgg::generateCacheKey(CacheWA &cwa) const
{
  RelExpr::generateCacheKey(cwa);

  // group by col/expr is an important part of the key
  ItemExpr *grpExpr = groupExprTree_ ? groupExprTree_ :
    groupExpr_.rebuildExprTree(ITM_ITEM_LIST);
  if (grpExpr) { 
    cwa += " gBy:"; 

    if (isRollup())
      {
        cwa += " roll:";

        ItemExpr * ie = rollupGroupExprList().rebuildExprTree(ITM_ITEM_LIST);
        if (ie)
          {
            ie->generateCacheKey(cwa);
          }
      }
    if (NOT extraOrderExpr().isEmpty() )
    {
        cwa += " extraOrder:";

        ItemExpr * ie = extraOrderExpr().rebuildExprTree(ITM_ITEM_LIST);
        if (ie)
          {
            ie->generateCacheKey(cwa);
          }
    }

    grpExpr->generateCacheKey(cwa); 
  }
}


// is this entire expression cacheable after this phase?
NABoolean GroupByAgg::isCacheableExpr(CacheWA& cwa)
{
  // descend to scans early to get cwa.numberOfScans_ 
  if (!RelExpr::isCacheableExpr(cwa)) {
    return FALSE;
  }
  // is the group by col/expr cacheable?
  ItemExpr *grpExpr = groupExprTree_ ? groupExprTree_ :
    groupExpr_.rebuildExprTree(ITM_ITEM_LIST);
  if (grpExpr && !grpExpr->isCacheableExpr(cwa)) { 
    return FALSE; 
  }
  return TRUE; // may be cacheable
}

// append an ascii-version of Insert into cachewa.qryText_
void Insert::generateCacheKey(CacheWA &cwa) const
{
  GenericUpdate::generateCacheKey(cwa);
  if (insertColTree_) { 
    cwa += " insCol:"; 
    insertColTree_->generateCacheKey(cwa); 
  }
  // order by clause is important
  ItemExpr *orderBy = orderByTree_ ? orderByTree_ :
    reqdOrder_.rebuildExprTree();
  if (orderBy) { 
    cwa += " order:"; 
    orderBy->generateCacheKey(cwa); 
  }

  const NATable *tbl;
  if (cwa.getPhase() >= CmpMain::BIND && 
      getTableDesc() && (tbl=getTableDesc()->getNATable()) != NULL) {
    // If PARTITION clause has been used we must reflect that in the key.
    if (tbl->isPartitionNameSpecified()) {
      cwa += " partition:";
      cwa += tbl->getClusteringIndex()->getFileSetName().getQualifiedNameAsString().data();
    }
    // If PARTITION range has been used we must reflect that in the key.
    else if (tbl->isPartitionRangeSpecified()) {
      cwa += " partition:";

      char str[100];
      sprintf(str, " from %d to %d", 
	      tbl->getExtendedQualName().getPartnClause().getBeginPartitionNumber() ,
	      tbl->getExtendedQualName().getPartnClause().getEndPartitionNumber());
      cwa += str;
    }
  }

  if (isUpsert())
    {
      cwa += " upsert:";
    }
}

// is this entire expression cacheable after this phase?
NABoolean Insert::isCacheableExpr(CacheWA& cwa)
{
  // non-single-row inserts are non-cacheable 
  if (insertType_ != SIMPLE_INSERT) { 
    return FALSE; 
  }
  // single-row insert may be cacheable
  return GenericUpdate::isCacheableExpr(cwa);
}

// change literals of a cacheable query into ConstantParameters 
RelExpr* Insert::normalizeForCache(CacheWA& cwa, BindWA& bindWA)
{
  if (nodeIsNormalizedForCache()) { 
    return this; 
  }
  // replace descendants' literals into ConstantParameters
  return GenericUpdate::normalizeForCache(cwa, bindWA);
}

// is this entire expression cacheable after this phase?
NABoolean Delete::isCacheableExpr(CacheWA& cwa)
{
  return GenericUpdate::isCacheableExpr(cwa);
}

// append an ascii-version of Merge into cachewa.qryText_
void MergeUpdate::generateCacheKey(CacheWA &cwa) const
{
  Update::generateCacheKey(cwa);

  if (insertCols_) { 
    cwa += " insertCols:"; 
    insertCols_->generateCacheKey(cwa); 
  }

  if (insertValues_) { 
    cwa += " insertValues:"; 
    insertValues_->generateCacheKey(cwa); 
  }
}

// is this entire expression cacheable after this phase?
NABoolean MergeUpdate::isCacheableExpr(CacheWA& cwa)
{
  if ((insertValues_) &&
      (insertValues_->isCacheableExpr(cwa))) {
    setNonCacheable();
    return FALSE;
  }

  return Update::isCacheableExpr(cwa);
}

// change literals of a cacheable query into ConstantParameters 
RelExpr* MergeUpdate::normalizeForCache(CacheWA& cwa, BindWA& bindWA)
{
  if (nodeIsNormalizedForCache()) { 
    return this; 
  }

  if (insertValues_) {
    insertValues_ = insertValues_->normalizeForCache(cwa, bindWA);
  }

  // replace descendants' literals into ConstantParameters
  return Update::normalizeForCache(cwa, bindWA);
}

// append an ascii-version of Merge into cachewa.qryText_
void MergeDelete::generateCacheKey(CacheWA &cwa) const
{
  Delete::generateCacheKey(cwa);

  if (insertCols_) { 
    cwa += " insertCols:"; 
    insertCols_->generateCacheKey(cwa); 
  }

  if (insertValues_) { 
    cwa += " insertValues:"; 
    insertValues_->generateCacheKey(cwa); 
  }
}

// is this entire expression cacheable after this phase?
NABoolean MergeDelete::isCacheableExpr(CacheWA& cwa)
{
  if ((insertValues_) &&
      (insertValues_->isCacheableExpr(cwa))) {
    setNonCacheable();
    return FALSE;
  }

  return Delete::isCacheableExpr(cwa);
}

// change literals of a cacheable query into ConstantParameters 
RelExpr* MergeDelete::normalizeForCache(CacheWA& cwa, BindWA& bindWA)
{
  if (nodeIsNormalizedForCache()) { 
    return this; 
  }

  if (insertValues_) {
    insertValues_ = insertValues_->normalizeForCache(cwa, bindWA);
  }

  // replace descendants' literals into ConstantParameters
  return Delete::normalizeForCache(cwa, bindWA);
}

// append an ascii-version of Join into cachewa.qryText_
void Join::generateCacheKey(CacheWA &cwa) const
{
  RelExpr::generateCacheKeyNode(cwa);
  if (isNaturalJoin_) {
    cwa += " natj "; 
  }
  ItemExpr *pred = joinPredTree_ ? joinPredTree_ :
    joinPred_.rebuildExprTree();
  if (pred) { 
    cwa += " joinPred:";
    pred->generateCacheKey(cwa); 
  }
  generateCacheKeyForKids(cwa);
}

// is this entire expression cacheable after this phase?
NABoolean Join::isCacheableExpr(CacheWA& cwa)
{
  if (cwa.getPhase() >= CmpMain::BIND) {
    // must first descend to scans to get cwa.numberOfScans_ 
    if (!RelExpr::isCacheableExpr(cwa)) {
      return FALSE;
    }
    if (isCacheableNode(cwa.getPhase())) { 
      cwa.setConditionallyCacheable();
    }
    // if we allow joins of views to be cached, query caching cannot 
    // distinguish between (see note at bottom of cachewa.h)
    //   select avg(f.a) from v f, v s group by f.b;
    //   select avg(s.a) from v f, v s group by f.b;
    //   select avg(t.a) from v f, t   group by f.b;
    // assuming v is "create view v from select * from t". We avoid
    // false cache hits by detecting the possible occurrence of such 
    // view joins here and later using cwa.isViewJoin_ to include
    // their query texts into their cache keys.
    //
    // A view is repsented by a renamed table with isView() returnning 
    // TRUE.

    RelExpr *c0 = child(0);
    RelExpr *c1 = child(1);
    if ((c0->getOperatorType() == REL_RENAME_TABLE &&
        ((RenameTable *)c0)->isView() == TRUE)
        ||
        (c1->getOperatorType() == REL_RENAME_TABLE &&
        ((RenameTable *)c1)->isView() == TRUE)) {
      cwa.foundViewJoin();
    }
    // check its join predicate
    ItemExpr *pred = joinPredTree_ ? joinPredTree_ :
      joinPred_.rebuildExprTree();
    if (pred) {
      cwa.setHasPredicate();
      // is join predicate cacheable?
      if (pred->hasNoLiterals(cwa)) {
        // predicate with no literals is cacheable
      }
      else {
        cwa.setPredHasNoLit(FALSE);
        if (!pred->isCacheableExpr(cwa)) {
          // a non-cacheable predicate renders Join non-cacheable.
          setNonCacheable();
          return FALSE;
        }
      }
    }
    return TRUE; // join may be cacheable
  }
  return FALSE;
}

// change literals of a cacheable query into ConstantParameters 
RelExpr* Join::normalizeForCache(CacheWA& cwa, BindWA& bindWA)
{
  return RelExpr::normalizeForCache(cwa, bindWA);
}

// are RelExpr's kids cacheable after this phase?
NABoolean RelExpr::cacheableKids(CacheWA& cwa)
{
  switch (cwa.getPhase()) {
  case CmpMain::PARSE:
  case CmpMain::BIND: {
    Int32 arity = getArity();
    if (arity <= 0) { // we have no kids
      if (cwa.isConditionallyCacheable()) {
        // we're conditionally cacheable and have no kids
        setCacheableNode(cwa.getPhase()); 
        return TRUE; // so, we're cachable
      }
      else {
        return FALSE; // MAYBECACHEABLE is not cacheable at this phase
        // don't mark this node non-cacheable because this
        // RelExpr may be cacheable after the next phase.
      }
    }
    // cacheability of child(ren) determine our cacheability
    for (Int32 x = 0; x < arity; x++) {
      if (!child(x) || // cases like "insert into t default values"
          // return 1 from getArity() even if child(0) is NULL; so
          // guard against this potential mxcmp crash and consider
          // these cases non-cacheable during the PARSE stage.
          child(x)->isNonCacheable()) {
        // the 1st noncacheable child makes us noncacheable
        setNonCacheable();
        return FALSE;
      }
      else if (!child(x)->isCacheableExpr(cwa)) {
        // noncacheable child
        return FALSE;
        // don't mark this node non-cacheable because this
        // RelExpr may be cacheable after the next phase.
      }
      else { // cacheable child
        continue; // look at next child
      }
    }
    // all children are cacheable, so we're cacheable too
    setCacheableNode(cwa.getPhase());
    return TRUE;
  }
  default:
    return FALSE;
  }
}

// append an ascii-version of RelExpr into cachewa.qryText_
void RelExpr::generateCacheKey(CacheWA &cwa) const
{
  generateCacheKeyNode(cwa);
  generateCacheKeyForKids(cwa);
}

// append an ascii-version of RelExpr node into cachewa.qryText_
void RelExpr::generateCacheKeyNode(CacheWA &cwa) const
{
  // emit any "[firstn_sorted]" modifier
  if (firstNRows_ != -1) {
    char firstN[40]; 
    convertInt64ToAscii(((RelExpr*)this)->getFirstNRows(), firstN); 
    cwa += firstN; 
    cwa += " ";
  }
  // emit other "significant" parts of RelExpr
  cwa += getText();
  ItemExpr *pred = selPredTree() ? selPredTree() :
    getSelectionPred().rebuildExprTree();
  if (pred) { 
    cwa += " selPred:"; 
    pred->generateCacheKey(cwa); 
  }
  // make any optimizer hints part of the postbinder cache key so that
  // 2 cacheable queries with different optimizer hints do not match
  if (hint_) {
    CollIndex x, cnt=hint_->indexCnt();
    if (cnt > 0) {
      cwa += " xhint:";
      for (x = 0; x < cnt; x++) {
        cwa += (*hint_)[x].data();
        cwa += ",";
      }
    }
    char str[100];
    if (hint_->hasCardinality()) {
      sprintf(str, "card:%g", hint_->getCardinality());
      cwa += str;
    }
    if (hint_->hasSelectivity()) {
      sprintf(str, ",sel:%g", hint_->getSelectivity());
      cwa += str;
    }
  }
}

// append an ascii-version of RelExpr's kids into cachewa.qryText_
void RelExpr::generateCacheKeyForKids(CacheWA& cwa) const
{
  Int32 maxi = getArity();
  if (maxi) {
    cwa += " kids(";
    for (Lng32 i = 0; i < maxi; i++) {
      if (i > 0) { 
        cwa += ","; 
      }
      if ( child(i).getPtr() == NULL ) { 
        continue; 
      }
      child(i)->generateCacheKey(cwa);
    }
    cwa += ")";
  }
}

// return any Scan node from this RelExpr
Scan *RelExpr::getAnyScanNode() const
{
  if (getOperatorType() == REL_SCAN) { 
    return (Scan*)this; 
  }
  Scan *result = NULL;
  Int32 arity = getArity();
  for (Int32 x = 0; x < arity && !result; x++) {
    if (child(x)) { 
      result = child(x)->getAnyScanNode(); 
    }
  }
  return result;
}

// is this entire expression cacheable after this phase?
NABoolean RelExpr::isCacheableExpr(CacheWA& cwa)
{
  switch (cwa.getPhase()) {
  case CmpMain::PARSE:
  case CmpMain::BIND: {
    // does query have too many ExprNodes?
    if (cwa.inc_N_check_still_cacheable() == FALSE) {
      // yes. query with too many ExprNodes is not cacheable.
      return FALSE;
    }
    if (isNonCacheable()) { // this node is not cacheable
      return FALSE; // so the entire expression is not cacheable
      // don't mark this node non-cacheable because this
      // RelExpr may be cacheable after the next phase.
    }
    if (isCacheableNode(cwa.getPhase())) { 
      // must be an INSERT, UPDATE, DELETE, or SELECT node;
      // so, mark this expression as conditionally cacheable.
      cwa.setConditionallyCacheable();
    }
    // must descend to scans to get cwa.numberOfScans_ 
    if (!cacheableKids(cwa)) {
      return FALSE;
    }
    // this node is either cacheable or maybecacheable
    // check its selection predicate
    ItemExpr *pred = selPredTree() ? selPredTree() :
      getSelectionPred().rebuildExprTree();
    if (pred) {
      cwa.setHasPredicate();
      // is selection predicate cacheable?
      if (pred->hasNoLiterals(cwa)) {
        // predicate with no literals is cacheable
      }
      else {
        cwa.setPredHasNoLit(FALSE);
        if (!pred->isCacheableExpr(cwa)) {
          // a non-cacheable selection predicate 
          // renders entire RelExpr non-cacheable.
          setNonCacheable();
          return FALSE;
        }
      }
    }
    return TRUE; // RelExpr may be cacheable
  }
  default: { const NABoolean notYetImplemented = FALSE; 
  CMPASSERT(notYetImplemented);
  return FALSE;
    }
  }
}

// is this ExprNode cacheable after this phase?
NABoolean RelExpr::isCacheableNode(CmpPhase phase) const
{ 
  switch (phase) {
  case CmpMain::PARSE: 
    return cacheable_ == ExprNode::CACHEABLE_PARSE;
  case CmpMain::BIND:
    return cacheable_ == ExprNode::CACHEABLE_BIND ||
      cacheable_ == ExprNode::CACHEABLE_PARSE;
  default:
    break;
  }
  return FALSE;
}

// change literals of a cacheable query into ConstantParameters 
RelExpr* RelExpr::normalizeForCache(CacheWA& cwa, BindWA& bindWA)
{
  if (nodeIsNormalizedForCache()) { 
    return this; 
  }
  // replace descendants' literals into ConstantParameters
  normalizeKidsForCache(cwa, bindWA);
  if (cwa.getPhase() >= CmpMain::BIND) {
    if (selection_) {
      selection_ = selection_->normalizeForCache(cwa, bindWA);
    }
    else {
      selectionPred().normalizeForCache(cwa, bindWA);
    }
    // RelExpr::bindSelf has done this line during binding; but, we
    // must redo it to recognize any new constantparameters created 
    // by the above normalizeForCache call(s) as RelExpr inputs.
    getGroupAttr()->addCharacteristicInputs
      (bindWA.getCurrentScope()->getOuterRefs());
  }

  markAsNormalizedForCache();
  return this;
}

// change literals in cacheable query's kids into ConstantParameters
void RelExpr::normalizeKidsForCache(CacheWA& cachewa, BindWA& bindWA)
{
  Int32 arity = getArity();
  for (Int32 x = 0; x < arity; x++) {
    child(x) = child(x)->normalizeForCache(cachewa, bindWA);
  }
}

// mark this ExprNode as cacheable after this phase
void RelExpr::setCacheableNode(CmpPhase phase)
{ 
  switch (phase) {
  case CmpMain::PARSE: 
    cacheable_ = ExprNode::CACHEABLE_PARSE;
    break;
  case CmpMain::BIND:
    cacheable_ = ExprNode::CACHEABLE_BIND;
    break;
  default:
    break;
  }
}

// append an ascii-version of RelRoot into cachewa.qryText_
void RelRoot::generateCacheKey(CacheWA &cwa) const
{
  RelExpr::generateCacheKey(cwa);
  ItemExpr *cExpr = compExprTree_ ? compExprTree_ : 
    compExpr_.rebuildExprTree();
  if (cExpr) { 
    // append any select list into cache key
    cwa += " cExpr:"; 
    cExpr->generateCacheKey(cwa);
    // reflect any "[first n]"
    cwa += ((RelRoot*)this)->needFirstSortedRows() ? " 1stN" : " ";
    // Should the select_list aliases be a part of the cache key?
    // Their not affecting the compiled plan argues for their exclusion.
    // Their affecting sqlci's expected output argues for their inclusion.
    RETDesc *rDesc = getRETDesc(); 
    CollIndex degree, x;

    if (rDesc && (degree=rDesc->getDegree()) > 0) {
      cwa += " sla:";
      for (x = 0; x < degree; x++){
        cwa += rDesc->getColRefNameObj(x).getColName().data(); 
        cwa += " ";
      }

        // fix 0-061115-0532 (query cache didn't handle select with embedded 
        // update correctly). New/Old corr. names are recorded for embedded
        // updates here for exact match. This is important because otherwise 
        // a reuse of a query returning the old/new version of values for 
        // a query requesting new/old version is totally possible and 
        // unacceptable.
        //
        // Sample embedded update queries
        // select * from (update tab1 set x = x + 1 where x > 1 return new.*) y;
        // select * from (update tab1 set x = x + 1 where x > 1 return new.x, old.y) y;
        //
      if ( cwa.isUpdate() && isTrueRoot() == FALSE ) {
         cwa += " corrNamTok:";
         cwa += rDesc->getBindWA()->getCorrNameTokens();
      }
    }
  }
  // order by clause is important
  ItemExpr *orderBy = orderByTree_ ? orderByTree_ :
    reqdOrder_.rebuildExprTree();
  if (orderBy) { 
    cwa += " order:"; 
    orderBy->generateCacheKey(cwa); 
  }
  // statement-level access type & lock mode are important for multiuser 
  // applications. both are reflected in the stmt-level and/or context-wide
  // TransMode. So, we mimic RelRoot::codeGen logic here: "copy the current 
  //   context-wide TransMode, then overlay with this stmt's 'FOR xxx ACCESS' 
  //   setting, if any".
  TransMode tmode;
  tmode.updateTransMode(CmpCommon::transMode());

  StmtLevelAccessOptions &opts = ((RelRoot*)this)->accessOptions();
  if (opts.accessType() != TransMode::ACCESS_TYPE_NOT_SPECIFIED_) {
    tmode.updateAccessModeFromIsolationLevel
      (TransMode::ATtoIL(opts.accessType()));
    tmode.setStmtLevelAccessOptions();
  }
  if (isTrueRoot()) {
    // these are needed by Javier's qc stats virtual tbl interface
    cwa.setIsoLvl(tmode.getIsolationLevel());
    cwa.setAccessMode(tmode.getAccessMode());
    cwa.setAutoCommit(tmode.getAutoCommit());
    cwa.setFlags(tmode.getFlags());
    cwa.setRollbackMode(tmode.getRollbackMode());
    cwa.setAutoabortInterval(tmode.getAutoAbortIntervalInSeconds());
    cwa.setMultiCommit(tmode.getMultiCommit());
  }

  // needed to distinguish these queries and avoid a false hit
  // select * from (delete from t where a=2) as t;
  // select * from (delete from t where a=2 for SKIP CONFLICT ACCESS) as t;
  char mode[40]; 
  str_itoa(tmode.getIsolationLevel(), mode); cwa += " il:"; cwa += mode;
  str_itoa(tmode.getAccessMode(), mode); cwa += " am:"; cwa += mode;

  // Solution: 10-060418-5903
  str_itoa(cwa.getIsoLvlForUpdates(), mode); cwa += " ilu:"; cwa += mode;

  str_itoa(tmode.getAutoCommit(), mode); cwa += " ac:"; cwa += mode;
  str_itoa(tmode.getFlags(), mode); cwa += " fl:"; cwa += mode;
  str_itoa(tmode.getRollbackMode(), mode); cwa += " rm:"; cwa += mode;
  str_itoa(tmode.getAutoAbortIntervalInSeconds(), mode); cwa += " ai:"; cwa += mode;
  str_itoa(tmode.getMultiCommit(), mode); cwa += " mc:"; cwa += mode;

  if (opts.lockMode() != LOCK_MODE_NOT_SPECIFIED_) {
    // need to distinguish these queries and avoid a false hit
    //   select * from t in share mode;
    //   select * from t in exclusive mode;
    str_itoa(opts.lockMode(), mode); cwa += " lm:"; cwa += mode;
  }

  // updatableSelect_ is essential. Otherwise, queries like
  // "select * from t" and "select * from t for update" can confuse
  // query caching into a false hit, causing fullstack/test051 to fail.
  if (updatableSelect_) { 
    cwa += " 4updt "; 
  }
  // for update of col [,col]... clause is important
  ItemExpr *updCol = updateColTree_ ? updateColTree_ :
    updateCol_.rebuildExprTree();
  if (updCol) { 
    cwa += " updCol:"; 
    updCol->generateCacheKey(cwa); 
  }
  // making the CQS part of the key is more efficient than calling
  // CompilerEnv::changeEnv() in ControlDB::setRequiredShape()
  if (reqdShape_) { 
    reqdShape_->unparse(cwa.reqdShape_); 
  }
}

// is this entire expression cacheable after this phase?
NABoolean RelRoot::isCacheableExpr(CacheWA& cwa)
{
  //queries prefixed by display are not cacheable e.g. display select * from ...
  if(getDisplayTree())
    return FALSE;
  
  // Parallel extract producer queries are not cacheable
  if (numExtractStreams_ > 0)
    return FALSE;

  // descend to scans early to get cwa.numberOfScans_ 
  if (!RelExpr::isCacheableExpr(cwa)) {
    return FALSE;
  }
  if (cwa.getPhase() == CmpMain::PARSE) {
    if (compExprTree_ || compExpr_.entries() > 0) {
      // insert-returning is not cacheable after parse
      return FALSE; 
    }
  }
  else if (cwa.getPhase() >= CmpMain::BIND) {
    // make sure select list is cacheable
    if (compExprTree_) {
      if (!compExprTree_->isCacheableExpr(cwa)) { 
        return FALSE; 
      }
    }
    else if (!compExpr_.isCacheableExpr(cwa)) {
      return FALSE;
    }
  }

  if (isAnalyzeOnly())
    return FALSE;

  return TRUE;
}

// change literals of a cacheable query into ConstantParameters and save
// true root into cachewa so we can "bind" ConstantParameters as "inputvars"
RelExpr* RelRoot::normalizeForCache(CacheWA& cwa, BindWA& bindWA)
{
  if (nodeIsNormalizedForCache()) { 
    return this; 
  }
  if (isTrueRoot()) { 
    cwa.setTopRoot(this); 
  }
  if (cwa.getPhase() >= CmpMain::BIND) {
    // replace any select list literals into constant parameters
    if (compExprTree_) {
      compExprTree_ = compExprTree_->normalizeForCache(cwa, bindWA);
    }
    else {
      compExpr_.normalizeForCache(cwa, bindWA);
    }
  }
  // replace descendants' literals into ConstantParameters
  RelExpr *result = RelExpr::normalizeForCache(cwa, bindWA);
  if (cwa.getPhase() >= CmpMain::BIND) {
    // query tree has undergone BINDing, but RelExpr::normalizeForCache
    // may have introduced new ConstantParameters in place of ConstValues;
    // we want to BIND these new ConstantParameters but a RelRoot::bindNode()
    // call here would be overkill; we just want these new ConstantParameters
    // to be "bound" as "inputvars"; so, we selectively cut and paste code
    // from BindRelExpr.cpp RelRoot::bindNode into here to "bind" any new 
    // ConstantParameters as "inputvars".
    ItemExpr *inputVarTree = removeInputVarTree();
    if (inputVarTree) {
      inputVarTree->convertToValueIdList(inputVars(), &bindWA, ITM_ITEM_LIST);
      if (bindWA.errStatus()) {
        return NULL;
      }
    }
  }
  return result;
}

// append an ascii-version of Scan into cachewa.qryText_
void Scan::generateCacheKey(CacheWA &cwa) const
{
  RelExpr::generateCacheKey(cwa);
  // Fix to 10-010618-3505, 10-010619-3515: include this Scan table's 
  // RedefTime into cwa.qryText_ to make sure we get a cache hit only on 
  // query that reference table(s) that have not changed since the query's 
  // addition to the cache. The queries that reference altered table(s) 
  // will never be hit again and will eventually age out of the cache.
  const NATable *tbl;
  if (cwa.getPhase() >= CmpMain::BIND && 
      getTableDesc() && (tbl=getTableDesc()->getNATable()) != NULL) {
    char redefTime[40];
    convertInt64ToAscii(tbl->getRedefTime(), redefTime);
    cwa += " redef:";
    cwa += redefTime;

    if (tbl->isHiveTable()) {
      char lastModTime[40];
      Int64 mTime = tbl->getClusteringIndex()->getHHDFSTableStats()->getModificationTS();
      convertInt64ToAscii(mTime, lastModTime);
      cwa += " lastMod:";
      cwa += lastModTime;

      cwa += " numFiles:";
      char numFiles[20];
      Int64 numberOfFiles = tbl->getClusteringIndex()->getHHDFSTableStats()->getNumFiles();
      sprintf(numFiles, " %ld", numberOfFiles); 
      cwa += numFiles ;
    }
    // save pointer to this table. later, QueryCache::addEntry will use
    // this pointer to get to this table's histograms's timestamp
    cwa.addTable( (NATable*)tbl );
    // If PARTITION clause has been used we must reflect that in the key.
    if (tbl->isPartitionNameSpecified()) {
      cwa += " partition:";
      cwa += tbl->getClusteringIndex()->getFileSetName().getQualifiedNameAsString().data();
    }
    // If PARTITION range has been used we must reflect that in the key.
    else if (tbl->isPartitionRangeSpecified()) {
      cwa += " partition:";

      char str[100];
      sprintf(str, " from %d to %d", 
	      tbl->getExtendedQualName().getPartnClause().getBeginPartitionNumber() ,
	      tbl->getExtendedQualName().getPartnClause().getEndPartitionNumber());
      cwa += str;
    }
  }
  // We must reflect userTableName_.location into cache key.
  // Otherwise, two queries which differ only in location such as
  //   table table (table T058a, location $system.zsd12345.x1234500);
  //   table table (table T058a, location $data  .zsd12345.x1234500);
  // can confuse our query caching code to return a false hit and 
  // cause fullstack/test058 to fail.
  cwa += userTableName_.getLocationName().data();

  // Same with stream_ because queries like
  // "select * from t" and "select * from stream(t)" can
  // confuse query caching into a false hit causing test079 to fail.
  if (stream_) { 
    cwa += " stream "; 
  }

  if (getHbaseAccessOptions())
    {
      cwa += " hbaseVersions: ";
      char numVersions[20];
      sprintf(numVersions, " %d", getHbaseAccessOptions()->getHbaseVersions());
      cwa += numVersions ;
    }
}

// is this entire expression cacheable after this phase?
NABoolean Scan::isCacheableExpr(CacheWA& cwa)
{
  if (cwa.getPhase() >= CmpMain::BIND) {
    // save scan's TableDesc
    cwa.incNofScans(tabId_);

    // native hbase access is not cacheable for now.
    if ((getTableDesc()->getNATable()->isHbaseRowTable()) ||
	(getTableDesc()->getNATable()->isHbaseCellTable()))
      return FALSE;

    if (stream_) { // pub-sub streams are not cacheable
      return FALSE;
    }

    cwa.setConditionallyCacheable(); 
    if (CmpCommon::getDefaultLong(MVQR_REWRITE_LEVEL) >= 1 &&
        QRDescGenerator::hasRewriteEnabledMVs(getTableDesc())) {
      cwa.setRewriteEnabledMV();
    }
    return RelExpr::isCacheableExpr(cwa);
  }
  return FALSE;
}

// append an ascii-version of Tuple into cachewa.qryText_
void Tuple::generateCacheKey(CacheWA &cwa) const
{
  // Do not call RelExpr::generateCacheKey(cwa) here because it's redundant.
  // It does the same things as the code below. RelExpr::generateCacheKey() 
  // calls Tuple::getText() which has logic similar to the following code.
  ItemExpr *tExpr = tupleExprTree() ? tupleExprTree() :
    tupleExpr_.rebuildExprTree();
  if (tExpr) { 
    cwa += " tupExpr:"; 
    tExpr->generateCacheKey(cwa); 
  }
  else {
    RelExpr::generateCacheKey(cwa);
  }
}

// is this entire expression cacheable after this phase?
NABoolean Tuple::isCacheableExpr(CacheWA& cwa)
{
  // we do not call RelExpr::isCacheableExpr here because it's redundant
  // -- Tuple is a leaf node and has no predicates.

  ItemExpr *tExpr = tupleExprTree() ? tupleExprTree() :
    tupleExpr_.rebuildExprTree();
  return tExpr->isCacheableExpr(cwa);
}

// change literals of a cacheable query into ConstantParameters 
RelExpr* Tuple::normalizeForCache(CacheWA& cwa, BindWA& bindWA)
{
  if (nodeIsNormalizedForCache()) { 
    return this; 
  }
  if (tupleExprTree_) {
    tupleExprTree_ = tupleExprTree_->normalizeForCache(cwa, bindWA);
  }
  else {
    tupleExpr_.normalizeForCache(cwa, bindWA);
  }
  // replace descendants' literals into ConstantParameters
  return RelExpr::normalizeForCache(cwa, bindWA);
}

// append an ascii-version of Union into cachewa.qryText_
void Union::generateCacheKey(CacheWA &cwa) const
{
  RelExpr::generateCacheKeyNode(cwa);

  char buf[40];

  cwa += " flgs_: ";
  convertInt64ToAscii(flags_, buf);
  cwa += buf;

  cwa += " ctrFlgs_: ";
  convertInt64ToAscii(controlFlags_, buf);
  cwa += buf;

  cwa += " sysGen_: ";
  cwa += (isSystemGenerated_) ? "1" : "0";

  // turn on the following when condExprTree_ and trigExceptExprTree_
  // are considered part of the key
  //
  //if (condExprTree_) {
  //  cwa += " condExprTree_: ";
  //  condExprTree_->generateCacheKey(cwa);
  //}

  //if (trigExceptExprTree_) {
  //  cwa += " trigExceptExprTree_: ";
  //  trigExceptExprTree_->generateCacheKey(cwa);
  //}
  generateCacheKeyForKids(cwa);
}

NABoolean Update::isCacheableExpr(CacheWA& cwa)
{
  cwa.setIsUpdate(TRUE);
  return GenericUpdate::isCacheableExpr(cwa);
}

// append an ascii-version of FastExtract into cachewa.qryText_
void FastExtract::generateCacheKey(CacheWA &cwa) const
{
  RelExpr::generateCacheKeyNode(cwa);

  char buf[40];
  cwa += " targType_ ";
  str_itoa(getTargetType(), buf);
  cwa += buf;

  cwa += " targName_ ";
  cwa += getTargetName();

  cwa += " delim_ ";
  cwa += getDelimiter();

  cwa += " isAppend_ ";
  cwa += isAppend() ? "1" : "0";

  cwa += " includeHeader_ ";
  cwa += includeHeader() ? "1" : "0";

  cwa += " cType_ ";
  str_itoa(getCompressionType(), buf);
  cwa += buf;

  cwa += " nullString_ ";
  cwa += getNullString();

  cwa += " recSep_ ";
  cwa += getRecordSeparator();

  generateCacheKeyForKids(cwa);
}

