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

  cwa += " nam:"; 
  cwa += functionName_.getExternalName().data();
  if (cwa.getPhase() >= CmpMain::BIND && 
      getRoutineDesc() && 
      (routine=getRoutineDesc()->getNARoutine()) != NULL) 
  {
    char redefTime[40];
    convertInt64ToAscii(routine->getRedefTime(), redefTime);
    cwa += " redef:";
    cwa += redefTime;
    if ((routine->getSchemaLabelFileName()) &&
        (str_len(routine->getSchemaLabelFileName()) > 0)) 
    {
      char schRedefTime[40];
      convertInt64ToAscii(routine->getSchemaRedefTime(), schRedefTime);
      cwa += " schredef:";
      cwa += schRedefTime;
    }
  }

  if (getRoutineDesc() && 
      getRoutineDesc()->getActionNameAsGiven().length() != 0)
  {
    cwa += " actnam:"; 
    cwa += getRoutineDesc()->getActionNameAsGiven();

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

  cwa += "(";
  Lng32 arity =  (Lng32) getArity();
  for (Lng32 i = 0; i < arity; i++) {
    if (i > 0) {
      cwa += ", ";
    }
    child(i)->generateCacheKey(cwa);
  }
 
  if (getRoutineDesc()->getLocale() != 0 )
  {
    cwa += ", LOCALE: ";
    char dFmt[20]; 
    str_itoa(getRoutineDesc()->getLocale(), dFmt); 
    cwa += dFmt;
  }
  cwa += ")";
}
示例#2
0
// 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;
}
示例#3
0
// 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;
    }
  }
}
示例#4
0
// 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;
    }
    // mpalias SELECT is not cacheable unless explicitly requested
    if (getTableDesc()->getNATable()->isAnMPTableWithAnsiName() &&
        CmpCommon::getDefault(QUERY_CACHE_MPALIAS) == DF_OFF) {
      return FALSE;
    }
    cwa.setConditionallyCacheable(); 
    if (CmpCommon::getDefaultLong(MVQR_REWRITE_LEVEL) >= 1 &&
        QRDescGenerator::hasRewriteEnabledMVs(getTableDesc())) {
      cwa.setRewriteEnabledMV();
    }
    return RelExpr::isCacheableExpr(cwa);
  }
  return FALSE;
}
示例#5
0
// Only alow UDFunctions to be cached after BIND time.
NABoolean UDFunction::isCacheableExpr(CacheWA& cwa)
{ 
  if (cwa.getPhase() >= CmpMain::BIND) 
    return TRUE;
  else 
    return FALSE; 
}
示例#6
0
// is any literal in this expr safely coercible to its target type?
NABoolean ItemExpr::isSafelyCoercible(CacheWA &cwa) const
{
  if (cwa.getPhase() >= CmpMain::BIND) {
    Int32 arity = getArity();
    for (Int32 x = 0; x < arity; x++) {
      if (!child(x)->isSafelyCoercible(cwa)) { 
        return FALSE; 
      }
    }
    if (arity == 2) {
      // we have to disallow caching of the following types of exprs:
      //   expr + 123456789012345678901234567890
      //   expr || 'overlylongstringthatwouldoverflow'
      ItemExpr *left = child(0), *right = child(1);
      if (left->getOperatorType() == ITM_CONSTANT) {
        if (right->getOperatorType() == ITM_CONSTANT) {
          // "10 + 1" should be safely coercible
          return TRUE;
        } else {
          return ((ConstValue*)left)->canBeSafelyCoercedTo
            (right->getValueId().getType());
        }
      }      
      else if (right->getOperatorType() == ITM_CONSTANT) {
        return ((ConstValue*)right)->canBeSafelyCoercedTo
          (left->getValueId().getType());
      }      
      // else both are nonliterals; fall thru
    }
    // else nondyadic expr; fall thru
    return TRUE; 
  }
  return FALSE;
}
示例#7
0
// we want BiLogic to be cacheable
NABoolean BiLogic::isCacheableExpr(CacheWA& cwa)
{
  if (cwa.getPhase() >= CmpMain::BIND && getArity() == 2) {
    if (getOperatorType() == ITM_AND) {
      ItemExpr *leftC=child(0), *rightC=child(1);
      // we want to descend to both left & right
      // so cwa.usedKeys & cwa.keyCols get updated
      NABoolean leftOK = leftC->isCacheableExpr(cwa);
      NABoolean rightOK = rightC->isCacheableExpr(cwa);
      // return FALSE if both left & right are not cacheable.
      if (!leftOK && !rightOK) 
        return FALSE;

      // allow "select * from t where k1=1 and k2=2" as potentially cacheable
      return TRUE;
      // the definitive check whether a query's predicate covers
      // all referenced tables' key columns can be (and is) done
      // only in RelRoot::isCacheableExpr() when cwa.usedKeys &
      // cwa.keyCols are fully defined. Otherwise, queries like
      //   "select * from t1 join t2 on a=x and a=7 where x=7"
      // may be incorrectly rejected as non-cacheable if t1 has
      // primary key(a) and t2 has primary key(x).
    }
    else if (getOperatorType() == ITM_OR) {
      return TRUE;
      // ORs can be cacheable but are not necessarily
      // parameterizable, see Bilogic::normalizeForCache below.
    }
  }
  return FALSE;
}
示例#8
0
// 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;
  }
}
示例#9
0
// 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 += ")";
  }
}
示例#10
0
// is any literal in this expr safely coercible to its target type?
NABoolean ValueIdProxy::isSafelyCoercible(CacheWA& cwa) const
{
  if (cwa.getPhase() >= CmpMain::BIND) {
      if (!derivedFrom_.getItemExpr()->isSafelyCoercible(cwa))
        return FALSE; 
      else
        return TRUE;
  }
  return FALSE;
}
示例#11
0
// does this ItemExpr (dis)qualify query to be cacheable after this phase?
NABoolean ConstValue::isCacheableExpr(CacheWA& cwa)
{
  if (cwa.getPhase() <= CmpMain::PARSE && hasUnknownCharSet()) {
    // string literal with unknown character set cannot be considered
    // cacheable by pre-binder stages because the information needed
    // to determine their character set is not known until bind-time.
    // This fixes genesis case 10-041215-6141, soln 10-041215-2826.
    return FALSE;
  }
  return ItemExpr::isCacheableExpr(cwa);
}
示例#12
0
// is any literal in this expr safely coercible to its target type?
NABoolean UDFunction::isSafelyCoercible(CacheWA& cwa) const
{
  if (cwa.getPhase() >= CmpMain::BIND) {
    Int32 arity = getArity();
    for (Int32 x = 0; x < arity; x++) {
      if (!child(x)->isSafelyCoercible(cwa)) { 
        return FALSE; 
      }
    }
    return TRUE;
  }
  return FALSE;
}
示例#13
0
// is any literal in this expr safely coercible to its target type?
NABoolean Cast::isSafelyCoercible(CacheWA &cwa) const
{
  if (cwa.getPhase() >= CmpMain::BIND) {
    ItemExpr *opd = child(0);
    if (!opd->isSafelyCoercible(cwa)) { 
      return FALSE; 
    }
    if (opd->getOperatorType() == ITM_CONSTANT) {
      return ((ConstValue*)opd)->canBeSafelyCoercedTo(*type_);
    }      
    return TRUE; 
  }
  return FALSE;
}
示例#14
0
// 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;
}
示例#15
0
// we want BiRelat to be cacheable
NABoolean BiRelat::isCacheableExpr(CacheWA& cwa)
{
  if (cwa.getPhase() >= CmpMain::BIND && getArity() == 2) {
    if (getOperatorType() == ITM_EQUAL) {
      ItemExpr *leftC=child(0), *rightC=child(1);
      OperatorTypeEnum leftO = leftC->getOperatorType();
      OperatorTypeEnum rightO = rightC->getOperatorType();
      BaseColumn *base;
      if (leftO == ITM_BASECOLUMN) {
        base = (BaseColumn*)leftC;
        if (base->isKeyColumnValue(*rightC)) {
          cwa.addToUsedKeys(base);
        }
        return TRUE;
      }
      else if (rightO == ITM_BASECOLUMN) {
        base = (BaseColumn*)rightC;
        if (base->isKeyColumnValue(*leftC)) {
          cwa.addToUsedKeys(base);
        }
        return TRUE;
      }
      else if (leftO == ITM_ITEM_LIST && rightO == ITM_ITEM_LIST &&
               ((ItemList*)leftC)->isListOfCacheableSelPred
               (cwa, (ItemList*)rightC)) {
        return TRUE;
      }
      else {
        // we want all other equality comparisons to be cacheable, eg,
        // retail_div_cd||acct_type_cd||substring(acct_id,1,8)='20V43085193'
        return TRUE;
      }
    }
    else {
      return TRUE;
      // other binary comparison predicates can be cacheable, but are
      // not necessarily parameterizable, see BiRelat::normalizeForCache
    }
  }
  return FALSE;
}
示例#16
0
// 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:";
    }
}
示例#17
0
// does this query's selection predicate list qualify query 
// to be cacheable after this phase?
NABoolean ItemList::isListOfCacheableSelPred
(CacheWA& cwa, ItemList *other) const
{
  Int32 arity = getArity();
  NABoolean result = FALSE;
  if (cwa.getPhase() >= CmpMain::BIND && 
      other && arity == other->getArity()) {
    // assume this is an AND list, so, we need only one
    // cacheable conjunct to consider the list cacheable.
    for (Int32 x = 0; x < arity; x++) {
      ItemExpr *leftC = child(x), *rightC = other->child(x);
      OperatorTypeEnum leftO = leftC->getOperatorType();
      OperatorTypeEnum rightO = rightC->getOperatorType();
      BaseColumn *base;
      if (leftO == ITM_BASECOLUMN) {
        base = (BaseColumn*)leftC;
        if (base->isKeyColumnValue(*rightC)) {
          cwa.addToUsedKeys(base);
        }
        result = TRUE;
        continue;
      }
      else if (rightO == ITM_BASECOLUMN) {
        base = (BaseColumn*)rightC;
        if (base->isKeyColumnValue(*leftC)) {
          cwa.addToUsedKeys(base);
        }
        result = TRUE;
        continue;
      }
      else if (leftO == ITM_ITEM_LIST && rightO == ITM_ITEM_LIST &&
               ((ItemList*)leftC)->isListOfCacheableSelPred
               (cwa, (ItemList*)rightC)) {
        result = TRUE;
        continue;
      }
    }
  }
  return result;
}
示例#18
0
// is any literal in this expr safely coercible to its target type?
NABoolean Assign::isSafelyCoercible(CacheWA &cwa) const
{
  if (cwa.getPhase() >= CmpMain::BIND) {
    // we have to disallow caching of the following types of updates:
    //   update t set col = overlylongliteral
    ItemExpr *src = getSource().getItemExpr();
    if (src->getOperatorType() == ITM_CONSTANT) {
      // source is a literal; make sure this update is cacheable only if
      // literal can be safely coerced into its target type.
      return ((ConstValue*)src)->canBeSafelyCoercedTo(getTarget().getType());
    }      
    else { // source is not a literal
      // we need to descend into this expr to verify that no 
      // errors can occur during backpatching. For example, 
      //   update t set i = i + 123456789012345678901234567890
      // should not be cacheable if i is a smallint.
      // reject "update t set c=(subquery)" as noncacheable
      // as part of a fix to CR 10-020108-8401.
      return src->isSafelyCoercible(cwa) && src->isCacheableExpr(cwa);
    }
  }
  return FALSE;
}
示例#19
0
// does this entire ItemExpr qualify query to be cacheable after this phase?
NABoolean ItemExpr::isCacheableExpr(CacheWA& cwa)
{
  switch (cwa.getPhase()) {
  default: { const NABoolean notYetImplemented = FALSE; 
    CMPASSERT(notYetImplemented);
    break;
  }
  case CmpMain::PARSE:
    // ItemExpr::isCacheableExpr is used by Tuple::isCacheable to
    // determine whether a tuple-insert or a tuplelist-insert is
    // cacheable after parse. It traverses a tuple's values list
    // looking for non-cacheable ItemExprs such as HostVar, 
    // DynamicParam, Subquery, etc.  
    // determine cacheability of tuple INSERT's itemexprs here
    if (isNonCacheable() || !cwa.isConditionallyCacheable()) {
      return FALSE;
    }
    else { // we're either cacheable or maybecacheable
      Int32 arity = getArity();
      if (arity <= 0) { // we have no kids & we're conditionally cacheable
        return TRUE; // we're cacheable
      }
      // cacheability of child(ren) determine our cacheability
      for (Int32 x = 0; x < arity; x++) {
        if (!child(x) || child(x)->isNonCacheable()) {
          // the 1st noncacheable child makes us noncacheable
          setNonCacheable();
          return FALSE;
        }
        else if (!child(x)->isCacheableExpr(cwa)) {
          // noncacheable child
          return FALSE;
        }
        else { // cacheable child
          continue; // look at next child
        }
      }
      // all children are cacheable, so we're cacheable too
      setCacheableNode(cwa.getPhase());
      return TRUE;
    }
    break;
  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;
    }
    // ItemExpr::isCacheableExpr is used in "after BIND" cases to
    // visit all operands of an ItemExpr looking for noncacheable
    // expressions. For example, it discovers that
    //   SELECT (SELECT a FROM t2 WHERE MAX(o.c)>1) FROM t1 o;
    // is noncacheable only after it visits the outer query's select list.
    if (isNonCacheable()) {
      return FALSE;
    }
    else if (isCacheableNode(cwa.getPhase())) {
      return TRUE;
    }
    else { // we're either cacheable or maybecacheable
      // Assume this ItemExpr is an operand of a function or a list. In
      // this case, a single noncacheable child renders us noncacheable.
      Int32 arity = getArity();
      for (Int32 x = 0; x < arity; x++) {
        if (!child(x) || !child(x)->isCacheableExpr(cwa)) {
          // noncacheable child
          return FALSE;
        }
        else { // cacheable child
          continue; // look at next child
        }
      }
      // all children are cacheable, so we're cacheable too
      setCacheableNode(cwa.getPhase());
      return TRUE;
    }
    break;
  }
  return FALSE;
}
示例#20
0
// does this entire ItemExpr qualify query to be cacheable after this phase?
NABoolean DynamicParam::isCacheableExpr(CacheWA& cwa)
{
  // a dynamic parameter is not cacheable after parse
  return (cwa.getPhase() <= CmpMain::PARSE) ? FALSE : TRUE;
}
示例#21
0
// 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 "; 
  }
  // mark mpalias queries so they can be decached upon user request
  if (getTableDesc()->getNATable()->isAnMPTableWithAnsiName()) {
    cwa += AM_AN_MPALIAS_QUERY;
  }

  if (getHbaseAccessOptions())
    {
      cwa += " hbaseVersions: ";
      char numVersions[20];
      sprintf(numVersions, " %d", getHbaseAccessOptions()->getHbaseVersions());
      cwa += numVersions ;
    }
}
示例#22
0
// 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
}
示例#23
0
// 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_
}