// 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; }
// 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; }
// 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; } } }