mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Bug#19671 mysql_list_fields returns incorrect table name for VIEWs
After view onening real view db name and table name are placed into table_list->view_db & table_list->view_name. Item_field class does not handle these names properly during intialization of Send_field. The fix is to use new class 'Item_ident_for_show' which sets correct view db name and table name for Send_field.
This commit is contained in:
13
sql/item.cc
13
sql/item.cc
@ -1457,7 +1457,18 @@ bool agg_item_charsets(DTCollation &coll, const char *fname,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Item_ident_for_show::make_field(Send_field *tmp_field)
|
||||||
|
{
|
||||||
|
tmp_field->table_name= tmp_field->org_table_name= table_name;
|
||||||
|
tmp_field->db_name= db_name;
|
||||||
|
tmp_field->col_name= tmp_field->org_col_name= field->field_name;
|
||||||
|
tmp_field->charsetnr= field->charset()->number;
|
||||||
|
tmp_field->length=field->field_length;
|
||||||
|
tmp_field->type=field->type();
|
||||||
|
tmp_field->flags= field->table->maybe_null ?
|
||||||
|
(field->flags & ~NOT_NULL_FLAG) : field->flags;
|
||||||
|
tmp_field->decimals= 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************/
|
/**********************************************/
|
||||||
|
|
||||||
|
22
sql/item.h
22
sql/item.h
@ -1142,6 +1142,28 @@ public:
|
|||||||
bool any_privileges);
|
bool any_privileges);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Item_ident_for_show :public Item
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Field *field;
|
||||||
|
const char *db_name;
|
||||||
|
const char *table_name;
|
||||||
|
|
||||||
|
Item_ident_for_show(Field *par_field, const char *db_arg,
|
||||||
|
const char *table_name_arg)
|
||||||
|
:field(par_field), db_name(db_arg), table_name(table_name_arg)
|
||||||
|
{}
|
||||||
|
|
||||||
|
enum Type type() const { return FIELD_ITEM; }
|
||||||
|
double val_real() { return field->val_real(); }
|
||||||
|
longlong val_int() { return field->val_int(); }
|
||||||
|
String *val_str(String *str) { return field->val_str(str); }
|
||||||
|
my_decimal *val_decimal(my_decimal *dec) { return field->val_decimal(dec); }
|
||||||
|
void make_field(Send_field *tmp_field);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class Item_equal;
|
class Item_equal;
|
||||||
class COND_EQUAL;
|
class COND_EQUAL;
|
||||||
|
|
||||||
|
@ -582,7 +582,14 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
|
|||||||
{
|
{
|
||||||
if (!wild || !wild[0] ||
|
if (!wild || !wild[0] ||
|
||||||
!wild_case_compare(system_charset_info, field->field_name,wild))
|
!wild_case_compare(system_charset_info, field->field_name,wild))
|
||||||
field_list.push_back(new Item_field(field));
|
{
|
||||||
|
if (table_list->view)
|
||||||
|
field_list.push_back(new Item_ident_for_show(field,
|
||||||
|
table_list->view_db.str,
|
||||||
|
table_list->view_name.str));
|
||||||
|
else
|
||||||
|
field_list.push_back(new Item_field(field));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
restore_record(table, s->default_values); // Get empty record
|
restore_record(table, s->default_values); // Get empty record
|
||||||
if (thd->protocol->send_fields(&field_list, Protocol::SEND_DEFAULTS |
|
if (thd->protocol->send_fields(&field_list, Protocol::SEND_DEFAULTS |
|
||||||
|
@ -8311,6 +8311,39 @@ static void test_list_fields()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void test_bug19671()
|
||||||
|
{
|
||||||
|
MYSQL_RES *result;
|
||||||
|
int rc;
|
||||||
|
myheader("test_bug19671");
|
||||||
|
|
||||||
|
rc= mysql_query(mysql, "drop table if exists t1");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
rc= mysql_query(mysql, "drop view if exists v1");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
rc= mysql_query(mysql, "create table t1(f1 int)");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
rc= mysql_query(mysql, "create view v1 as select va.* from t1 va");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
result= mysql_list_fields(mysql, "v1", NULL);
|
||||||
|
mytest(result);
|
||||||
|
|
||||||
|
rc= my_process_result_set(result);
|
||||||
|
DIE_UNLESS(rc == 0);
|
||||||
|
|
||||||
|
verify_prepare_field(result, 0, "f1", "f1", MYSQL_TYPE_LONG,
|
||||||
|
"v1", "v1", current_db, 11, "0");
|
||||||
|
|
||||||
|
mysql_free_result(result);
|
||||||
|
myquery(mysql_query(mysql, "drop view v1"));
|
||||||
|
myquery(mysql_query(mysql, "drop table t1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Test a memory ovverun bug */
|
/* Test a memory ovverun bug */
|
||||||
|
|
||||||
static void test_mem_overun()
|
static void test_mem_overun()
|
||||||
@ -15195,6 +15228,7 @@ static struct my_tests_st my_tests[]= {
|
|||||||
{ "test_bug15613", test_bug15613 },
|
{ "test_bug15613", test_bug15613 },
|
||||||
{ "test_bug14169", test_bug14169 },
|
{ "test_bug14169", test_bug14169 },
|
||||||
{ "test_bug17667", test_bug17667 },
|
{ "test_bug17667", test_bug17667 },
|
||||||
|
{ "test_bug19671", test_bug19671},
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user