Example #1
0
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();
            }
        }