From f9214221fc5a42f1f864b14046cdcebbff5a7d0e Mon Sep 17 00:00:00 2001 From: "gluh@eagle.intranet.mysql.r18.ru" <> Date: Thu, 29 Jun 2006 16:52:46 +0500 Subject: [PATCH] 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. --- sql/item.cc | 13 ++++++++++++- sql/item.h | 22 ++++++++++++++++++++++ sql/sql_show.cc | 9 ++++++++- tests/mysql_client_test.c | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 2 deletions(-) diff --git a/sql/item.cc b/sql/item.cc index 24efc1f106f..e73a6044574 100644 --- a/sql/item.cc +++ b/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; +} /**********************************************/ diff --git a/sql/item.h b/sql/item.h index 2cadfda6895..bee24d23245 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1142,6 +1142,28 @@ public: 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 COND_EQUAL; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 60d50c415d5..71a6b0acde9 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -582,7 +582,14 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild) { if (!wild || !wild[0] || !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 if (thd->protocol->send_fields(&field_list, Protocol::SEND_DEFAULTS | diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 3876de58b0e..0f2847e0f63 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -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 */ static void test_mem_overun() @@ -15195,6 +15228,7 @@ static struct my_tests_st my_tests[]= { { "test_bug15613", test_bug15613 }, { "test_bug14169", test_bug14169 }, { "test_bug17667", test_bug17667 }, + { "test_bug19671", test_bug19671}, { 0, 0 } };