MXS-1364 Improve collection of arguments to IN
This commit is contained in:
@ -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)
|
static QC_FUNCTION_INFO* get_function_info(parsing_info_t* info, const char* name)
|
||||||
{
|
{
|
||||||
QC_FUNCTION_INFO* function_info = NULL;
|
QC_FUNCTION_INFO* function_info = NULL;
|
||||||
@ -2496,7 +2511,7 @@ static QC_FUNCTION_INFO* get_function_info(parsing_info_t* info, const char* nam
|
|||||||
return function_info;
|
return function_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_function_info(parsing_info_t* info,
|
static QC_FUNCTION_INFO* add_function_info(parsing_info_t* info,
|
||||||
st_select_lex* select,
|
st_select_lex* select,
|
||||||
const char* name,
|
const char* name,
|
||||||
uint32_t usage,
|
uint32_t usage,
|
||||||
@ -2505,6 +2520,8 @@ static void add_function_info(parsing_info_t* info,
|
|||||||
{
|
{
|
||||||
ss_dassert(name);
|
ss_dassert(name);
|
||||||
|
|
||||||
|
QC_FUNCTION_INFO* function_info = NULL;
|
||||||
|
|
||||||
name = map_function_name(info->function_name_mappings, name);
|
name = map_function_name(info->function_name_mappings, name);
|
||||||
|
|
||||||
QC_FUNCTION_INFO item = { (char*)name, usage };
|
QC_FUNCTION_INFO item = { (char*)name, usage };
|
||||||
@ -2512,17 +2529,16 @@ static void add_function_info(parsing_info_t* info,
|
|||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < info->function_infos_len; ++i)
|
for (i = 0; i < info->function_infos_len; ++i)
|
||||||
{
|
{
|
||||||
QC_FUNCTION_INFO* function_info = info->function_infos + i;
|
if (strcasecmp(name, info->function_infos[i].name) == 0)
|
||||||
|
|
||||||
if (strcasecmp(item.name, function_info->name) == 0)
|
|
||||||
{
|
{
|
||||||
|
function_info = &info->function_infos[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QC_FUNCTION_INFO* function_infos = NULL;
|
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)
|
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;
|
size_t capacity = info->function_infos_capacity ? 2 * info->function_infos_capacity : 8;
|
||||||
function_infos = (QC_FUNCTION_INFO*)realloc(info->function_infos,
|
function_infos = (QC_FUNCTION_INFO*)realloc(info->function_infos,
|
||||||
capacity * sizeof(QC_FUNCTION_INFO));
|
capacity * sizeof(QC_FUNCTION_INFO));
|
||||||
|
assert(function_infos);
|
||||||
|
|
||||||
if (function_infos)
|
|
||||||
{
|
|
||||||
info->function_infos = function_infos;
|
info->function_infos = function_infos;
|
||||||
info->function_infos_capacity = capacity;
|
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;
|
||||||
{
|
|
||||||
info->function_infos[i].usage |= usage;
|
|
||||||
|
|
||||||
if (strcmp(name, "=") != 0)
|
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.
|
return function_info;
|
||||||
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]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_field_info(parsing_info_t* pi,
|
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:
|
case Item::SUBSELECT_ITEM:
|
||||||
{
|
{
|
||||||
Item_subselect* subselect_item = static_cast<Item_subselect*>(item);
|
Item_subselect* subselect_item = static_cast<Item_subselect*>(item);
|
||||||
|
QC_FUNCTION_INFO* fi = NULL;
|
||||||
switch (subselect_item->substype())
|
switch (subselect_item->substype())
|
||||||
{
|
{
|
||||||
case Item_subselect::IN_SUBS:
|
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::ALL_SUBS:
|
||||||
case Item_subselect::ANY_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.
|
update_field_infos(pi, select, source, // TODO: Might be wrong select.
|
||||||
in_subselect_item->left_expr_orig, usage, excludep);
|
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();
|
st_select_lex* ssl = in_subselect_item->get_select_lex();
|
||||||
if (ssl)
|
if (ssl)
|
||||||
@ -2973,6 +2987,12 @@ static void update_field_infos(parsing_info_t* pi,
|
|||||||
ssl,
|
ssl,
|
||||||
sub_usage,
|
sub_usage,
|
||||||
excludep);
|
excludep);
|
||||||
|
|
||||||
|
if (subselect_item->substype() == Item_subselect::IN_SUBS)
|
||||||
|
{
|
||||||
|
assert(fi);
|
||||||
|
add_function_field_usage(select, ssl, fi);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#pragma message "Figure out what to do with versions < 5.5.48."
|
#pragma message "Figure out what to do with versions < 5.5.48."
|
||||||
|
@ -1045,17 +1045,33 @@ public:
|
|||||||
case TK_EXISTS:
|
case TK_EXISTS:
|
||||||
case TK_IN:
|
case TK_IN:
|
||||||
case TK_SELECT:
|
case TK_SELECT:
|
||||||
if (pExpr->flags & EP_xIsSelect)
|
|
||||||
{
|
{
|
||||||
uint32_t sub_usage = usage;
|
uint32_t sub_usage = usage;
|
||||||
|
|
||||||
sub_usage &= ~QC_USED_IN_SELECT;
|
sub_usage &= ~QC_USED_IN_SELECT;
|
||||||
sub_usage |= QC_USED_IN_SUBSELECT;
|
sub_usage |= QC_USED_IN_SUBSELECT;
|
||||||
update_field_infos_from_subselect(pAliases, pExpr->x.pSelect, sub_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
|
else
|
||||||
{
|
{
|
||||||
update_field_infos_from_exprlist(pAliases, pExpr->x.pList, usage, pExclude);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user