Commit b318ed17 authored by konstantin@mysql.com's avatar konstantin@mysql.com

A fix and a test case for Bug#13488 "Left outer join query incorrectly

gives MYSQL_DATA_TRUNCATED"
parent c669c387
......@@ -558,6 +558,24 @@ int Materialized_cursor::open(JOIN *join __attribute__((unused)))
result->prepare(item_list, &fake_unit) ||
table->file->ha_rnd_init(TRUE));
thd->restore_active_arena(this, &backup_arena);
if (rc == 0)
{
/*
Now send the result set metadata to the client. We need to do it
here, as in Select_materialize::send_fields the exact column types
are not yet known. The new types may differ from the original ones
sent at prepare if some of them were altered by MySQL HEAP tables
mechanism -- used when create_tmp_field_from_item may alter the
original column type.
We can't simply supply SEND_EOF flag to send_fields, because
send_fields doesn't flush the network buffer.
*/
rc= result->send_fields(item_list, Protocol::SEND_NUM_ROWS);
thd->server_status|= SERVER_STATUS_CURSOR_EXISTS;
result->send_eof();
thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS;
}
return rc;
}
......@@ -647,14 +665,6 @@ bool Select_materialize::send_fields(List<Item> &list, uint flags)
if (create_result_table(unit->thd, unit->get_unit_column_types(),
FALSE, thd->options | TMP_TABLE_ALL_COLUMNS, ""))
return TRUE;
/*
We can't simply supply SEND_EOF flag to send_fields, because send_fields
doesn't flush the network buffer.
*/
rc= result->send_fields(list, Protocol::SEND_NUM_ROWS);
thd->server_status|= SERVER_STATUS_CURSOR_EXISTS;
result->send_eof();
thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS;
return rc;
}
......@@ -14419,6 +14419,74 @@ static void test_bug14210()
myquery(rc);
}
/* Bug#13488 */
static void test_bug13488()
{
MYSQL_BIND bind[3];
MYSQL_STMT *stmt1;
int rc, f1, f2, f3, i;
const ulong type= CURSOR_TYPE_READ_ONLY;
const char *query= "select * from t1 left join t2 on f1=f2 where f1=1";
myheader("test_bug13488");
rc= mysql_query(mysql, "drop table if exists t1, t2");
myquery(rc);
rc= mysql_query(mysql, "create table t1 (f1 int not null primary key)");
myquery(rc);
rc= mysql_query(mysql, "create table t2 (f2 int not null primary key, "
"f3 int not null)");
myquery(rc);
rc= mysql_query(mysql, "insert into t1 values (1), (2)");
myquery(rc);
rc= mysql_query(mysql, "insert into t2 values (1,2), (2,4)");
myquery(rc);
memset(bind, 0, sizeof(bind));
for (i= 0; i < 3; i++)
{
bind[i].buffer_type= MYSQL_TYPE_LONG;
bind[i].buffer_length= 4;
bind[i].length= 0;
}
bind[0].buffer=&f1;
bind[1].buffer=&f2;
bind[2].buffer=&f3;
stmt1= mysql_stmt_init(mysql);
rc= mysql_stmt_attr_set(stmt1,STMT_ATTR_CURSOR_TYPE, (const void *)&type);
check_execute(stmt1, rc);
rc= mysql_stmt_prepare(stmt1, query, strlen(query));
check_execute(stmt1, rc);
rc= mysql_stmt_execute(stmt1);
check_execute(stmt1, rc);
rc= mysql_stmt_bind_result(stmt1, bind);
check_execute(stmt1, rc);
rc= mysql_stmt_fetch(stmt1);
check_execute(stmt1, rc);
rc= mysql_stmt_free_result(stmt1);
check_execute(stmt1, rc);
rc= mysql_stmt_reset(stmt1);
check_execute(stmt1, rc);
rc= mysql_stmt_close(stmt1);
check_execute(stmt1, rc);
if (!opt_silent)
printf("data is: %s", (f1 == 1 && f2 == 1 && f3 == 2)?"OK":
"wrong");
DIE_UNLESS(f1 == 1 && f2 == 1 && f3 == 2);
rc= mysql_query(mysql, "drop table t1, t2");
myquery(rc);
}
/*
Read and parse arguments and MySQL options from my.cnf
*/
......@@ -14675,6 +14743,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug11904", test_bug11904 },
{ "test_bug12243", test_bug12243 },
{ "test_bug14210", test_bug14210 },
{ "test_bug13488", test_bug13488 },
{ 0, 0 }
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment