Commit 75fab514 authored by unknown's avatar unknown

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

gives MYSQL_DATA_TRUNCATED"


sql/sql_cursor.cc:
  A partial fix for Bug#13488 "Left outer join query incorrectly gives 
  MYSQL_DATA_TRUNCATED": send the correct metadata of the cursor
  result set at execute. The full fix would be to make sure that
  the metadata doesn't change between prepare and execute.
tests/mysql_client_test.c:
  A test case for Bug#13488 "Left outer join query incorrectly gives 
  MYSQL_DATA_TRUNCATED"
parent db46acd0
...@@ -558,6 +558,24 @@ int Materialized_cursor::open(JOIN *join __attribute__((unused))) ...@@ -558,6 +558,24 @@ int Materialized_cursor::open(JOIN *join __attribute__((unused)))
result->prepare(item_list, &fake_unit) || result->prepare(item_list, &fake_unit) ||
table->file->ha_rnd_init(TRUE)); table->file->ha_rnd_init(TRUE));
thd->restore_active_arena(this, &backup_arena); 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; return rc;
} }
...@@ -647,14 +665,6 @@ bool Select_materialize::send_fields(List<Item> &list, uint flags) ...@@ -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(), if (create_result_table(unit->thd, unit->get_unit_column_types(),
FALSE, thd->options | TMP_TABLE_ALL_COLUMNS, "")) FALSE, thd->options | TMP_TABLE_ALL_COLUMNS, ""))
return TRUE; 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; return rc;
} }
...@@ -14419,6 +14419,74 @@ static void test_bug14210() ...@@ -14419,6 +14419,74 @@ static void test_bug14210()
myquery(rc); 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 Read and parse arguments and MySQL options from my.cnf
*/ */
...@@ -14675,6 +14743,7 @@ static struct my_tests_st my_tests[]= { ...@@ -14675,6 +14743,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug11904", test_bug11904 }, { "test_bug11904", test_bug11904 },
{ "test_bug12243", test_bug12243 }, { "test_bug12243", test_bug12243 },
{ "test_bug14210", test_bug14210 }, { "test_bug14210", test_bug14210 },
{ "test_bug13488", test_bug13488 },
{ 0, 0 } { 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