diff options
author | unknown <konstantin@mysql.com> | 2005-11-09 20:31:01 +0300 |
---|---|---|
committer | unknown <konstantin@mysql.com> | 2005-11-09 20:31:01 +0300 |
commit | 75fab5146f0c230115ddc6e2e1e0f1b9c213f3d5 (patch) | |
tree | d7c8b15f9e7d1d4503383243fdb60d355613dade | |
parent | db46acd0bcec59e876c01953587fa9f1d5c93ded (diff) | |
download | mariadb-git-75fab5146f0c230115ddc6e2e1e0f1b9c213f3d5.tar.gz |
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"
-rw-r--r-- | sql/sql_cursor.cc | 26 | ||||
-rw-r--r-- | tests/mysql_client_test.c | 69 |
2 files changed, 87 insertions, 8 deletions
diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc index e8da691ea18..07be9efa6ac 100644 --- a/sql/sql_cursor.cc +++ b/sql/sql_cursor.cc @@ -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; } diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 949c3d5bf1c..b065a0dfa03 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -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 } }; |