FunctionColumn::FunctionColumn( const FunctionColumn& rhs, const uint32_t sessionID): ReturnedColumn(rhs, sessionID), fFunctionName(rhs.functionName()), fTableAlias (rhs.tableAlias()), fData (rhs.data()), fFunctor(rhs.fFunctor) { fFunctionParms.clear(); fSimpleColumnList.clear(); fAggColumnList.clear(); fWindowFunctionColumnList.clear(); SPTP pt; for (uint32_t i = 0; i < rhs.fFunctionParms.size(); i++) { pt.reset(new ParseTree (*(rhs.fFunctionParms[i]))); fFunctionParms.push_back(pt); pt->walk(getSimpleCols, &fSimpleColumnList); pt->walk(getAggCols, &fAggColumnList); pt->walk(getWindowFunctionCols, &fWindowFunctionColumnList); } fAlias = rhs.alias(); }
void FunctionColumn::unserialize(messageqcpp::ByteStream& b) { uint32_t size, i; //SRCP rc; SPTP pt; FunctionParm::iterator it; fFunctionParms.erase(fFunctionParms.begin(), fFunctionParms.end()); fSimpleColumnList.clear(); fAggColumnList.clear(); fWindowFunctionColumnList.clear(); ObjectReader::checkType(b, ObjectReader::FUNCTIONCOLUMN); ReturnedColumn::unserialize(b); b >> fFunctionName; b >> size; for (i = 0; i < size; i++) { pt.reset(ObjectReader::createParseTree(b)); fFunctionParms.push_back(pt); pt->walk(getSimpleCols, &fSimpleColumnList); pt->walk(getAggCols, &fAggColumnList); pt->walk(getWindowFunctionCols, &fWindowFunctionColumnList); } b >> fTableAlias; b >> fData; FuncExp* funcExp = FuncExp::instance(); fFunctor = funcExp->getFunctor(fFunctionName); // @bug 3506. Special treatment for rand() function. reset the seed Func_rand* rand = dynamic_cast<Func_rand*>(fFunctor); if (rand) rand->seedSet(false); }
OuterJoinOnFilter::OuterJoinOnFilter(const SPTP& pt): fPt(new ParseTree (*(pt.get()))), fData("Outer Join On Filter") {}
execplan::ReturnedColumn* buildPseudoColumn(Item* item, gp_walk_info& gwi, bool& nonSupport, uint32_t pseudoType) { Item_func* ifp = (Item_func*)item; // idblocalpm is replaced by constant if (pseudoType == PSEUDO_LOCALPM) { int64_t localPm = idblocalpm(); ConstantColumn* cc; if (localPm) cc = new ConstantColumn(localPm); else cc = new ConstantColumn("", ConstantColumn::NULLDATA); cc->alias(ifp->name? ifp->name : ""); return cc; } // convert udf item to pseudocolumn item. // adjust result type // put arg col to column map string funcName = ifp->func_name(); if (ifp->arg_count != 1 || !(ifp->arguments()) || !(ifp->arguments()[0]) || ifp->arguments()[0]->type() != Item::FIELD_ITEM) return nullOnError(gwi, funcName); Item_field* field = (Item_field*)(ifp->arguments()[0]); // @todo rule out derive table if (!field->field || !field->db_name || strlen(field->db_name) == 0) return nullOnError(gwi, funcName); SimpleColumn *sc = buildSimpleColumn(field, gwi); if (!sc) return nullOnError(gwi, funcName); if ((pseudoType == PSEUDO_EXTENTMIN || pseudoType == PSEUDO_EXTENTMAX) && (sc->colType().colDataType == CalpontSystemCatalog::VARBINARY || (sc->colType().colDataType == CalpontSystemCatalog::VARCHAR && sc->colType().colWidth > 7) || (sc->colType().colDataType == CalpontSystemCatalog::CHAR && sc->colType().colWidth > 8))) return nullOnError(gwi, funcName); // put arg col to column map if (gwi.clauseType == SELECT || gwi.clauseType == GROUP_BY) // select clause { SRCP srcp(sc); gwi.columnMap.insert(CalpontSelectExecutionPlan::ColumnMap::value_type(sc->columnName(), srcp)); gwi.tableMap[make_aliastable(sc->schemaName(), sc->tableName(), sc->tableAlias(), sc->isInfiniDB())] = make_pair(1, field->cached_table); } else if (!gwi.rcWorkStack.empty()) { gwi.rcWorkStack.pop(); } if (pseudoType == PSEUDO_PARTITION) { // parms: psueducolumn dbroot, segmentdir, segment SPTP sptp; FunctionColumn *fc = new FunctionColumn(funcName); funcexp::FunctionParm parms; PseudoColumn *dbroot = new PseudoColumn(*sc, PSEUDO_DBROOT); sptp.reset(new ParseTree(dbroot)); parms.push_back(sptp); PseudoColumn *pp = new PseudoColumn(*sc, PSEUDO_SEGMENTDIR); sptp.reset(new ParseTree(pp)); parms.push_back(sptp); PseudoColumn* seg = new PseudoColumn(*sc, PSEUDO_SEGMENT); sptp.reset(new ParseTree(seg)); parms.push_back(sptp); fc->functionParms(parms); fc->expressionId(gwi.expressionId++); // string result type CalpontSystemCatalog::ColType ct; ct.colDataType = CalpontSystemCatalog::VARCHAR; ct.colWidth = 256; fc->resultType(ct); // operation type integer funcexp::Func_idbpartition* idbpartition = new funcexp::Func_idbpartition(); fc->operationType(idbpartition->operationType(parms, fc->resultType())); fc->alias(ifp->name? ifp->name : ""); return fc; } PseudoColumn *pc = new PseudoColumn(*sc, pseudoType); // @bug5892. set alias for derived table column matching. pc->alias(ifp->name? ifp->name : ""); return pc; }
ReturnedColumn* buildBoundExp(WF_Boundary& bound, SRCP& order, gp_walk_info& gwi) { 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); bool addOp = true; ReturnedColumn* rc = NULL; if (bound.fFrame == execplan::WF_PRECEDING) { if (order->asc()) addOp = false; } else if (!order->asc()) // must be WF_FOLLOWING addOp = false; funcexp::FunctionParm funcParms; SPTP sptp; IntervalColumn* intervalCol = dynamic_cast<IntervalColumn*>(bound.fVal.get()); // @todo error out non constant. only support literal interval for now. if (!intervalCol && order->resultType().colDataType == CalpontSystemCatalog::DATE) { intervalCol = new IntervalColumn(bound.fVal, (int)IntervalColumn::INTERVAL_DAY); bound.fVal.reset(intervalCol); } if (intervalCol) { // date_add rc = new FunctionColumn(); string funcName = "date_add_interval"; // @bug6061 . YEAR, QUARTER, MONTH, WEEK, DAY type CalpontSystemCatalog::ColType ct; if (order->resultType().colDataType == CalpontSystemCatalog::DATE && intervalCol->intervalType() <= IntervalColumn::INTERVAL_DAY) { ct.colDataType = CalpontSystemCatalog::DATE; ct.colWidth = 4; } else { ct.colDataType = CalpontSystemCatalog::DATETIME; ct.colWidth = 8; } // put interval val column to bound (dynamic_cast<FunctionColumn*>(rc))->functionName(funcName); sptp.reset(new ParseTree(order->clone())); funcParms.push_back(sptp); sptp.reset(new ParseTree(intervalCol->val()->clone())); funcParms.push_back(sptp); funcParms.push_back(getIntervalType(intervalCol->intervalType())); SRCP srcp(intervalCol->val()); bound.fVal = srcp; if (addOp) { sptp.reset(new ParseTree(new ConstantColumn("ADD"))); funcParms.push_back(sptp); } else { sptp.reset(new ParseTree(new ConstantColumn("SUB"))); funcParms.push_back(sptp); } (dynamic_cast<FunctionColumn*>(rc))->functionParms(funcParms); rc->resultType(ct); // @bug6061. Use result type as operation type for WF bound expression rc->operationType(ct); rc->expressionId(ci->expressionId++); return rc; } // arithmetic rc = new ArithmeticColumn(); ArithmeticOperator* aop; if (addOp) aop = new ArithmeticOperator("+"); else aop = new ArithmeticOperator("-"); ParseTree *pt = new ParseTree(aop); ParseTree *lhs = 0, *rhs = 0; lhs = new ParseTree(order->clone()); rhs = new ParseTree(bound.fVal->clone()); pt->left(lhs); pt->right(rhs); aop->resultType(order->resultType()); aop->operationType(aop->resultType()); (dynamic_cast<ArithmeticColumn*>(rc))->expression(pt); rc->resultType(aop->resultType()); rc->operationType(aop->operationType()); rc->expressionId(ci->expressionId++); return rc; }