MXS-1364 Improve collection of arguments to IN
This commit is contained in:
parent
17db8e9705
commit
c34140abd8
@ -2456,6 +2456,21 @@ static void add_function_field_usage(st_select_lex* select,
|
||||
}
|
||||
}
|
||||
|
||||
static void add_function_field_usage(st_select_lex* select,
|
||||
st_select_lex* sub_select,
|
||||
QC_FUNCTION_INFO* fi)
|
||||
{
|
||||
List_iterator<Item> ilist(sub_select->item_list);
|
||||
|
||||
while (Item *item = ilist++)
|
||||
{
|
||||
if (item->type() == Item::FIELD_ITEM)
|
||||
{
|
||||
add_function_field_usage(select, static_cast<Item_field*>(item), fi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static QC_FUNCTION_INFO* get_function_info(parsing_info_t* info, const char* name)
|
||||
{
|
||||
QC_FUNCTION_INFO* function_info = NULL;
|
||||
@ -2496,15 +2511,17 @@ static QC_FUNCTION_INFO* get_function_info(parsing_info_t* info, const char* nam
|
||||
return function_info;
|
||||
}
|
||||
|
||||
static void add_function_info(parsing_info_t* info,
|
||||
st_select_lex* select,
|
||||
const char* name,
|
||||
uint32_t usage,
|
||||
Item** items,
|
||||
int n_items)
|
||||
static QC_FUNCTION_INFO* add_function_info(parsing_info_t* info,
|
||||
st_select_lex* select,
|
||||
const char* name,
|
||||
uint32_t usage,
|
||||
Item** items,
|
||||
int n_items)
|
||||
{
|
||||
ss_dassert(name);
|
||||
|
||||
QC_FUNCTION_INFO* function_info = NULL;
|
||||
|
||||
name = map_function_name(info->function_name_mappings, name);
|
||||
|
||||
QC_FUNCTION_INFO item = { (char*)name, usage };
|
||||
@ -2512,17 +2529,16 @@ static void add_function_info(parsing_info_t* info,
|
||||
size_t i;
|
||||
for (i = 0; i < info->function_infos_len; ++i)
|
||||
{
|
||||
QC_FUNCTION_INFO* function_info = info->function_infos + i;
|
||||
|
||||
if (strcasecmp(item.name, function_info->name) == 0)
|
||||
if (strcasecmp(name, info->function_infos[i].name) == 0)
|
||||
{
|
||||
function_info = &info->function_infos[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QC_FUNCTION_INFO* function_infos = NULL;
|
||||
|
||||
if (i == info->function_infos_len) // If true, the function was not present already.
|
||||
if (!function_info)
|
||||
{
|
||||
if (info->function_infos_len < info->function_infos_capacity)
|
||||
{
|
||||
@ -2533,40 +2549,28 @@ static void add_function_info(parsing_info_t* info,
|
||||
size_t capacity = info->function_infos_capacity ? 2 * info->function_infos_capacity : 8;
|
||||
function_infos = (QC_FUNCTION_INFO*)realloc(info->function_infos,
|
||||
capacity * sizeof(QC_FUNCTION_INFO));
|
||||
assert(function_infos);
|
||||
|
||||
if (function_infos)
|
||||
{
|
||||
info->function_infos = function_infos;
|
||||
info->function_infos_capacity = capacity;
|
||||
}
|
||||
info->function_infos = function_infos;
|
||||
info->function_infos_capacity = capacity;
|
||||
}
|
||||
|
||||
function_info = &info->function_infos[info->function_infos_len++];
|
||||
|
||||
function_info->name = strdup(name);
|
||||
function_info->usage = 0;
|
||||
function_info->fields = NULL;
|
||||
function_info->n_fields = 0;
|
||||
}
|
||||
else
|
||||
|
||||
function_info->usage |= usage;
|
||||
|
||||
if (strcmp(name, "=") != 0)
|
||||
{
|
||||
info->function_infos[i].usage |= usage;
|
||||
|
||||
if (strcmp(name, "=") != 0)
|
||||
{
|
||||
add_function_field_usage(select, items, n_items, &info->function_infos[i]);
|
||||
}
|
||||
add_function_field_usage(select, items, n_items, function_info);
|
||||
}
|
||||
|
||||
// If function_infos is NULL, then the function was found and has already been noted.
|
||||
if (function_infos)
|
||||
{
|
||||
item.name = strdup(item.name);
|
||||
|
||||
if (item.name)
|
||||
{
|
||||
int i = info->function_infos_len++;
|
||||
function_infos[i] = item;
|
||||
|
||||
if (strcmp(name, "=") != 0)
|
||||
{
|
||||
add_function_field_usage(select, items, n_items, &info->function_infos[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return function_info;
|
||||
}
|
||||
|
||||
static void add_field_info(parsing_info_t* pi,
|
||||
@ -2938,11 +2942,11 @@ static void update_field_infos(parsing_info_t* pi,
|
||||
case Item::SUBSELECT_ITEM:
|
||||
{
|
||||
Item_subselect* subselect_item = static_cast<Item_subselect*>(item);
|
||||
|
||||
QC_FUNCTION_INFO* fi = NULL;
|
||||
switch (subselect_item->substype())
|
||||
{
|
||||
case Item_subselect::IN_SUBS:
|
||||
add_function_info(pi, select, "in", usage, 0, 0);
|
||||
fi = add_function_info(pi, select, "in", usage, 0, 0);
|
||||
case Item_subselect::ALL_SUBS:
|
||||
case Item_subselect::ANY_SUBS:
|
||||
{
|
||||
@ -2959,6 +2963,16 @@ static void update_field_infos(parsing_info_t* pi,
|
||||
{
|
||||
update_field_infos(pi, select, source, // TODO: Might be wrong select.
|
||||
in_subselect_item->left_expr_orig, usage, excludep);
|
||||
|
||||
if (subselect_item->substype() == Item_subselect::IN_SUBS)
|
||||
{
|
||||
Item* item = in_subselect_item->left_expr_orig;
|
||||
|
||||
if (item->type() == Item::FIELD_ITEM)
|
||||
{
|
||||
add_function_field_usage(select, static_cast<Item_field*>(item), fi);
|
||||
}
|
||||
}
|
||||
}
|
||||
st_select_lex* ssl = in_subselect_item->get_select_lex();
|
||||
if (ssl)
|
||||
@ -2973,6 +2987,12 @@ static void update_field_infos(parsing_info_t* pi,
|
||||
ssl,
|
||||
sub_usage,
|
||||
excludep);
|
||||
|
||||
if (subselect_item->substype() == Item_subselect::IN_SUBS)
|
||||
{
|
||||
assert(fi);
|
||||
add_function_field_usage(select, ssl, fi);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#pragma message "Figure out what to do with versions < 5.5.48."
|
||||
|
@ -1045,17 +1045,33 @@ public:
|
||||
case TK_EXISTS:
|
||||
case TK_IN:
|
||||
case TK_SELECT:
|
||||
if (pExpr->flags & EP_xIsSelect)
|
||||
{
|
||||
uint32_t sub_usage = usage;
|
||||
|
||||
sub_usage &= ~QC_USED_IN_SELECT;
|
||||
sub_usage |= QC_USED_IN_SUBSELECT;
|
||||
update_field_infos_from_subselect(pAliases, pExpr->x.pSelect, sub_usage, pExclude);
|
||||
}
|
||||
else
|
||||
{
|
||||
update_field_infos_from_exprlist(pAliases, pExpr->x.pList, usage, pExclude);
|
||||
|
||||
if (pExpr->flags & EP_xIsSelect)
|
||||
{
|
||||
update_field_infos_from_subselect(pAliases, pExpr->x.pSelect,
|
||||
sub_usage, pExclude);
|
||||
|
||||
if (pExpr->op == TK_IN)
|
||||
{
|
||||
update_function_info(pAliases, "in",
|
||||
pExpr->x.pSelect->pEList, sub_usage, pExclude);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
update_field_infos_from_exprlist(pAliases, pExpr->x.pList, usage, pExclude);
|
||||
|
||||
if (pExpr->op == TK_IN)
|
||||
{
|
||||
update_function_info(pAliases, "in",
|
||||
pExpr->x.pList, sub_usage, pExclude);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user