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; }
void PrintItemTree(Item* item, int indent) { #ifdef PURE_LIBRARY BHERROR("NOT IMPLEMENTED! Depends on MySQL code."); #else static const char* name_of[] = { "FIELD_ITEM", "FUNC_ITEM", "SUM_FUNC_ITEM", "STRING_ITEM", "INT_ITEM", "REAL_ITEM", "NULL_ITEM", "VARBIN_ITEM", "COPY_STR_ITEM", "FIELD_AVG_ITEM", "DEFAULT_VALUE_ITEM", "PROC_ITEM", "COND_ITEM", "REF_ITEM", "FIELD_STD_ITEM", "FIELD_VARIANCE_ITEM", "INSERT_VALUE_ITEM", "SUBSELECT_ITEM", "ROW_ITEM", "CACHE_ITEM", "TYPE_HOLDER", "PARAM_ITEM", "TRIGGER_FIELD_ITEM", "DECIMAL_ITEM", "XPATH_NODESET", "XPATH_NODESET_CMP", "VIEW_FIXER_ITEM" }; static const char* sum_name_of[] = { "COUNT_FUNC", "COUNT_DISTINCT_FUNC", "SUM_FUNC", "SUM_DISTINCT_FUNC", "AVG_FUNC", "AVG_DISTINCT_FUNC", "MIN_FUNC", "MAX_FUNC", "STD_FUNC", "VARIANCE_FUNC", "SUM_BIT_FUNC", "UDF_SUM_FUNC", "GROUP_CONCAT_FUNC" }; for(int i = 0; i <= indent; i++) fprintf(stderr, "*"); fprintf(stderr, " "); indent += 1; if(!item) { fprintf(stderr, "NULL item\n"); return; } const char* name; Item::Type type = item->type(); if((int)type < sizeof(name_of)/sizeof(*name_of)) name = name_of[type]; else name = "BHFIELD_ITEM"; const char* result = "<unknown result type>"; switch (item->result_type()) { case STRING_RESULT: result = "STRING_RESULT"; break; case INT_RESULT: result = "INT_RESULT"; break; case REAL_RESULT: result = "REAL_RESULT"; break; case DECIMAL_RESULT: result = "DECIMAL_RESULT"; break; } fprintf(stderr, "%s %s @%p %s %s max_length=%d", name, item->full_name(), (void*)item, FieldType(item->field_type()), result, item->max_length); if(item->result_type() == DECIMAL_RESULT) fprintf(stderr, " [prec=%d,dec=%d,int=%d]", item->decimal_precision(), (int)item->decimals, item->decimal_int_part()); switch(type) { case Item::FUNC_ITEM: { Item_func* func = static_cast <Item_func*> (item); fprintf(stderr, " func_name=%s\n", func->func_name()); String str; // GA, print function takes extra argument but do not use it in the base class. func->print(&str,QT_ORDINARY); fprintf(stderr, " f contents: %s\n", str.c_ptr_safe()); Item** args = func->arguments(); for(uint i = 0; i < func->argument_count(); i++) PrintItemTree(args[i], indent); return; } case Item::COND_ITEM: { Item_cond* cond = static_cast <Item_cond*> (item); fprintf(stderr, " func_name=%s\n", cond->func_name()); List_iterator<Item> li(*cond->argument_list()); Item* arg; while ((arg = li++)) PrintItemTree(arg, indent); return; } case Item::SUM_FUNC_ITEM: { Item_sum* sum_func = static_cast <Item_sum*> (item); uint index = sum_func->sum_func(); const char* sumname; if (index >= sizeof(sum_name_of)/sizeof(*sum_name_of)) sumname = "<UNKNOWN>"; else sumname = sum_name_of[index]; fprintf(stderr, " %s\n", sumname); Item** args = sum_func->args; uint args_count = sum_func->arg_count; for(uint i=0; i < args_count; i++) PrintItemTree(args[i], indent); return; } case Item::REF_ITEM: { Item_ref* ref = static_cast<Item_ref*> (item); Item* real = ref->real_item(); fprintf(stderr, "\n"); if(ref != real) PrintItemTree(real, indent); return; } case Item::INT_ITEM: { Item_int_with_ref* int_ref = dynamic_cast<Item_int_with_ref*>(item); if(!int_ref) break; // else item is an instance of Item_int_with_ref, not Item_int fprintf(stderr, " [Item_int_with_ref]\n"); PrintItemTree(int_ref->real_item(), indent); return; } case Item::SUBSELECT_ITEM: Item_subselect* ss = dynamic_cast<Item_subselect*>(item); fprintf(stderr, " subselect type %d\n", ss->substype()); String str; // GA, print function takes extra argument but do not use it. ss->get_unit()->print(&str, QT_ORDINARY); fprintf(stderr, "%s\n", str.c_ptr_safe()); } fprintf(stderr, "\n"); #endif }
static int is_columnstore_files_fill(THD* thd, TABLE_LIST* tables, COND* cond) { BRM::DBRM* emp = new BRM::DBRM(); BRM::OID_t cond_oid = 0; TABLE* table = tables->table; if (!emp || !emp->isDBRMReady()) { return 1; } if (cond && cond->type() == Item::FUNC_ITEM) { Item_func* fitem = (Item_func*) cond; if ((fitem->functype() == Item_func::EQ_FUNC) && (fitem->argument_count() == 2)) { if (fitem->arguments()[0]->real_item()->type() == Item::FIELD_ITEM && fitem->arguments()[1]->const_item()) { // WHERE object_id = value Item_field* item_field = (Item_field*) fitem->arguments()[0]->real_item(); if (strcasecmp(item_field->field_name.str, "object_id") == 0) { cond_oid = fitem->arguments()[1]->val_int(); return generate_result(cond_oid, emp, table, thd); } } else if (fitem->arguments()[1]->real_item()->type() == Item::FIELD_ITEM && fitem->arguments()[0]->const_item()) { // WHERE value = object_id Item_field* item_field = (Item_field*) fitem->arguments()[1]->real_item(); if (strcasecmp(item_field->field_name.str, "object_id") == 0) { cond_oid = fitem->arguments()[0]->val_int(); return generate_result(cond_oid, emp, table, thd); } } } else if (fitem->functype() == Item_func::IN_FUNC) { // WHERE object_id in (value1, value2) Item_field* item_field = (Item_field*) fitem->arguments()[0]->real_item(); if (strcasecmp(item_field->field_name.str, "object_id") == 0) { for (unsigned int i = 1; i < fitem->argument_count(); i++) { cond_oid = fitem->arguments()[i]->val_int(); int result = generate_result(cond_oid, emp, table, thd); if (result) return 1; } } } else if (fitem->functype() == Item_func::UNKNOWN_FUNC && strcasecmp(fitem->func_name(), "find_in_set") == 0) { // WHERE FIND_IN_SET(object_id, values) String* tmp_var = fitem->arguments()[1]->val_str(); std::stringstream ss(tmp_var->ptr()); while (ss >> cond_oid) { int ret = generate_result(cond_oid, emp, table, thd); if (ret) return 1; if (ss.peek() == ',') ss.ignore(); } }