Skip to content

Commit f3926cd

Browse files
author
Alexey Botchkov
committed
MDEV-5273 Prepared statement doesn't return metadata after prepare.
Fix for SHOW CREATE DATABASE.
1 parent 07e9762 commit f3926cd

File tree

4 files changed

+63
-26
lines changed

4 files changed

+63
-26
lines changed

sql/sql_prepare.cc

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1812,6 +1812,14 @@ static bool mysql_test_create_table(Prepared_statement *stmt)
18121812
}
18131813

18141814

1815+
static bool send_stmt_metadata(THD *thd, Prepared_statement *stmt, List<Item> *fields)
1816+
{
1817+
return send_prep_stmt(stmt, fields->elements) ||
1818+
thd->protocol->send_result_set_metadata(fields, Protocol::SEND_EOF) ||
1819+
thd->protocol->flush();
1820+
}
1821+
1822+
18151823
/**
18161824
Validate and prepare for execution SHOW CREATE TABLE statement.
18171825
@@ -1824,7 +1832,7 @@ static bool mysql_test_create_table(Prepared_statement *stmt)
18241832
TRUE error, error message is set in THD
18251833
*/
18261834

1827-
static int mysql_test_show_create_table(Prepared_statement *stmt,
1835+
static bool mysql_test_show_create_table(Prepared_statement *stmt,
18281836
TABLE_LIST *tables)
18291837
{
18301838
DBUG_ENTER("mysql_test_show_create_table");
@@ -1833,22 +1841,31 @@ static int mysql_test_show_create_table(Prepared_statement *stmt,
18331841
char buff[2048];
18341842
String buffer(buff, sizeof(buff), system_charset_info);
18351843

1836-
if (mysqld_show_create_get_fields(thd, tables, &fields, &buffer))
1837-
goto err_exit;
1838-
1839-
if (!stmt->is_sql_prepare())
1840-
{
1841-
if (send_prep_stmt(stmt, fields.elements) ||
1842-
thd->protocol->send_result_set_metadata(&fields, Protocol::SEND_EOF) ||
1843-
thd->protocol->flush())
1844-
goto err_exit;
1844+
DBUG_RETURN(mysqld_show_create_get_fields(thd, tables, &fields, &buffer) ||
1845+
send_stmt_metadata(thd, stmt, &fields));
1846+
}
18451847

1846-
DBUG_RETURN(2);
1847-
}
1848-
DBUG_RETURN(0);
18491848

1850-
err_exit:
1851-
DBUG_RETURN(1);
1849+
/**
1850+
Validate and prepare for execution SHOW CREATE DATABASE statement.
1851+
1852+
@param stmt prepared statement
1853+
1854+
@retval
1855+
FALSE success
1856+
@retval
1857+
TRUE error, error message is set in THD
1858+
*/
1859+
1860+
static bool mysql_test_show_create_db(Prepared_statement *stmt)
1861+
{
1862+
DBUG_ENTER("mysql_test_show_create_db");
1863+
THD *thd= stmt->thd;
1864+
List<Item> fields;
1865+
1866+
mysqld_show_create_db_get_fields(thd, &fields);
1867+
1868+
DBUG_RETURN(send_stmt_metadata(thd, stmt, &fields));
18521869
}
18531870

18541871

@@ -2186,8 +2203,14 @@ static bool check_prepared_statement(Prepared_statement *stmt)
21862203
res= mysql_test_create_table(stmt);
21872204
break;
21882205
case SQLCOM_SHOW_CREATE:
2189-
res= mysql_test_show_create_table(stmt, tables);
2190-
if (res == 2)
2206+
if (!(res= mysql_test_show_create_table(stmt, tables)))
2207+
{
2208+
/* Statement and field info has already been sent */
2209+
DBUG_RETURN(FALSE);
2210+
}
2211+
break;
2212+
case SQLCOM_SHOW_CREATE_DB:
2213+
if (!(res= mysql_test_show_create_db(stmt)))
21912214
{
21922215
/* Statement and field info has already been sent */
21932216
DBUG_RETURN(FALSE);

sql/sql_show.cc

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,6 +1272,19 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
12721272
DBUG_RETURN(error);
12731273
}
12741274

1275+
1276+
void mysqld_show_create_db_get_fields(THD *thd, List<Item> *field_list)
1277+
{
1278+
MEM_ROOT *mem_root= thd->mem_root;
1279+
field_list->push_back(new (mem_root)
1280+
Item_empty_string(thd, "Database", NAME_CHAR_LEN),
1281+
mem_root);
1282+
field_list->push_back(new (mem_root)
1283+
Item_empty_string(thd, "Create Database", 1024),
1284+
mem_root);
1285+
}
1286+
1287+
12751288
bool mysqld_show_create_db(THD *thd, LEX_STRING *dbname,
12761289
LEX_STRING *orig_dbname,
12771290
const DDL_options_st &options)
@@ -1284,7 +1297,7 @@ bool mysqld_show_create_db(THD *thd, LEX_STRING *dbname,
12841297
#endif
12851298
Schema_specification_st create;
12861299
Protocol *protocol=thd->protocol;
1287-
MEM_ROOT *mem_root= thd->mem_root;
1300+
List<Item> field_list;
12881301
DBUG_ENTER("mysql_show_create_db");
12891302

12901303
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -1318,13 +1331,8 @@ bool mysqld_show_create_db(THD *thd, LEX_STRING *dbname,
13181331

13191332
load_db_opt_by_name(thd, dbname->str, &create);
13201333
}
1321-
List<Item> field_list;
1322-
field_list.push_back(new (mem_root)
1323-
Item_empty_string(thd, "Database", NAME_CHAR_LEN),
1324-
mem_root);
1325-
field_list.push_back(new (mem_root)
1326-
Item_empty_string(thd, "Create Database", 1024),
1327-
mem_root);
1334+
1335+
mysqld_show_create_db_get_fields(thd, &field_list);
13281336

13291337
if (protocol->send_result_set_metadata(&field_list,
13301338
Protocol::SEND_NUM_ROWS |

sql/sql_show.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ int mysqld_dump_create_info(THD *thd, TABLE_LIST *table_list, int fd);
8888
bool mysqld_show_create_get_fields(THD *thd, TABLE_LIST *table_list,
8989
List<Item> *field_list, String *buffer);
9090
bool mysqld_show_create(THD *thd, TABLE_LIST *table_list);
91+
void mysqld_show_create_db_get_fields(THD *thd, List<Item> *field_list);
9192
bool mysqld_show_create_db(THD *thd, LEX_STRING *db_name,
9293
LEX_STRING *orig_db_name,
9394
const DDL_options_st &options);

tests/mysql_client_test.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,9 +426,14 @@ static void test_prepare_simple()
426426
strmov(query, "SHOW CREATE TABLE test_prepare_simple");
427427
stmt= mysql_simple_prepare(mysql, query);
428428
check_stmt(stmt);
429-
430429
DIE_UNLESS(mysql_stmt_field_count(stmt) == 2);
430+
mysql_stmt_close(stmt);
431431

432+
/* show create database */
433+
strmov(query, "SHOW CREATE DATABASE test");
434+
stmt= mysql_simple_prepare(mysql, query);
435+
check_stmt(stmt);
436+
DIE_UNLESS(mysql_stmt_field_count(stmt) == 2);
432437
mysql_stmt_close(stmt);
433438

434439
/* now fetch the results ..*/

0 commit comments

Comments
 (0)