summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2016-12-05 17:37:54 +0100
committerOleksandr Byelkin <sanja@mariadb.com>2016-12-06 19:34:25 +0100
commitd67ef7a2fb3b52b3f61ce71dfe23cf4d610afc3c (patch)
treef961dcee68f01bb7232f135321602cd1d7222a09 /sql/item.cc
parent035a5ac62a0215c2f6e3e363331e3e984d780138 (diff)
downloadmariadb-git-d67ef7a2fb3b52b3f61ce71dfe23cf4d610afc3c.tar.gz
MDEV-10663: Use of Inline table columns in HAVING clause throws 1463 Error
check for VIEW/DERIVED fields
Diffstat (limited to 'sql/item.cc')
-rw-r--r--sql/item.cc72
1 files changed, 43 insertions, 29 deletions
diff --git a/sql/item.cc b/sql/item.cc
index ede1df6aa9b..53666aaf83d 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -4556,8 +4556,6 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list)
const char *field_name;
ORDER *found_group= NULL;
int found_match_degree= 0;
- Item_ident *cur_field;
- int cur_match_degree= 0;
char name_buff[SAFE_NAME_LEN+1];
if (find_item->type() == Item::FIELD_ITEM ||
@@ -4582,54 +4580,70 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list)
for (ORDER *cur_group= group_list ; cur_group ; cur_group= cur_group->next)
{
- if ((*(cur_group->item))->real_item()->type() == Item::FIELD_ITEM)
+ int cur_match_degree= 0;
+
+ /* SELECT list element with explicit alias */
+ if ((*(cur_group->item))->name &&
+ !(*(cur_group->item))->is_autogenerated_name &&
+ !my_strcasecmp(system_charset_info,
+ (*(cur_group->item))->name, field_name))
{
- cur_field= (Item_ident*) *cur_group->item;
- cur_match_degree= 0;
-
- DBUG_ASSERT(cur_field->field_name != 0);
+ ++cur_match_degree;
+ }
+ /* Reference on the field or view/derived field. */
+ else if ((*(cur_group->item))->type() == Item::FIELD_ITEM ||
+ (*(cur_group->item))->type() == Item::REF_ITEM )
+ {
+ Item_ident *cur_field= (Item_ident*) *cur_group->item;
+ const char *l_db_name= cur_field->db_name;
+ const char *l_table_name= cur_field->table_name;
+ const char *l_field_name= cur_field->field_name;
+
+ DBUG_ASSERT(l_field_name != 0);
if (!my_strcasecmp(system_charset_info,
- cur_field->field_name, field_name))
+ l_field_name, field_name))
++cur_match_degree;
else
continue;
- if (cur_field->table_name && table_name)
+ if (l_table_name && table_name)
{
/* If field_name is qualified by a table name. */
- if (my_strcasecmp(table_alias_charset, cur_field->table_name, table_name))
+ if (my_strcasecmp(table_alias_charset, l_table_name, table_name))
/* Same field names, different tables. */
return NULL;
++cur_match_degree;
- if (cur_field->db_name && db_name)
+ if (l_db_name && db_name)
{
/* If field_name is also qualified by a database name. */
- if (strcmp(cur_field->db_name, db_name))
+ if (strcmp(l_db_name, db_name))
/* Same field names, different databases. */
return NULL;
++cur_match_degree;
}
}
+ }
+ else
+ continue;
- if (cur_match_degree > found_match_degree)
- {
- found_match_degree= cur_match_degree;
- found_group= cur_group;
- }
- else if (found_group && (cur_match_degree == found_match_degree) &&
- ! (*(found_group->item))->eq(cur_field, 0))
- {
- /*
- If the current resolve candidate matches equally well as the current
- best match, they must reference the same column, otherwise the field
- is ambiguous.
- */
- my_error(ER_NON_UNIQ_ERROR, MYF(0),
- find_item->full_name(), current_thd->where);
- return NULL;
- }
+ if (cur_match_degree > found_match_degree)
+ {
+ found_match_degree= cur_match_degree;
+ found_group= cur_group;
+ }
+ else if (found_group && (cur_match_degree == found_match_degree) &&
+ !(*(found_group->item))->eq((*(cur_group->item)), 0))
+ {
+ /*
+ If the current resolve candidate matches equally well as the current
+ best match, they must reference the same column, otherwise the field
+ is ambiguous.
+ */
+ my_error(ER_NON_UNIQ_ERROR, MYF(0),
+ find_item->full_name(), current_thd->where);
+ return NULL;
}
}