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);
}
Exemplo n.º 2
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
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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");
}
Exemplo n.º 6
0
/**
* 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;
}
Exemplo n.º 7
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);
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
0
void TupleConstantOnlyStep::fillInConstants()
{
	fRowGroupOut.getRow(0, &fRowOut);
	idbassert(fRowConst.getSize() == fRowOut.getSize());
	copyRow(fRowConst, &fRowOut);
	fRowGroupOut.resetRowGroup(0);
	fRowGroupOut.setRowCount(1);
	fRowsReturned = 1;
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 15
0
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;
}
Exemplo n.º 16
0
/**
 * 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);
}
Exemplo n.º 17
0
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);
}
Exemplo n.º 18
0
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);
}
Exemplo n.º 19
0
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;
}
Exemplo n.º 21
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;
}
Exemplo n.º 22
0
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]);
}
Exemplo n.º 23
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());
}
Exemplo n.º 24
0
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);

}
Exemplo n.º 26
0
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);
}
Exemplo n.º 28
0
const CalpontSystemCatalog::OID& VirtualTable::columnOid(uint32_t i) const
{
	idbassert(i < fColumns.size());
	return fColumns[i]->oid();
}
Exemplo n.º 29
0
const CalpontSystemCatalog::ColType& VirtualTable::columnType(uint32_t i) const
{
	idbassert(i < fColumnTypes.size());
	return fColumnTypes[i];
}
Exemplo n.º 30
0
void VirtualTable::columnType(CalpontSystemCatalog::ColType& type, uint32_t i)
{
	idbassert(i < fColumnTypes.size());
	fColumnTypes[i] = type;
	fColumns[i]->resultType(type);
}