diff options
author | unknown <evgen@moonbone.local> | 2005-06-15 02:57:22 +0400 |
---|---|---|
committer | unknown <evgen@moonbone.local> | 2005-06-15 02:57:22 +0400 |
commit | 970e20b7fe8eb9070dc5350785a6bd0c7df96f04 (patch) | |
tree | 0ebb3dd2fbf3798247e3ab456a10484d9c287fe6 | |
parent | d5600efdc1ec98c1b9ef7190565788e7174e45f0 (diff) | |
parent | 4095a52a778cd227f94d14e8659dbdde71758911 (diff) | |
download | mariadb-git-970e20b7fe8eb9070dc5350785a6bd0c7df96f04.tar.gz |
Merge epotemkin@bk-internal.mysql.com:/home/bk/mysql-5.0
into moonbone.local:/work/mysql-5.0-bug-11111
-rw-r--r-- | sql/item.h | 8 | ||||
-rw-r--r-- | sql/sql_select.cc | 14 | ||||
-rw-r--r-- | tests/mysql_client_test.c | 43 |
3 files changed, 63 insertions, 2 deletions
diff --git a/sql/item.h b/sql/item.h index 1fe90a41e3a..2629f94a903 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1352,7 +1352,13 @@ public: { (*ref)->save_in_field(result_field, no_conversions); } - Item *real_item() { return *ref; } + Item *real_item() { + Item *item= this; + do + item= *((Item_ref *)item)->ref; + while (item->type() == Item::REF_ITEM); + return item; + } bool walk(Item_processor processor, byte *arg) { return (*ref)->walk(processor, arg); } void print(String *str); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7d57fd78c93..c416b81bf1b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7957,6 +7957,19 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, modify_item ? (Item_field*) item : NULL, convert_blob_length); } + case Item::REF_ITEM: + if ( ((Item_ref*)item)->real_item()->type() == Item::FIELD_ITEM) + { + Item_field *field= (Item_field*) *((Item_ref*)item)->ref; + Field *new_field= create_tmp_field_from_field(thd, + (*from_field= field->field), + item->name, table, + NULL, + convert_blob_length); + if (modify_item) + item->set_result_field(new_field); + return new_field; + } case Item::FUNC_ITEM: case Item::COND_ITEM: case Item::FIELD_AVG_ITEM: @@ -7968,7 +7981,6 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, case Item::REAL_ITEM: case Item::DECIMAL_ITEM: case Item::STRING_ITEM: - case Item::REF_ITEM: case Item::NULL_ITEM: case Item::VARBIN_ITEM: return create_tmp_field_from_item(thd, item, table, copy_func, modify_item, diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index b6ca4996c70..fb18c83b30e 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -13146,6 +13146,48 @@ static void test_bug9643() } /* + Bug#11111: fetch from view returns wrong data +*/ + +static void test_bug11111() +{ + MYSQL_STMT *stmt; + MYSQL_BIND bind[2]; + char buf[2][20]; + long len[2]; + int i; + const char * query = "SELECT DISTINCT f1,ff2 FROM v1"; + + mysql_query(mysql, "drop table if exists t1, t2, v1"); + mysql_query(mysql, "create table t1 (f1 int, f2 int)"); + mysql_query(mysql, "create table t2 (ff1 int, ff2 int)"); + mysql_query(mysql, "create view v1 as select * from t1, t2 where f1=ff1"); + mysql_query(mysql, "insert into t1 values (1,1), (2,2), (3,3)"); + mysql_query(mysql, "insert into t2 values (1,1), (2,2), (3,3)"); + + stmt = mysql_stmt_init(mysql); + + mysql_stmt_prepare(stmt, query, strlen(query)); + mysql_stmt_execute(stmt); + + for (i=0; i < 2; i++) { + memset(&bind[i], '\0', sizeof(MYSQL_BIND)); + bind[i].buffer_type= MYSQL_TYPE_STRING; + bind[i].buffer= (gptr *)&buf[i]; + bind[i].buffer_length= 20; + bind[i].length= &len[i]; + } + + if (mysql_stmt_bind_result(stmt, bind)) + printf("Error: %s\n", mysql_stmt_error(stmt)); + + mysql_stmt_fetch(stmt); + DIE_UNLESS(!strcmp(buf[1],"1")); + mysql_stmt_close(stmt); + mysql_query(mysql, "drop table t1, t2, v1"); +} + +/* Check that proper cleanups are done for prepared statement when fetching thorugh a cursor. */ @@ -13439,6 +13481,7 @@ static struct my_tests_st my_tests[]= { { "test_bug9478", test_bug9478 }, { "test_bug9643", test_bug9643 }, { "test_bug10729", test_bug10729 }, + { "test_bug11111", test_bug11111 }, { 0, 0 } }; |