summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <evgen@moonbone.local>2005-06-15 02:57:22 +0400
committerunknown <evgen@moonbone.local>2005-06-15 02:57:22 +0400
commit970e20b7fe8eb9070dc5350785a6bd0c7df96f04 (patch)
tree0ebb3dd2fbf3798247e3ab456a10484d9c287fe6
parentd5600efdc1ec98c1b9ef7190565788e7174e45f0 (diff)
parent4095a52a778cd227f94d14e8659dbdde71758911 (diff)
downloadmariadb-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.h8
-rw-r--r--sql/sql_select.cc14
-rw-r--r--tests/mysql_client_test.c43
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 }
};