void WF_nth_value<T>::parseParms(const std::vector<execplan::SRCP>& parms) { // parms[0]: value-expr // skip // parms[1]: nth value ConstantColumn* cc = dynamic_cast<ConstantColumn*>(parms[1].get()); if (cc != NULL) { fNthNull = false; fNth = cc->getIntVal(fRow, fNthNull); // row not used, no need to setData. if (fNth <= 0) { ostringstream oss; oss << fNth; throw IDBExcept(IDBErrorInfo::instance()->errorMsg(ERR_WF_ARG_OUT_OF_RANGE, oss.str()), ERR_WF_ARG_OUT_OF_RANGE); } } // parms[2]: from first | from last bool isNull = false; cc = dynamic_cast<ConstantColumn*>(parms[2].get()); idbassert(cc != NULL); fFromFirst = (cc->getIntVal(fRow, isNull) > 0); // parms[3]: respect null | ignore null cc = dynamic_cast<ConstantColumn*>(parms[3].get()); idbassert(cc != NULL); fRespectNulls = (cc->getIntVal(fRow, isNull) > 0); }
// this fcn is dumb; relies on external check on whether it's safe or not // also relies on external write lock grab void CopyLocks::releaseRange(const LBIDRange& l) { int i, numEntries; LBID_t lastBlock = l.start + l.size - 1; LBID_t eLastBlock; #ifdef BRM_DEBUG // debatable whether this should be included or not given the timers // that automatically release locks idbassert(isLocked(l)); #endif numEntries = shminfo->allocdSize/sizeof(CopyLockEntry); for (i = 0; i < numEntries; i++) { CopyLockEntry &e = entries[i]; if (e.size != 0) { eLastBlock = e.start + e.size - 1; if (l.start <= eLastBlock && lastBlock >= e.start) { makeUndoRecord(&entries[i], sizeof(CopyLockEntry)); e.size = 0; makeUndoRecord(shminfo, sizeof(MSTEntry)); shminfo->currentSize -= sizeof(CopyLockEntry); } } } #ifdef BRM_DEBUG idbassert(!isLocked(l)); //log(string("CopyLocks::releaseRange(): that range isn't locked", LOG_TYPE_WARNING)); //throw std::invalid_argument("CopyLocks::releaseRange(): that range isn't locked"); #endif }
const string symname2devname(const string& sympath) { string ret; #ifndef _MSC_VER typedef boost::tokenizer<boost::char_separator<char> > tokenizer; boost::char_separator<char> sep("="); tokenizer tokens(sympath, sep); tokenizer::iterator tok_iter = tokens.begin(); idbassert(tok_iter != tokens.end()); string symtype = *tok_iter; if (symtype != "LABEL" && symtype != "UUID") return ret; idbassert(symtype == "LABEL" || symtype == "UUID"); ++tok_iter; idbassert(tok_iter != tokens.end()); string symname = *tok_iter; ++tok_iter; idbassert(tok_iter == tokens.end()); if (symtype == "LABEL") ret = label2dev(symname); else if (symtype == "UUID") ret = uuid2dev(symname); #endif return ret; }
void CopyLocks::growCL() { int allocSize; key_t newshmkey; if (shminfo->allocdSize == 0) allocSize = CL_INITIAL_SIZE; else allocSize = shminfo->allocdSize + CL_INCREMENT; newshmkey = chooseShmkey(); idbassert((allocSize == CL_INITIAL_SIZE && !fCopyLocksImpl) || fCopyLocksImpl); if (!fCopyLocksImpl) fCopyLocksImpl = CopyLocksImpl::makeCopyLocksImpl(newshmkey, allocSize, r_only); else fCopyLocksImpl->grow(newshmkey, allocSize); shminfo->tableShmkey = currentShmkey = newshmkey; shminfo->allocdSize = allocSize; if (r_only) fCopyLocksImpl->makeReadOnly(); entries = fCopyLocksImpl->get(); // Temporary fix. Get rid of the old undo records that now point to nothing. // Would be nice to be able to carry them forward. confirmChanges(); }
void SessionManagerServer::finishTransaction(TxnID& txn) { iterator it; mutex::scoped_lock lk(mutex); bool found = false; if (!txn.valid) throw invalid_argument("SessionManagerServer::finishTransaction(): transaction is invalid"); for (it = activeTxns.begin(); it != activeTxns.end(); ) { if (it->second == txn.id) { activeTxns.erase(it++); txn.valid = false; found = true; //we could probably break at this point, but there won't be that many active txns, and, // even though it'd be an error to have multiple entries for the same txn, we might // well just get rid of them... } else ++it; } if (found) { semValue++; idbassert(semValue <= (uint32_t)maxTxns); condvar.notify_one(); } else throw invalid_argument("SessionManagerServer::finishTransaction(): transaction doesn't exist"); }
/** * Build an expression tree with the tokens */ ParseTree* ExpressionParser::reduce(TreeNode* op, ParseTree* value) { char c = op->data().at(0); switch (c) { case 'M': case 'm': { ParseTree *root = new ParseTree(op); ParseTree *lhs = new ParseTree(new ConstantColumn("0", ConstantColumn::NUM)); root->left(lhs); root->right(value); return root; } case 'I': case 'i': delete op; return value; default: idbassert(0); } ostringstream oss; oss << "ExpressionParser::reduce(TreeNode*,ParseTree*): invalid input token: >" << op->data() << '<'; throw std::runtime_error(oss.str()); return 0; }
void LimitedOrderBy::initialize(const RowGroup& rg, const JobInfo& jobInfo) { fRm = &jobInfo.rm; fErrorCode = ERR_LIMIT_TOO_BIG; // locate column position in the rowgroup map<uint32_t, uint32_t> keyToIndexMap; for (uint64_t i = 0; i < rg.getKeys().size(); ++i) { if (keyToIndexMap.find(rg.getKeys()[i]) == keyToIndexMap.end()) keyToIndexMap.insert(make_pair(rg.getKeys()[i], i)); } vector<pair<uint32_t, bool> >::const_iterator i = jobInfo.orderByColVec.begin(); for ( ; i != jobInfo.orderByColVec.end(); i++) { map<uint32_t, uint32_t>::iterator j = keyToIndexMap.find(i->first); idbassert(j != keyToIndexMap.end()); fOrderByCond.push_back(IdbSortSpec(j->second, i->second)); } // limit row count info fStart = jobInfo.limitStart; fCount = jobInfo.limitCount; // fMemSize = (fStart + fCount) * rg.getRowSize(); IdbOrderBy::initialize(rg); }
void pColScanStep::addFilters() { AnyDataListSPtr dl = fInputJobStepAssociation.outAt(0); DataList_t* bdl = dl->dataList(); idbassert(bdl); int it = -1; bool more; ElementType e; int64_t token; try{ it = bdl->getIterator(); }catch(std::exception& ex) { cerr << "pColScanStep::addFilters: caught exception: " << ex.what() << " stepno: " << fStepId << endl; throw; }catch(...) { cerr << "pColScanStep::addFilters: caught exception" << endl; throw; } fBOP = BOP_OR; more = bdl->next(it, &e); while (more) { token = e.second; addFilter(COMPARE_EQ, token); more = bdl->next(it, &e); } return; }
int BRMShmImpl::grow(unsigned newKey, off_t newSize) { idbassert(newKey != fKey); idbassert(newSize >= fSize); string oldName = fShmobj.get_name(); string keyName = ShmKeys::keyToName(newKey); #if BOOST_VERSION < 104500 bi::shared_memory_object shm(bi::create_only, keyName.c_str(), bi::read_write); #ifdef __linux__ { string pname = "/dev/shm/" + keyName; chmod(pname.c_str(), 0666); } #endif #else bi::permissions perms; perms.set_unrestricted(); bi::shared_memory_object shm(bi::create_only, keyName.c_str(), bi::read_write, perms); #endif shm.truncate(newSize); bi::mapped_region region(shm, bi::read_write); //Copy old data into new region memcpy(region.get_address(), fMapreg.get_address(), fSize); //clear new region //make some versions of gcc happier... memset(reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(region.get_address()) + fSize), 0, newSize - fSize); fShmobj.swap(shm); fMapreg.swap(region); if (!oldName.empty()) bi::shared_memory_object::remove(oldName.c_str()); fKey = newKey; fSize = newSize; if (fReadOnly) { bi::mapped_region ro_region(fShmobj, bi::read_only); fMapreg.swap(ro_region); } return 0; }
uint64_t JoinPartition::writeByteStream(int which, ByteStream &bs) { size_t &offset = (which == 0 ? nextSmallOffset : nextLargeOffset); fstream &fs = (which == 0 ? smallFile : largeFile); const char *filename = (which == 0 ? smallFilename.c_str() : largeFilename.c_str()); fs.open(filename, ios::binary | ios::out | ios::app); int saveErrno = errno; if (!fs) { fs.close(); ostringstream os; os << "Disk join could not open file (write access) " << filename << ": " << strerror(saveErrno) << endl; throw IDBExcept(os.str().c_str(), ERR_DBJ_FILE_IO_ERROR); } uint64_t ret = 0; size_t len = bs.length(); idbassert(len != 0); fs.seekp(offset); if (!useCompression) { ret = len + 4; fs.write((char *) &len, sizeof(len)); fs.write((char *) bs.buf(), len); saveErrno = errno; if (!fs) { fs.close(); ostringstream os; os << "Disk join could not write file " << filename << ": " << strerror(saveErrno) << endl; throw IDBExcept(os.str().c_str(), ERR_DBJ_FILE_IO_ERROR); } totalBytesWritten += sizeof(len) + len; } else { uint64_t maxSize = compressor.maxCompressedSize(len); size_t actualSize; boost::scoped_array<uint8_t> compressed(new uint8_t[maxSize]); compressor.compress((char *) bs.buf(), len, (char *) compressed.get(), &actualSize); ret = actualSize + 4; fs.write((char *) &actualSize, sizeof(actualSize)); fs.write((char *) compressed.get(), actualSize); saveErrno = errno; if (!fs) { fs.close(); ostringstream os; os << "Disk join could not write file " << filename << ": " << strerror(saveErrno) << endl; throw IDBExcept(os.str().c_str(), ERR_DBJ_FILE_IO_ERROR); } totalBytesWritten += sizeof(actualSize) + actualSize; } bs.advance(len); offset = fs.tellp(); fs.close(); return ret; }
void TupleConstantOnlyStep::fillInConstants() { fRowGroupOut.getRow(0, &fRowOut); idbassert(fRowConst.getSize() == fRowOut.getSize()); copyRow(fRowConst, &fRowOut); fRowGroupOut.resetRowGroup(0); fRowGroupOut.setRowCount(1); fRowsReturned = 1; }
void FileBufferMgr::depleteCache() { for (uint32_t i = 0; i < fDeleteBlocks && !fbList.empty(); ++i) { FBData_t fbdata(fbList.back()); //the lru block HashObject_t lastFB(fbdata.lbid, fbdata.ver, 0); filebuffer_uset_iter_t iter = fbSet.find( lastFB ); idbassert(iter != fbSet.end()); uint32_t idx = iter->poolIdx; idbassert(idx < fFBPool.size()); //Save position in FileBuffer pool for reuse. fEmptyPoolSlots.push_back(idx); fbSet.erase(iter); if (fbList.back().hits==0) fBlksNotUsed++; fbList.pop_back(); fCacheSize--; } }
const TxnID SessionManagerServer::newTxnID(const SID session, bool block, bool isDDL) { TxnID ret; //ctor must set valid = false iterator it; mutex::scoped_lock lk(mutex); // if it already has a txn... it = activeTxns.find(session); if (it != activeTxns.end()) { ret.id = it->second; ret.valid = true; return ret; } if (!block && semValue == 0) return ret; else while (semValue == 0) condvar.wait(lk); semValue--; idbassert(semValue <= (uint32_t)maxTxns); ret.id = ++_verID; ret.valid = true; activeTxns[session] = ret.id; if (isDDL) ++_sysCatVerID; if (!IDBPolicy::useHdfs()) { int filedata[2]; filedata[0] = _verID; filedata[1] = _sysCatVerID; lseek(txnidfd, 0, SEEK_SET); int err = write(txnidfd, filedata, 8); if (err < 0) { perror("SessionManagerServer::newTxnID(): write(verid)"); throw runtime_error("SessionManagerServer::newTxnID(): write(verid) failed"); } } else { saveSMTxnIDAndState(); } return ret; }
SCSEP SelectSubQuery::transform() { idbassert(fSelSub); SCSEP csep(new CalpontSelectExecutionPlan()); csep->sessionID(fGwip.sessionid); csep->subType (CalpontSelectExecutionPlan::SELECT_SUBS); // gwi for the sub query gp_walk_info gwi; gwi.thd = fGwip.thd; gwi.subQuery = this; // @4632 merge table list to gwi in case there is FROM sub to be referenced // in the SELECT sub gwi.derivedTbCnt = fGwip.derivedTbList.size(); uint32_t tbCnt = fGwip.tbList.size(); gwi.tbList.insert(gwi.tbList.begin(), fGwip.tbList.begin(), fGwip.tbList.end()); gwi.derivedTbList.insert(gwi.derivedTbList.begin(), fGwip.derivedTbList.begin(), fGwip.derivedTbList.end()); if (getSelectPlan(gwi, *(fSelSub->get_select_lex()), csep) != 0) { if (!gwi.fatalParseError) { fGwip.fatalParseError = true; fGwip.parseErrorText = "Error occured in SelectSubQuery::transform()"; } else { fGwip.fatalParseError = gwi.fatalParseError; fGwip.parseErrorText = gwi.parseErrorText; } csep.reset(); return csep; } fGwip.subselectList.push_back(csep); // remove outer query tables CalpontSelectExecutionPlan::TableList tblist; if (csep->tableList().size() >= tbCnt) tblist.insert(tblist.begin(), csep->tableList().begin() + tbCnt, csep->tableList().end()); CalpontSelectExecutionPlan::SelectList derivedTbList; if (csep->derivedTableList().size() >= gwi.derivedTbCnt) derivedTbList.insert(derivedTbList.begin(), csep->derivedTableList().begin() + gwi.derivedTbCnt, csep->derivedTableList().end()); csep->tableList(tblist); csep->derivedTableList(derivedTbList); return csep; }
int FileBufferMgr::bulkInsert(const vector<CacheInsert_t> &ops) { uint32_t i; int32_t pi; int ret = 0; mutex::scoped_lock lk(fWLock); for (i = 0; i < ops.size(); i++) { const CacheInsert_t &op = ops[i]; if (gPMProfOn && gPMStatsPtr) #ifdef _MSC_VER gPMStatsPtr->markEvent(op.lbid, GetCurrentThreadId(), gSession, 'I'); #else gPMStatsPtr->markEvent(op.lbid, pthread_self(), gSession, 'I'); #endif HashObject_t fbIndex(op.lbid, op.ver, 0); filebuffer_pair_t pr = fbSet.insert(fbIndex); if (!pr.second) { if (gPMProfOn && gPMStatsPtr) #ifdef _MSC_VER gPMStatsPtr->markEvent(op.lbid, GetCurrentThreadId(), gSession, 'D'); #else gPMStatsPtr->markEvent(op.lbid, pthread_self(), gSession, 'D'); #endif continue; } //cout << "FBM: inserting <" << op.lbid << ", " << op.ver << endl; fCacheSize++; fBlksLoaded++; FBData_t fbdata = {op.lbid, op.ver, 0}; updateLRU(fbdata); pi = doBlockCopy(op.lbid, op.ver, op.data); HashObject_t &ref = const_cast<HashObject_t &>(*pr.first); ref.poolIdx = pi; fFBPool[pi].listLoc(fbList.begin()); if (gPMProfOn && gPMStatsPtr) #ifdef _MSC_VER gPMStatsPtr->markEvent(op.lbid, GetCurrentThreadId(), gSession, 'J'); #else gPMStatsPtr->markEvent(op.lbid, pthread_self(), gSession, 'J'); #endif ret++; } idbassert(fCacheSize <= maxCacheSize()); return ret; }
/** * This is invoked when a NOT function is got. It's usually the case NOT<IN optimizer> * This function will simple turn the semi join to anti join * */ void InSub::handleNot() { ParseTree *pt = fGwip.ptWorkStack.top(); ExistsFilter *subFilter = dynamic_cast<ExistsFilter*>(pt->data()); idbassert(subFilter); subFilter->notExists(true); SCSEP csep = subFilter->sub(); const ParseTree* ptsub = csep->filters(); if (ptsub) ptsub->walk(makeAntiJoin); ptsub = csep->having(); if (ptsub) ptsub->walk(makeAntiJoin); }
void Stats::touchedLBID(uint64_t lbid, pthread_t thdid, uint32_t session) { if (lbid < 0 || session == 0) return; mutex::scoped_lock lk(traceFileMapMutex); TraceFileMap_t::iterator iter = traceFileMap.find(session); if (iter == traceFileMap.end()) { traceFileMap[session] = TraceFileInfo(session); iter = traceFileMap.find(session); idbassert(iter != traceFileMap.end()); } iter->second.log(lbid2oid(lbid), lbid, thdid); }
void Stats::markEvent(const uint64_t lbid, const pthread_t thdid, const uint32_t session, const char event) { if (lbid < 0 || session == 0) return; mutex::scoped_lock lk(traceFileMapMutex); TraceFileMap_t::iterator iter = traceFileMap.find(session); if (iter == traceFileMap.end()) { traceFileMap[session] = TraceFileInfo(session, fName); iter = traceFileMap.find(session); idbassert(iter != traceFileMap.end()); } iter->second.log(lbid2oid(lbid), lbid, thdid, event); }
void DictStepJL::createCommand(ByteStream &bs) const { bs << (uint8_t) DICT_STEP; bs << BOP; bs << (uint8_t)compressionType; bs << filterCount; bs << (uint8_t) hasEqFilter; if (hasEqFilter) { idbassert(filterCount == eqFilter.size()); bs << eqOp; for (uint32_t i = 0; i < filterCount; i++) bs << eqFilter[i]; } else bs << filterString; CommandJL::createCommand(bs); }
int RF2::run(istream& in) { const streamsize ilinelen = 1024; scoped_array<char> iline(new char[ilinelen]); int cnt = 0; dmlif::DMLIF dmlif(fSessionID, fTflg, fDflg, fVflg); for (;;) { dmlif.rf2Start(fSchema); for (int i = 0; i < fPack; i++) { in.getline(iline.get(), ilinelen); if (in.eof()) break; typedef char_separator<char> cs; typedef tokenizer<cs> tk; cs sep("|"); tk tok(string(iline.get()), sep); tk::iterator iter = tok.begin(); idbassert(iter != tok.end()); string keystr = *iter; ++iter; //idbassert(iter == tok.end()); int64_t okey = strtol(keystr.c_str(), 0, 0); dmlif.rf2Add(okey); } dmlif.rf2Send(); cnt++; if ((cnt % fIntvl) == 0) dmlif.sendOne("COMMIT;"); if (in.eof()) break; } dmlif.sendOne("COMMIT;"); return 0; }
/*static*/ VBBMImpl* VBBMImpl::makeVBBMImpl(unsigned key, off_t size, bool readOnly) { boost::mutex::scoped_lock lk(fInstanceMutex); if (fInstance) { if (key != fInstance->fVBBM.key()) { BRMShmImpl newShm(key, size); fInstance->swapout(newShm); } idbassert(key == fInstance->fVBBM.key()); return fInstance; } fInstance = new VBBMImpl(key, size, readOnly); return fInstance; }
void WF_percentile<T>::parseParms(const std::vector<execplan::SRCP>& parms) { // parms[0]: nve ConstantColumn* cc = dynamic_cast<ConstantColumn*>(parms[0].get()); if (cc != NULL) { fNveNull = false; fNve = cc->getDoubleVal(fRow, fNveNull); // row not used, no need to setData. if (!fNveNull && (fNve < 0 || fNve > 1)) { ostringstream oss; oss << fNve; throw IDBExcept(IDBErrorInfo::instance()->errorMsg(ERR_WF_ARG_OUT_OF_RANGE, oss.str()), ERR_WF_ARG_OUT_OF_RANGE); } } // workaround for the within group order by column index idbassert(fPeer->fIndex.size() > 0); fFieldIndex.push_back(fPeer->fIndex[0]); }
void ColumnCommandJL::setLBID(uint64_t rid, uint dbRoot) { uint32_t partNum; uint16_t segNum; uint8_t extentNum; uint16_t blockNum; uint colWidth; uint i; idbassert(extents.size() > 0); colWidth = extents[0].colWid; rowgroup::getLocationFromRid(rid, &partNum, &segNum, &extentNum, &blockNum); for (i = 0; i < extents.size(); i++) { if (extents[i].dbRoot == dbRoot && extents[i].partitionNum == partNum && extents[i].segmentNum == segNum && extents[i].blockOffset == (extentNum * colWidth * 1024)) { lbid = extents[i].range.start + (blockNum * colWidth); /* ostringstream os; os << "CCJL: rid=" << rid << "; dbroot=" << dbRoot << "; partitionNum=" << partNum << "; segmentNum=" << segNum << "; extentNum = " << (int) extentNum << "; blockNum = " << blockNum << "; OID=" << OID << " LBID=" << lbid; cout << os.str() << endl; */ return; } } throw logic_error("ColumnCommandJL: setLBID didn't find the extent for the rid."); // ostringstream os; // os << "CCJL: rid=" << rid << "; dbroot=" << dbRoot << "; partitionNum=" << partitionNum << "; segmentNum=" << segmentNum << "; stripeWithinPartition=" << // stripeWithinPartition << "; OID=" << OID << " LBID=" << lbid; // BRM::log(os.str()); }
void SubAdapterStep::addExpression(const JobStepVector& exps, JobInfo& jobInfo) { // maps key to the index in the RG map<uint32_t, uint32_t> keyToIndexMap; const vector<uint32_t>& keys = fRowGroupIn.getKeys(); for (size_t i = 0; i < keys.size(); i++) keyToIndexMap[keys[i]] = i; // combine the expression to one parse tree ParseTree* filter = NULL; for (JobStepVector::const_iterator it = exps.begin(); it != exps.end(); it++) { ExpressionStep* e = dynamic_cast<ExpressionStep*>(it->get()); idbassert(e); e->updateInputIndex(keyToIndexMap, jobInfo); if (filter != NULL) { ParseTree* left = filter; ParseTree* right = new ParseTree(); right->copyTree(*(e->expressionFilter())); filter = new ParseTree(new LogicOperator("and")); filter->left(left); filter->right(right); } else { filter = new ParseTree(); filter->copyTree(*(e->expressionFilter())); } } // add to the expression wrapper if (fExpression.get() == NULL) fExpression.reset(new funcexp::FuncExpWrapper()); fExpression->addFilter(boost::shared_ptr<execplan::ParseTree>(filter)); }
execplan::ParseTree* ScalarSub::buildParseTree(PredicateOperator* op) { idbassert(fColumn.get() && fSub && fFunc); vector<SRCP> cols; Filter* filter; RowColumn* rcol = dynamic_cast<RowColumn*>(fColumn.get()); if (rcol) { // IDB only supports (c1,c2..) =/!= (subquery) if (fFunc->functype() != Item_func::EQ_FUNC && fFunc->functype() != Item_func::NE_FUNC) { fGwip.fatalParseError = true; fGwip.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_INVALID_OPERATOR_WITH_LIST); return NULL; } cols = rcol->columnVec(); } else cols.push_back(fColumn); SCSEP csep(new CalpontSelectExecutionPlan()); csep->sessionID(fGwip.sessionid); csep->location(CalpontSelectExecutionPlan::WHERE); csep->subType (CalpontSelectExecutionPlan::SINGLEROW_SUBS); // gwi for the sub query gp_walk_info gwi; gwi.thd = fGwip.thd; gwi.subQuery = this; // @4827 merge table list to gwi in case there is FROM sub to be referenced // in the FROM sub gwi.derivedTbCnt = fGwip.derivedTbList.size(); uint32_t tbCnt = fGwip.tbList.size(); gwi.tbList.insert(gwi.tbList.begin(), fGwip.tbList.begin(), fGwip.tbList.end()); gwi.derivedTbList.insert(gwi.derivedTbList.begin(), fGwip.derivedTbList.begin(), fGwip.derivedTbList.end()); if (getSelectPlan(gwi, *(fSub->get_select_lex()), csep) != 0) { //@todo more in error handling if (!gwi.fatalParseError) { fGwip.fatalParseError = true; fGwip.parseErrorText = "Error occured in ScalarSub::transform()"; } else { fGwip.fatalParseError = gwi.fatalParseError; fGwip.parseErrorText = gwi.parseErrorText; } return NULL; } fGwip.subselectList.push_back(csep); // error out non-support case for now: comparison out of semi join tables. // only check for simplecolumn if (!gwi.correlatedTbNameVec.empty()) { for (uint32_t i = 0; i < cols.size(); i++) { SimpleColumn* sc = dynamic_cast<SimpleColumn*>(cols[i].get()); if (sc) { CalpontSystemCatalog::TableAliasName tan = make_aliastable(sc->schemaName(), sc->tableName(), sc->tableAlias()); uint32_t j = 0; for (; j < gwi.correlatedTbNameVec.size(); j++) if (tan == gwi.correlatedTbNameVec[j]) break; if (j == gwi.correlatedTbNameVec.size()) { fGwip.fatalParseError = true; fGwip.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_NON_SUPPORT_SCALAR); return NULL; } } } } // remove outer query tables CalpontSelectExecutionPlan::TableList tblist; if (csep->tableList().size() >= tbCnt) tblist.insert(tblist.begin(), csep->tableList().begin() + tbCnt, csep->tableList().end()); CalpontSelectExecutionPlan::SelectList derivedTbList; if (csep->derivedTableList().size() >= gwi.derivedTbCnt) derivedTbList.insert(derivedTbList.begin(), csep->derivedTableList().begin() + gwi.derivedTbCnt, csep->derivedTableList().end()); csep->tableList(tblist); csep->derivedTableList(derivedTbList); // if (fSub->is_correlated) if (fSub->unit->first_select()->master_unit()->uncacheable) { SelectFilter* subFilter = new SelectFilter(); subFilter->correlated(true); subFilter->cols(cols); subFilter->sub(csep); subFilter->op(SOP(op)); subFilter->returnedColPos(fReturnedColPos); filter = subFilter; } else { SimpleScalarFilter* subFilter = new SimpleScalarFilter(); subFilter->cols(cols); subFilter->sub(csep); subFilter->op(SOP(op)); filter = subFilter; } return new ParseTree(filter); }
bool SubAdapterStep::deliverStringTableRowGroup() const { idbassert(fRowGroupOut.usesStringTable() == fRowGroupDeliver.usesStringTable()); return fRowGroupDeliver.usesStringTable(); }
/** MySQL transform (NOT) IN subquery to (NOT) EXIST * */ execplan::ParseTree* InSub::transform() { if (!fFunc) return NULL; // @todo need to handle scalar IN and BETWEEN specially // this blocks handles only one subselect scalar // arg[0]: column | arg[1]: subselect //assert (fFunc->argument_count() == 2 && fGwip.rcWorkStack.size() >= 2); if (fFunc->argument_count() != 2 || fGwip.rcWorkStack.size() < 2) { fGwip.fatalParseError = true; fGwip.parseErrorText = "Unsupported item in IN subquery"; return NULL; } ReturnedColumn* rhs = fGwip.rcWorkStack.top(); fGwip.rcWorkStack.pop(); delete rhs; ReturnedColumn* lhs = fGwip.rcWorkStack.top(); fGwip.rcWorkStack.pop(); delete lhs; fSub = (Item_subselect*)(fFunc->arguments()[1]); idbassert(fSub && fFunc); SCSEP csep (new CalpontSelectExecutionPlan()); csep->sessionID(fGwip.sessionid); csep->location(CalpontSelectExecutionPlan::WHERE); csep->subType (CalpontSelectExecutionPlan::IN_SUBS); // gwi for the sub query gp_walk_info gwi; gwi.thd = fGwip.thd; gwi.subQuery = this; // @4827 merge table list to gwi in case there is FROM sub to be referenced // in the FROM sub gwi.derivedTbCnt = fGwip.derivedTbList.size(); uint32_t tbCnt = fGwip.tbList.size(); gwi.tbList.insert(gwi.tbList.begin(), fGwip.tbList.begin(), fGwip.tbList.end()); gwi.derivedTbList.insert(gwi.derivedTbList.begin(), fGwip.derivedTbList.begin(), fGwip.derivedTbList.end()); if (getSelectPlan(gwi, *(fSub->get_select_lex()), csep) != 0) { fGwip.fatalParseError = true; if (gwi.fatalParseError && !gwi.parseErrorText.empty()) fGwip.parseErrorText = gwi.parseErrorText; else fGwip.parseErrorText = "Error occured in InSub::transform()"; return NULL; } // remove outer query tables CalpontSelectExecutionPlan::TableList tblist; if (csep->tableList().size() >= tbCnt) tblist.insert(tblist.begin(), csep->tableList().begin() + tbCnt, csep->tableList().end()); CalpontSelectExecutionPlan::SelectList derivedTbList; if (csep->derivedTableList().size() >= gwi.derivedTbCnt) derivedTbList.insert(derivedTbList.begin(), csep->derivedTableList().begin() + gwi.derivedTbCnt, csep->derivedTableList().end()); csep->tableList(tblist); csep->derivedTableList(derivedTbList); ExistsFilter* subFilter = new ExistsFilter(); subFilter->sub(csep); if (gwi.subQuery->correlated()) subFilter->correlated(true); else subFilter->correlated(false); if (fGwip.clauseType == HAVING && subFilter->correlated()) { fGwip.fatalParseError = true; fGwip.parseErrorText = logging::IDBErrorInfo::instance()->errorMsg(logging::ERR_NON_SUPPORT_HAVING); } fGwip.subselectList.push_back(csep); return new ParseTree(subFilter); }
const CalpontSystemCatalog::OID& VirtualTable::columnOid(uint32_t i) const { idbassert(i < fColumns.size()); return fColumns[i]->oid(); }
const CalpontSystemCatalog::ColType& VirtualTable::columnType(uint32_t i) const { idbassert(i < fColumnTypes.size()); return fColumnTypes[i]; }
void VirtualTable::columnType(CalpontSystemCatalog::ColType& type, uint32_t i) { idbassert(i < fColumnTypes.size()); fColumnTypes[i] = type; fColumns[i]->resultType(type); }