Beispiel #1
0
void SimpleColumn::setOID()
{
	boost::shared_ptr<CalpontSystemCatalog> csc = CalpontSystemCatalog::makeCalpontSystemCatalog(fSessionID);
	CalpontSystemCatalog::TableColName tcn;
	tcn = make_tcn(fSchemaName, fTableName, fColumnName);

	fOid = csc->lookupOID (tcn);
	if (fOid == -1)
	{
		// get colMap from CalpontSelectExecutionPlan
		// and try to map the schema and table name
		CalpontSelectExecutionPlan::ColumnMap::iterator iter;
		CalpontSelectExecutionPlan::ColumnMap colMap = CalpontSelectExecutionPlan::colMap();

		// if this is the only column name exist in the map, return it ??
		for (iter = colMap.find(fColumnName); iter != colMap.end(); ++iter)
		{
			SRCP srcp = iter->second;
			SimpleColumn* scp = dynamic_cast<SimpleColumn*>(srcp.get());
			if (colMap.count(fColumnName) == 1 ||
			    scp->tableName().compare(fTableName) == 0)
			{
				fOid = scp->oid();
				//@bug 221 fix
				fTableName = scp->tableName();
				fSchemaName = scp->schemaName();
				//@info assign tableAlias also. watch for other conflict
				fTableAlias = scp->tableAlias();
				fResultType = scp->resultType();
				return;
			}
		}
	}
	fResultType = csc->colType(fOid);
}
Beispiel #2
0
RowColumn::RowColumn (const RowColumn& rhs, const uint32_t sessionID):
                ReturnedColumn(rhs, sessionID)                
{
	fColumnVec.clear();
	//fColumnVec = rhs.fColumnVec;
	SRCP srcp;
	for (uint32_t i = 0; i < rhs.fColumnVec.size(); i++)
	{
		srcp.reset(rhs.fColumnVec[i]->clone());
		fColumnVec.push_back(srcp);
	}
}
void CalpontSelectExecutionPlan::columnMap (const ColumnMap& columnMap)
{
	ColumnMap::const_iterator map_it1, map_it2;
	fColumnMap.erase(fColumnMap.begin(), fColumnMap.end());

	SRCP srcp;
	for (map_it2 = columnMap.begin(); map_it2 != columnMap.end(); ++map_it2)
	{
		srcp.reset(map_it2->second->clone());
		fColumnMap.insert(ColumnMap::value_type(map_it2->first, srcp));
	}
}
Beispiel #4
0
void RowColumn::unserialize(messageqcpp::ByteStream& b)
{
	fColumnVec.clear();
	ObjectReader::checkType(b, ObjectReader::ROWCOLUMN);
	ReturnedColumn::unserialize(b);
	uint32_t size;
	SRCP srcp;
	b >> (uint32_t&)size;
	for (uint32_t i = 0; i < size; i++)
	{
		srcp.reset(dynamic_cast<ReturnedColumn*>((ObjectReader::createTreeNode(b))));
		fColumnVec.push_back(srcp);
	}
}
void SelectFilter::unserialize(messageqcpp::ByteStream& b)
{
    ObjectReader::checkType(b, ObjectReader::SELECTFILTER);

    Filter::unserialize(b);
    fCols.clear();
    uint32_t size;
    SRCP srcp;
    b >> size;

    for (uint32_t i = 0; i < size; i++)
    {
        srcp.reset(dynamic_cast<ReturnedColumn*>(ObjectReader::createTreeNode(b)));
        fCols.push_back(srcp);
    }

    fOp.reset(dynamic_cast<Operator*>(ObjectReader::createTreeNode(b)));
    fSub.reset(dynamic_cast<CalpontSelectExecutionPlan*>(ObjectReader::createExecutionPlan(b)));
    b >> static_cast<uint64_t&>(fReturnedColPos);
}
Beispiel #6
0
void* ing_opentbl(void* qctx, const char* sn, const char* tn)
{
try {
	if (!qctx) return 0;
	if (!sn) return 0;
	if (!tn) return 0;
	if (strlen(sn) == 0) return 0;
	if (strlen(tn) == 0) return 0;

	IngQCtx* ingQctx = reinterpret_cast<IngQCtx*>(qctx);
	cpsm_conhdl_t* cal_conn_hndl = reinterpret_cast<cpsm_conhdl_t*>(ingQctx->dhcs_ses_ctx);
	IngTCtx* tctx = new IngTCtx();

	dhcs_tableid_t tableid = 0;
	//tableid = tbname2id(sn, tn, cal_conn_hndl);
	tableid = tbname2id("te", "f_trans", cal_conn_hndl);

	RequiredColOidSet requiredColOidSet;
	const CalpontSelectExecutionPlan::ColumnMap colMap = ingQctx->csep.columnMap();
	CalpontSelectExecutionPlan::ColumnMap::const_iterator colIter = colMap.begin();
	CalpontSelectExecutionPlan::ColumnMap::const_iterator colend = colMap.end();
	while (colIter != colend)
	{
		SRCP srcp = colIter->second;
		SimpleColumn* scp = dynamic_cast<SimpleColumn*>(srcp.get());
		if (scp)
			requiredColOidSet.insert(scp->oid());
		++colIter;
	}
	tctx->dhcs_tpl_ctx = new cpsm_tplh_t();
	dhcs_tpl_open(tableid, &tctx->dhcs_tpl_ctx, ingQctx->dhcs_ses_ctx, requiredColOidSet);
	tctx->dhcs_tpl_scan_ctx = new cpsm_tplsch_t();
	dhcs_tpl_scan_open(tableid, DHCS_TPL_FH_READ, &tctx->dhcs_tpl_scan_ctx, ingQctx->dhcs_ses_ctx);

	return tctx;
} catch (...) {
}
	return NULL;
}
void addAggregateColumn(AggregateColumn* agc, int idx, RetColsVector& vec, JobInfo& jobInfo)
{
    uint32_t eid = agc->expressionId();
    setExpTupleInfo(agc->resultType(), eid, agc->alias(), jobInfo);

    vector<pair<int, int> >::iterator i;

    for (i = jobInfo.aggEidIndexList.begin(); i != jobInfo.aggEidIndexList.end(); ++i)
    {
        if (i->first == (int) eid)
            break;
    }

    if (idx < 0 && i != jobInfo.aggEidIndexList.end())
    {
        agc->inputIndex(i->second);
        jobInfo.cloneAggregateColMap.insert(make_pair(vec[i->second].get(), agc));
    }
    else
    {
        SRCP srcp;

        if (idx < 0)
        {
            srcp.reset(agc->clone());
            idx = vec.size();
            vec.push_back(srcp);
        }
        else
        {
            srcp = vec[idx];
        }

        jobInfo.aggEidIndexList.push_back(make_pair(eid, idx));
        agc->inputIndex(idx);
        jobInfo.cloneAggregateColMap.insert(make_pair(srcp.get(), agc));
    }
}
Beispiel #8
0
void VirtualTable::addColumn(const SRCP& column)
{
	// As of bug3695, make sure varbinary is not used in subquery.
	if (column->resultType().colDataType == CalpontSystemCatalog::VARBINARY && !fVarBinOK)
		throw runtime_error ("VARBINARY in subquery is not supported.");

	AggregateColumn*      agc = NULL;
	ArithmeticColumn*     arc = NULL;
	ConstantColumn*       cc  = NULL;
	FunctionColumn*       fc  = NULL;
	SimpleColumn*         sc  = NULL;
	WindowFunctionColumn* wc  = NULL;

	string columnName;
	ostringstream oss;
	UniqId colId;
	if ((sc = dynamic_cast<SimpleColumn*>(column.get())) != NULL)
	{
		columnName = sc->columnName();
		colId = UniqId(sc);
	}
	else if ((agc = dynamic_cast<AggregateColumn*>(column.get())) != NULL)
	{
//		oss << agc->functionName() << "_" << agc->expressionId();
//		oss << "Aggregate_" << agc->expressionId();
		columnName = agc->data();
		colId = UniqId(agc->expressionId(), "", "", "");
	}
	else if ((wc = dynamic_cast<WindowFunctionColumn*>(column.get())) != NULL)
	{
//		oss << wc->functionName() << "_" << wc->expressionId();
//		oss << "Window_" << wc->expressionId();
		columnName = wc->data();
		colId = UniqId(wc->expressionId(), "", "", "");
	}
	else if ((arc = dynamic_cast<ArithmeticColumn*>(column.get())) != NULL)
	{
//		oss << "Arithmetic_" << arc->expressionId();
		columnName = arc->data();
		colId = UniqId(arc->expressionId(), "", "", "");
	}
	else if ((fc = dynamic_cast<FunctionColumn*>(column.get())) != NULL)
	{
//		oss << fc->functionName() << "_" << fc->expressionId();
		columnName = fc->data();
		colId = UniqId(fc->expressionId(), "", "", "");
	}
	else if ((cc = dynamic_cast<ConstantColumn*>(column.get())) != NULL)
	{
//		oss << "Constant_" << cc->expressionId();
		columnName = cc->data();
		colId = UniqId(cc->expressionId(), cc->alias(), "", fView);
	}
	else // new column type has added, but this code is not updated.
	{
		oss << "not supported column type: " << typeid(*(column.get())).name();
		throw runtime_error(oss.str());
	}

	if (columnName.empty())
		columnName = column->alias();

	SimpleColumn* vc = new SimpleColumn();
	vc->tableName(fName);
	vc->tableAlias(fAlias);
	vc->columnName(columnName);
	vc->alias(column->alias());
	vc->viewName(fView);

	uint32_t index = fColumns.size();
	vc->colPosition(index);
	vc->oid(fTableOid+index+1);
	vc->resultType(column->resultType());

	SSC ssc(vc);
	fColumns.push_back(ssc);
	fColumnTypes.push_back(column->resultType());
	fColumnMap.insert(make_pair(colId, index));
}
Beispiel #9
0
uint32_t getTupleKey(JobInfo& jobInfo, const SRCP& srcp, bool add)
{
	int key = -1;

	if (add)
	{
		// setTupleInfo first if add is ture, ok if already set.
		const SimpleColumn* sc = dynamic_cast<const SimpleColumn*>(srcp.get());
		if (sc != NULL)
		{
			if (sc->schemaName().empty())
			{
				SimpleColumn tmp(*sc, jobInfo.sessionId);
				tmp.oid(tableOid(sc, jobInfo.csc) + 1 + sc->colPosition());
				key = getTupleKey(jobInfo, &tmp); // sub-query should be there
			}
			else
			{
				erydbSystemCatalog::ColType ct = sc->colType();
				string alias(extractTableAlias(sc));
				erydbSystemCatalog::OID tblOid = tableOid(sc, jobInfo.csc);
				TupleInfo ti(setTupleInfo(ct, sc->oid(), jobInfo, tblOid, sc, alias));
				key = ti.key;

				erydbSystemCatalog::OID dictOid = isDictCol(ct);
				if (dictOid > 0)
				{
					ti = setTupleInfo(ct, dictOid, jobInfo, tblOid, sc, alias);
					jobInfo.keyInfo->dictKeyMap[key] = ti.key;
					key = ti.key;
				}
			}
		}
		else
		{
			erydbSystemCatalog::ColType ct = srcp->resultType();
			TupleInfo ti(setExpTupleInfo(ct, srcp->expressionId(), srcp->alias(), jobInfo));
			key = ti.key;
		}
	}
	else
	{
		// TupleInfo is expected to be set already
		const SimpleColumn* sc = dynamic_cast<const SimpleColumn*>(srcp.get());
		if (sc != NULL)
		{
			if (sc->schemaName().empty())
			{
				SimpleColumn tmp(*sc, jobInfo.sessionId);
				tmp.oid(tableOid(sc, jobInfo.csc) + 1 + sc->colPosition());
				key = getTupleKey(jobInfo, &tmp);
			}
			else
			{
				key = getTupleKey(jobInfo, sc);
			}

			// check if this is a dictionary column
			if (jobInfo.keyInfo->dictKeyMap.find(key) != jobInfo.keyInfo->dictKeyMap.end())
				key = jobInfo.keyInfo->dictKeyMap[key];
		}
		else
		{
			key = getExpTupleKey(jobInfo, srcp->expressionId());
		}
	}

	return key;
}
Beispiel #10
0
ReturnedColumn* buildWindowFunctionColumn(Item* item, gp_walk_info& gwi, bool& nonSupport)
{
	//@todo fix print for create view
	//String str;
	//item->print(&str, QT_INFINIDB_NO_QUOTE);
	//cout << str.c_ptr() << endl;
	if (!(gwi.thd->infinidb_vtable.cal_conn_info))
		gwi.thd->infinidb_vtable.cal_conn_info = (void*)(new cal_connection_info());
	cal_connection_info* ci = reinterpret_cast<cal_connection_info*>(gwi.thd->infinidb_vtable.cal_conn_info);

	gwi.hasWindowFunc = true;
	Item_func_window* wf = (Item_func_window*)item;
	string funcName = wf->func_name();
	WindowFunctionColumn* ac = new WindowFunctionColumn(funcName);
	ac->distinct(wf->isDistinct());
	Window_context *wf_ctx = wf->window_ctx();
	SRCP srcp;

	// arguments
	vector<SRCP> funcParms;
	for (uint32_t i = 0; i < wf->arg_count; i++)
	{
		srcp.reset(buildReturnedColumn(wf->arguments()[i], gwi, nonSupport));
		if (!srcp)
			return nullOnError(gwi);
		funcParms.push_back(srcp);
		if (gwi.clauseType == WHERE && !gwi.rcWorkStack.empty())
			gwi.rcWorkStack.pop();
	}
	ac->functionParms(funcParms);

	// Partition by
	if (wf_ctx)
	{
		vector<SRCP> partitions;
		for (uint32_t i = 0; i < wf_ctx->partition_count; i++)
		{
			srcp.reset(buildReturnedColumn(wf_ctx->partitions[i], gwi, nonSupport));
			if (!srcp)
				return nullOnError(gwi);
			partitions.push_back(srcp);
		}
		ac->partitions(partitions);

		// Order by
		if (wf_ctx->ordering)
		{
			WF_OrderBy orderBy;
			// order columns
			if (wf_ctx->ordering->orders)
			{
				vector<SRCP> orders;
				ORDER* orderCol = reinterpret_cast<ORDER*>(wf_ctx->ordering->orders->first);
				for (; orderCol; orderCol= orderCol->next)
				{
					Item* orderItem = *(orderCol->item);
					srcp.reset(buildReturnedColumn(orderItem, gwi, nonSupport));
					if (!srcp)
						return nullOnError(gwi);
					srcp->asc(orderCol->asc);
					srcp->nullsFirst(orderCol->nulls); // nulls 1-nulls first 0-nulls last
					orders.push_back(srcp);
				}
				orderBy.fOrders = orders;
			}

			// window frame
			WF_Frame frm;
			if (wf_ctx->ordering->frame)
			{
				frm.fIsRange = wf_ctx->ordering->frame->isRange;
				// start
				if (wf_ctx->ordering->frame->start)
				{
					frm.fStart.fFrame = frame(wf_ctx->ordering->frame->start->bound);

					if (wf_ctx->ordering->frame->start->item)
					{
						frm.fStart.fVal.reset(buildReturnedColumn(wf_ctx->ordering->frame->start->item, gwi, nonSupport));
						if (!frm.fStart.fVal)
							return nullOnError(gwi);

						// 1. check expr is numeric type (rows) or interval (range)
						bool boundTypeErr = false;
						switch (frm.fStart.fVal->resultType().colDataType)
						{
							case CalpontSystemCatalog::CHAR:
							case CalpontSystemCatalog::VARCHAR:
							case CalpontSystemCatalog::VARBINARY:
							case CalpontSystemCatalog::BLOB:
							case CalpontSystemCatalog::CLOB:
								boundTypeErr = true;
								break;
							case CalpontSystemCatalog::DATE:
							case CalpontSystemCatalog::DATETIME:
								if (!frm.fIsRange)
									boundTypeErr = true;
								else if (dynamic_cast<IntervalColumn*>(frm.fStart.fVal.get()) == NULL)
									boundTypeErr = true;
								break;
							default: //okay
								break;
						}
						if (boundTypeErr)
						{
							gwi.fatalParseError = true;
							gwi.parseErrorText =
							   logging::IDBErrorInfo::instance()->errorMsg(logging::ERR_WF_INVALID_BOUND_TYPE,
							                colDataTypeToString(frm.fStart.fVal->resultType().colDataType));
							return nullOnError(gwi);
						}
					}
				}

				// end
				if (wf_ctx->ordering->frame->end)
				{
					frm.fEnd.fFrame = frame(wf_ctx->ordering->frame->end->bound);
					if (wf_ctx->ordering->frame->end->item)
					{
						frm.fEnd.fVal.reset(buildReturnedColumn(wf_ctx->ordering->frame->end->item, gwi, nonSupport));
						if (!frm.fEnd.fVal)
							return nullOnError(gwi);

						// check expr is numeric type (rows) or interval (range)
						bool boundTypeErr = false;
						switch (frm.fEnd.fVal->resultType().colDataType)
						{
							case CalpontSystemCatalog::CHAR:
							case CalpontSystemCatalog::VARCHAR:
							case CalpontSystemCatalog::VARBINARY:
							case CalpontSystemCatalog::BLOB:
							case CalpontSystemCatalog::CLOB:
								boundTypeErr = true;
								break;
							case CalpontSystemCatalog::DATE:
							case CalpontSystemCatalog::DATETIME:
								if (!frm.fIsRange)
									boundTypeErr = true;
								else if (dynamic_cast<IntervalColumn*>(frm.fEnd.fVal.get()) == NULL)
									boundTypeErr = true;
								break;
							default: //okay
								break;
						}
						if (boundTypeErr)
						{
							gwi.fatalParseError = true;
							gwi.parseErrorText =
							   logging::IDBErrorInfo::instance()->errorMsg(logging::ERR_WF_INVALID_BOUND_TYPE,
							                colDataTypeToString(frm.fStart.fVal->resultType().colDataType));
							return nullOnError(gwi);
						}
					}
				}
				else // no end specified. default end to current row
				{
					frm.fEnd.fFrame = WF_CURRENT_ROW;
				}

				if (frm.fStart.fVal || frm.fEnd.fVal)
				{
					// check order by key only 1 (should be error-ed out in parser. double check here)
					if (frm.fIsRange && orderBy.fOrders.size() > 1)
					{
						gwi.fatalParseError = true;
						gwi.parseErrorText =
						   logging::IDBErrorInfo::instance()->errorMsg(logging::ERR_WF_INVALID_ORDER_KEY);
						return nullOnError(gwi);
					}

					// check order by key type is numeric or date/datetime
					bool orderTypeErr = false;
					if (frm.fIsRange && orderBy.fOrders.size() == 1)
					{
						switch (orderBy.fOrders[0]->resultType().colDataType)
						{
							case CalpontSystemCatalog::CHAR:
							case CalpontSystemCatalog::VARCHAR:
							case CalpontSystemCatalog::VARBINARY:
							case CalpontSystemCatalog::BLOB:
							case CalpontSystemCatalog::CLOB:
								orderTypeErr = true;
								break;
							default: //okay
								// interval bound has to have date/datetime order key
								if ((dynamic_cast<IntervalColumn*>(frm.fStart.fVal.get()) != NULL ||
									  dynamic_cast<IntervalColumn*>(frm.fEnd.fVal.get()) != NULL))
								{
									if (orderBy.fOrders[0]->resultType().colDataType != CalpontSystemCatalog::DATE &&
									   orderBy.fOrders[0]->resultType().colDataType != CalpontSystemCatalog::DATETIME)
										orderTypeErr = true;
								}
								else
								{
									if (orderBy.fOrders[0]->resultType().colDataType == CalpontSystemCatalog::DATETIME)
										orderTypeErr = true;
								}
								break;
						}
						if (orderTypeErr)
						{
							gwi.fatalParseError = true;
							gwi.parseErrorText =
								   logging::IDBErrorInfo::instance()->errorMsg(logging::ERR_WF_INVALID_ORDER_TYPE,
								             colDataTypeToString(orderBy.fOrders[0]->resultType().colDataType));
							return nullOnError(gwi);
						}
					}
				}

				// construct +,- or interval function for boundary
				if (frm.fIsRange && frm.fStart.fVal)
				{
					frm.fStart.fBound.reset(buildBoundExp(frm.fStart, orderBy.fOrders[0], gwi));
					if (!frm.fStart.fBound)
						return nullOnError(gwi);
				}
				if (frm.fIsRange && frm.fEnd.fVal)
				{
					frm.fEnd.fBound.reset(buildBoundExp(frm.fEnd, orderBy.fOrders[0], gwi));
					if (!frm.fEnd.fVal)
						return nullOnError(gwi);
				}
			}
			else
			{
				frm.fStart.fFrame = WF_UNBOUNDED_PRECEDING;
				frm.fEnd.fFrame = WF_CURRENT_ROW;
			}

			orderBy.fFrame = frm;
			ac->orderBy(orderBy);
		}
	}

	if (gwi.fatalParseError || nonSupport)
	{
		if (gwi.parseErrorText.empty())
			gwi.parseErrorText = logging::IDBErrorInfo::instance()->errorMsg(logging::ERR_WF_NON_SUPPORT);
		setError(gwi.thd, HA_ERR_UNSUPPORTED, gwi.parseErrorText);
		return NULL;
	}

	ac->resultType(colType_MysqlToIDB(wf));

	// bug5736. Make the result type double for some window functions when
	// infinidb_double_for_decimal_math is set.
	ac->adjustResultType();

	ac->expressionId(ci->expressionId++);
	if (item->name)
		ac->alias(item->name);
	
	// put ac on windowFuncList
	gwi.windowFuncList.push_back(ac);
	return ac;
	
}