Exemplo n.º 1
0
// 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() != 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_); 
  }
}