Below is the list of changes that have just been committed into a local
5.1 repository of marcsql. When marcsql does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2008-05-20 10:33:20-06:00, malff@weblab.(none) +12 -0
Bug 17898
STATUS: random hacking to investigate feasability, not ready for anything.
include/mysql_com.h@stripped, 2008-05-20 10:32:37-06:00, marcsql@weblab.(none) +1 -0
Posting old notes, not a full patch
libmysql/libmysql.c@stripped, 2008-05-20 10:32:37-06:00, marcsql@weblab.(none) +6 -0
Posting old notes, not a full patch
mysql-test/t/marc.test@stripped, 2008-05-20 10:32:38-06:00, marcsql@weblab.(none) +21 -0
Posting old notes, not a full patch
mysql-test/t/marc.test@stripped, 2008-05-20 10:32:38-06:00, marcsql@weblab.(none) +0 -0
mysql-test/t/mysql_client_test.test@stripped, 2008-05-20 10:32:37-06:00,
marcsql@weblab.(none) +7 -2
Posting old notes, not a full patch
sql-common/client.c@stripped, 2008-05-20 10:32:37-06:00, marcsql@weblab.(none) +19 -0
Posting old notes, not a full patch
sql/item.cc@stripped, 2008-05-20 10:32:37-06:00, marcsql@weblab.(none) +42 -0
Posting old notes, not a full patch
sql/item.h@stripped, 2008-05-20 10:32:37-06:00, marcsql@weblab.(none) +30 -7
Posting old notes, not a full patch
sql/protocol.cc@stripped, 2008-05-20 10:32:37-06:00, marcsql@weblab.(none) +102 -0
Posting old notes, not a full patch
sql/protocol.h@stripped, 2008-05-20 10:32:37-06:00, marcsql@weblab.(none) +3 -1
Posting old notes, not a full patch
sql/sql_connect.cc@stripped, 2008-05-20 10:32:37-06:00, marcsql@weblab.(none) +8 -1
Posting old notes, not a full patch
sql/sql_prepare.cc@stripped, 2008-05-20 10:32:37-06:00, marcsql@weblab.(none) +64 -9
Posting old notes, not a full patch
tests/mysql_client_test.c@stripped, 2008-05-20 10:32:38-06:00, marcsql@weblab.(none) +111
-0
Posting old notes, not a full patch
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: malff
# Host: weblab.(none)
# Root: /home/marcsql/TREE/mysql-5.1-17898
--- 1.120/include/mysql_com.h 2008-05-20 10:33:27 -06:00
+++ 1.121/include/mysql_com.h 2008-05-20 10:33:27 -06:00
@@ -143,6 +143,7 @@ enum enum_server_command
#define CLIENT_SECURE_CONNECTION 32768 /* New 4.1 authentication */
#define CLIENT_MULTI_STATEMENTS (1UL << 16) /* Enable/disable multi-stmt support */
#define CLIENT_MULTI_RESULTS (1UL << 17) /* Enable/disable multi-results */
+#define CLIENT_BIDIR_PARAM (1UL << 18) /* Bi directional parameter bindings */
#define CLIENT_SSL_VERIFY_SERVER_CERT (1UL << 30)
#define CLIENT_REMEMBER_OPTIONS (1UL << 31)
--- 1.273/libmysql/libmysql.c 2008-05-20 10:33:27 -06:00
+++ 1.274/libmysql/libmysql.c 2008-05-20 10:33:27 -06:00
@@ -1925,6 +1925,12 @@ my_bool cli_read_prepare_result(MYSQL *m
DBUG_PRINT("exit",("field_count: %u param_count: %u warning_count: %u",
field_count, param_count, (uint) mysql->warning_count));
+ if (mysql->server_capabilities & CLIENT_BIDIR_PARAM)
+ {
+ if ((packet_length= cli_safe_read(mysql)) == packet_error)
+ DBUG_RETURN(1);
+ }
+
DBUG_RETURN(0);
}
--- 1.263/sql/item.cc 2008-05-20 10:33:27 -06:00
+++ 1.264/sql/item.cc 2008-05-20 10:33:27 -06:00
@@ -2581,6 +2581,48 @@ bool Item_param::set_from_user_var(THD *
DBUG_RETURN(0);
}
+bool Item_param::set_value(THD *thd, sp_rcontext * /* ctx */, Item **it)
+{
+ DBUG_ASSERT(it);
+ DBUG_ASSERT(*it);
+
+ Item *out= *it;
+
+ switch(out->result_type()) {
+ case STRING_RESULT:
+ // FIXME
+ DBUG_ASSERT(FALSE);
+ break;
+ case REAL_RESULT:
+ set_double(out->val_real());
+ item_type= Item::REAL_ITEM;
+ item_result_type= REAL_RESULT;
+ break;
+ case INT_RESULT:
+ set_int(val_int(), MY_INT64_NUM_DECIMAL_DIGITS);
+ item_type= Item::INT_ITEM;
+ item_result_type= INT_RESULT;
+ break;
+ case DECIMAL_RESULT:
+ {
+ my_decimal buffer;
+ const my_decimal *ent_value= out->val_decimal(& buffer);
+ my_decimal2decimal(ent_value, &decimal_value);
+ state= DECIMAL_VALUE;
+ decimals= ent_value->frac;
+ max_length= my_decimal_precision_to_length(ent_value->precision(),
+ decimals, unsigned_flag);
+ break;
+ }
+ case ROW_RESULT:
+ default:
+ DBUG_ASSERT(FALSE);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
/*
Resets parameter after execution.
--- 1.238/sql/item.h 2008-05-20 10:33:27 -06:00
+++ 1.239/sql/item.h 2008-05-20 10:33:27 -06:00
@@ -1447,9 +1447,19 @@ public:
bool check_partition_func_processor(byte *int_arg) {return TRUE;}
};
-/* Item represents one placeholder ('?') of prepared statement */
+/* Item_param represents one placeholder ('?') of prepared statement */
-class Item_param :public Item
+/*
+ Assign placeholder value from bind data.
+ Note, that 'len' has different semantics in embedded library (as we
+ don't need to check that packet is not broken there). See
+ sql_prepare.cc for details.
+*/
+typedef void (*set_param_func_t)(Item_param *param, uchar **pos, ulong len);
+typedef void (*get_param_func_t)(Item_param *param, void* opaque);
+
+class Item_param : public Item,
+ private Settable_routine_parameter
{
char cnvbuf[MAX_FIELD_WIDTH];
String cnvstr;
@@ -1542,13 +1552,18 @@ public:
void set_time(TIME *tm, timestamp_type type, uint32 max_length_arg);
bool set_from_user_var(THD *thd, const user_var_entry *entry);
void reset();
- /*
+
+ /**
Assign placeholder value from bind data.
- Note, that 'len' has different semantics in embedded library (as we
- don't need to check that packet is not broken there). See
- sql_prepare.cc for details.
+ This function pointer is a memento, to be used by the caller.
+ */
+ set_param_func_t set_param_func;
+
+ /**
+ Assign output value to the bind data.
+ This function pointer is a memento, to be used by the caller.
*/
- void (*set_param_func)(Item_param *param, uchar **pos, ulong len);
+ get_param_func_t get_param_func;
const String *query_val_str(String *str) const;
@@ -1583,6 +1598,14 @@ public:
Otherwise return FALSE.
*/
bool eq(const Item *item, bool binary_cmp) const;
+
+ Settable_routine_parameter *get_settable_routine_parameter()
+ {
+ return this;
+ }
+
+private:
+ bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
};
--- 1.126/sql/protocol.cc 2008-05-20 10:33:27 -06:00
+++ 1.127/sql/protocol.cc 2008-05-20 10:33:27 -06:00
@@ -695,6 +695,108 @@ err:
}
+bool Protocol::send_parameters(List<Item_param> *list, uint flags)
+{
+ List_iterator_fast<Item_param> it(*list);
+ Item_param *item;
+ char buff[80];
+ String tmp((char*) buff,sizeof(buff),&my_charset_bin);
+ Protocol_text prot(thd);
+ String *local_packet= prot.storage_packet();
+ CHARSET_INFO *thd_charset= thd->variables.character_set_results;
+ DBUG_ENTER("send_fields");
+
+#ifndef DBUG_OFF
+ field_types= (enum_field_types*) thd->alloc(sizeof(field_types) *
+ list->elements);
+ uint count= 0;
+#endif
+
+ DBUG_ASSERT(thd->client_capabilities & CLIENT_BIDIR_PARAM);
+ DBUG_ASSERT(thd->client_capabilities & CLIENT_PROTOCOL_41);
+
+ while ((item=it++))
+ {
+ char *pos;
+ CHARSET_INFO *cs= system_charset_info;
+ Send_field field;
+ item->make_field(&field);
+
+ prot.prepare_for_resend();
+
+ if (prot.store(STRING_WITH_LEN("def"), cs, thd_charset) ||
+ prot.store(field.db_name, (uint) strlen(field.db_name),
+ cs, thd_charset) ||
+ prot.store(field.table_name, (uint) strlen(field.table_name),
+ cs, thd_charset) ||
+ prot.store(field.org_table_name, (uint) strlen(field.org_table_name),
+ cs, thd_charset) ||
+ prot.store(field.col_name, (uint) strlen(field.col_name),
+ cs, thd_charset) ||
+ prot.store(field.org_col_name, (uint) strlen(field.org_col_name),
+ cs, thd_charset) ||
+ local_packet->realloc(local_packet->length()+12))
+ goto err;
+ /* Store fixed length fields */
+ pos= (char*) local_packet->ptr()+local_packet->length();
+ *pos++= 12; // Length of packed fields
+ if (item->collation.collation == &my_charset_bin || thd_charset == NULL)
+ {
+ /* No conversion */
+ int2store(pos, field.charsetnr);
+ int4store(pos+2, field.length);
+ }
+ else
+ {
+ /* With conversion */
+ uint max_char_len;
+ int2store(pos, thd_charset->number);
+ /*
+ For TEXT/BLOB columns, field_length describes the maximum data
+ length in bytes. There is no limit to the number of characters
+ that a TEXT column can store, as long as the data fits into
+ the designated space.
+ For the rest of textual columns, field_length is evaluated as
+ char_count * mbmaxlen, where character count is taken from the
+ definition of the column. In other words, the maximum number
+ of characters here is limited by the column definition.
+ */
+ max_char_len= (field.type >= (int) MYSQL_TYPE_TINY_BLOB &&
+ field.type <= (int) MYSQL_TYPE_BLOB) ?
+ field.length / item->collation.collation->mbminlen :
+ field.length / item->collation.collation->mbmaxlen;
+ int4store(pos+2, max_char_len * thd_charset->mbmaxlen);
+ }
+ pos[6]= field.type;
+ int2store(pos+7,field.flags);
+ pos[9]= (char) field.decimals;
+ pos[10]= 0; // For the future
+ pos[11]= 0; // For the future
+ pos+= 12;
+
+ local_packet->length((uint) (pos - local_packet->ptr()));
+ if (prot.write())
+ break; /* purecov: inspected */
+#ifndef DBUG_OFF
+ field_types[count++]= field.type;
+#endif
+ }
+
+ if (flags & SEND_EOF)
+ write_eof_packet(thd, &thd->net);
+
+ DBUG_RETURN(FALSE);
+
+
+ // FIXME: DBUG_RETURN(prepare_for_send(list));
+
+err:
+ my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES),
+ MYF(0)); /* purecov: inspected */
+ DBUG_RETURN(TRUE); /* purecov: inspected */
+}
+
+
bool Protocol::write()
{
DBUG_ENTER("Protocol::write");
--- 1.128/sql-common/client.c 2008-05-20 10:33:27 -06:00
+++ 1.129/sql-common/client.c 2008-05-20 10:33:27 -06:00
@@ -1514,6 +1514,12 @@ mysql_init(MYSQL *mysql)
*/
mysql->reconnect= 0;
+ /*
+ This client knows about the bi directional parameter binding protocol
+ used by prepare statements.
+ */
+ mysql->options.client_flag|= CLIENT_BIDIR_PARAM;
+
return mysql;
}
@@ -2178,10 +2184,23 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
if (db)
client_flag|=CLIENT_CONNECT_WITH_DB;
+ // FIXME
+ client_flag |= CLIENT_BIDIR_PARAM;
+
+#ifdef LATER
/* Remove options that server doesn't support */
client_flag= ((client_flag &
~(CLIENT_COMPRESS | CLIENT_SSL | CLIENT_PROTOCOL_41)) |
(client_flag & mysql->server_capabilities));
+#endif
+
+ DBUG_ASSERT(mysql->server_capabilities & CLIENT_BIDIR_PARAM);
+
+ client_flag= client_flag & mysql->server_capabilities;
+
+
+
+
#ifndef HAVE_COMPRESS
client_flag&= ~CLIENT_COMPRESS;
#endif
--- 1.23/mysql-test/t/mysql_client_test.test 2008-05-20 10:33:27 -06:00
+++ 1.24/mysql-test/t/mysql_client_test.test 2008-05-20 10:33:27 -06:00
@@ -8,8 +8,13 @@
# server or run mysql-test-run --debug mysql_client_test and check
# var/log/mysql_client_test.trace
---exec echo "$MYSQL_CLIENT_TEST" > $MYSQLTEST_VARDIR/log/mysql_client_test.log
2>&1
---exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M >>
$MYSQLTEST_VARDIR/log/mysql_client_test.log 2>&1
+#
+# When --exec fails, the error log is overwritten, so it's critical
+# to capture the test output in a file *not* named after the
+# basename of the test (mysql_client_test).
+
+--exec echo "$MYSQL_CLIENT_TEST" > $MYSQLTEST_VARDIR/log/mysql_client_test_log.log
2>&1
+--exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M --debug >>
$MYSQLTEST_VARDIR/log/mysql_client_test_log.log 2>&1
# End of 4.1 tests
echo ok;
--- New file ---
+++ mysql-test/t/marc.test 08/05/20 10:32:38
# This test should work in embedded server after we fix mysqltest
-- source include/not_embedded.inc
# We run with different binaries for normal and --embedded-server
#
# If this test fails with "command "$MYSQL_CLIENT_TEST" failed",
# you should either run mysql_client_test separartely against a running
# server or run mysql-test-run --debug mysql_client_test and check
# var/log/mysql_client_test.trace
#
# When --exec fails, the error log is overwritten, so it's critical
# to capture the test output in a file *not* named after the
# basename of the test (mysql_client_test).
--exec echo "$MYSQL_CLIENT_TEST" > $MYSQLTEST_VARDIR/log/mysql_client_test_log.log
2>&1
--exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M --debug test_bug17898_a >>
$MYSQLTEST_VARDIR/log/mysql_client_test_log.log 2>&1
# End of 4.1 tests
echo ok;
--- 1.39/sql/protocol.h 2008-05-20 10:33:27 -06:00
+++ 1.40/sql/protocol.h 2008-05-20 10:33:27 -06:00
@@ -22,6 +22,7 @@ class i_string;
class THD;
typedef struct st_mysql_field MYSQL_FIELD;
typedef struct st_mysql_rows MYSQL_ROWS;
+class Item_param;
class Protocol
{
@@ -51,7 +52,8 @@ public:
void init(THD* thd_arg);
enum { SEND_NUM_ROWS= 1, SEND_DEFAULTS= 2, SEND_EOF= 4 };
- virtual bool send_fields(List<Item> *list, uint flags);
+ bool send_fields(List<Item> *list, uint flags);
+ bool send_parameters(List<Item_param> *list, uint flags);
bool store(I_List<i_string> *str_list);
bool store(const char *from, CHARSET_INFO *cs);
--- 1.1/sql/sql_connect.cc 2008-05-20 10:33:27 -06:00
+++ 1.2/sql/sql_connect.cc 2008-05-20 10:33:27 -06:00
@@ -719,6 +719,12 @@ static int check_connection(THD *thd)
client_flags |= CLIENT_SSL; /* Wow, SSL is available! */
#endif /* HAVE_OPENSSL */
+
+ // FIXME, prototyping
+ client_flags |= CLIENT_BIDIR_PARAM;
+
+ DBUG_PRINT("info", ("server capabilities: %lu", client_flags));
+
end= strnmov(buff, server_version, SERVER_VERSION_LENGTH) + 1;
int4store((uchar*) end, thd->thread_id);
end+= 4;
@@ -779,10 +785,11 @@ static int check_connection(THD *thd)
end= (char*) net->read_pos+5;
}
+ DBUG_PRINT("info", ("client capabilities: %lu", thd->client_capabilities));
+
if (thd->client_capabilities & CLIENT_IGNORE_SPACE)
thd->variables.sql_mode|= MODE_IGNORE_SPACE;
#ifdef HAVE_OPENSSL
- DBUG_PRINT("info", ("client capabilities: %lu", thd->client_capabilities));
if (thd->client_capabilities & CLIENT_SSL)
{
/* Do the SSL layering. */
--- 1.209/sql/sql_prepare.cc 2008-05-20 10:33:27 -06:00
+++ 1.210/sql/sql_prepare.cc 2008-05-20 10:33:27 -06:00
@@ -241,15 +241,31 @@ static bool send_prep_stmt(Prepared_stat
tmp= min(stmt->thd->total_warn_count, 65535);
int2store(buff+10, tmp);
- /*
- Send types and names of placeholders to the client
- XXX: fix this nasty upcast from List<Item_param> to List<Item>
- */
- DBUG_RETURN(my_net_write(net, buff, sizeof(buff)) ||
- (stmt->param_count &&
- stmt->thd->protocol_text.send_fields((List<Item> *)
- &stmt->lex->param_list,
- Protocol::SEND_EOF)));
+ if (my_net_write(net, buff, sizeof(buff)))
+ DBUG_RETURN(TRUE);
+
+ if (stmt->param_count)
+ {
+ Protocol *prot= & stmt->thd->protocol_text;
+
+ if (false && stmt->thd->client_capabilities & CLIENT_BIDIR_PARAM)
+ {
+ DBUG_RETURN(prot->send_parameters(& stmt->lex->param_list,
+ Protocol::SEND_EOF));
+ }
+ else
+ {
+ /*
+ Send types and names of placeholders to the client
+ TODO: fix this nasty cast from List<Item_param> to List<Item>
+ */
+ DBUG_RETURN(prot->send_fields((List<Item> *)
+ &stmt->lex->param_list,
+ Protocol::SEND_EOF));
+ }
+ }
+
+ DBUG_RETURN(FALSE);
}
#else
static bool send_prep_stmt(Prepared_statement *stmt,
@@ -387,6 +403,11 @@ static void set_param_int32(Item_param *
*pos+= 4;
}
+static void get_param_int32(Item_param *param, Protocol *prot)
+{
+ prot->store(param->val_int());
+}
+
static void set_param_int64(Item_param *param, uchar **pos, ulong len)
{
longlong value;
@@ -582,6 +603,9 @@ static void set_param_str(Item_param *pa
static void setup_one_conversion_function(THD *thd, Item_param *param,
uchar param_type)
{
+ // FIXME
+ param->get_param_func= NULL;
+
switch (param_type) {
case MYSQL_TYPE_TINY:
param->set_param_func= set_param_tiny;
@@ -595,6 +619,7 @@ static void setup_one_conversion_functio
break;
case MYSQL_TYPE_LONG:
param->set_param_func= set_param_int32;
+ param->get_param_func= (get_param_func_t) get_param_int32;
param->item_type= Item::INT_ITEM;
param->item_result_type= INT_RESULT;
break;
@@ -2305,10 +2330,40 @@ void mysql_stmt_execute(THD *thd, char *
*/
DBUG_ASSERT(thd->free_list == NULL);
+ DBUG_ASSERT(thd->net.no_send_ok == 0);
+ // thd->net.no_send_ok= 1;
+
error= stmt->execute(&expanded_query,
test(flags & (ulong) CURSOR_TYPE_READ_ONLY));
+
+ // thd->net.no_send_ok= 0;
+
+ // send_ok(thd);
+
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(), WAIT_PRIOR);
+
+#ifndef EMBEDDED_LIBRARY
+ if (false && error == 0)
+ {
+ // FIXME: prototyping
+
+ char buff[6];
+ buff[0] = 0x02;
+ buff[1] = 0x01;
+ buff[2] = 0xDE;
+ buff[3] = 0xAD;
+ buff[4] = 0xBE;
+ buff[5] = 0xEF;
+
+ DBUG_PRINT("marc", ("FAKE packet"));
+ error= my_net_write(& stmt->thd->net, buff, sizeof(buff));
+ thd->protocol->flush();
+ }
+#else
+#endif
+
+
if (error == 0)
{
const char *format= "[%lu] %.*b";
--- 1.231/tests/mysql_client_test.c 2008-05-20 10:33:27 -06:00
+++ 1.232/tests/mysql_client_test.c 2008-05-20 10:33:27 -06:00
@@ -784,6 +784,18 @@ static void do_verify_prepare_field(MYSQ
DIE_UNLESS(strcmp(field->def, def) == 0);
}
+static bool get_BIDIR_PARAM(MYSQL *mysql)
+{
+ bool have_bidir_param= (mysql->client_flag & CLIENT_BIDIR_PARAM);
+
+ if (!opt_silent)
+ {
+ fprintf(stdout, "\n CLIENT_BIDIR_PARAM: %s",
+ (have_bidir_param ? "TRUE" : "FALSE"));
+ }
+
+ return have_bidir_param;
+}
/* Utility function to verify the parameter count */
@@ -16050,6 +16062,104 @@ static void test_bug24179()
DBUG_VOID_RETURN;
}
+// MARC:
+
+/*
+ Bug#17898 (No straightforward way to deal with output parameters)
+
+*/
+static void test_bug17898_a()
+{
+ static const char* proc_17898_a=
+ "CREATE PROCEDURE proc_17898_a(IN p1 int, INOUT p2 int, OUT p3 int)\n"
+ "BEGIN\n"
+ "SET p2 := p2 + p1;\n"
+ "SET p3 := p2 + 100;\n"
+ "END\n"
+ ;
+
+ static const char* prep_call=
+ "CALL proc_17898_a(?, ?, ?)"
+ ;
+
+ int rc;
+ MYSQL_STMT *stmt;
+ MYSQL_BIND my_bind[3];
+ bool have_BIDIR_PARAM;
+ int p1_data;
+ int p2_data;
+ int p3_data;
+
+ DBUG_ENTER("test_bug17898_a");
+ myheader("test_bug17898_a");
+
+ have_BIDIR_PARAM = get_BIDIR_PARAM(mysql);
+
+ rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS proc_17898_a");
+ DIE_UNLESS(rc == 0);
+
+ rc= mysql_query(mysql, proc_17898_a);
+ DIE_UNLESS(rc == 0);
+
+ stmt= mysql_stmt_init(mysql);
+ DIE_UNLESS(stmt);
+
+ rc= mysql_stmt_prepare(stmt, prep_call, strlen(prep_call));
+ check_execute(stmt, rc);
+
+ verify_param_count(stmt, 3);
+
+ bzero((char*) my_bind, sizeof(my_bind));
+
+ my_bind[0].buffer_type= MYSQL_TYPE_LONG;
+ my_bind[0].buffer= (void *) & p1_data;
+
+ my_bind[1].buffer_type= MYSQL_TYPE_LONG;
+ my_bind[1].buffer= (void *) & p2_data;
+
+ my_bind[2].buffer_type= MYSQL_TYPE_LONG;
+ my_bind[2].buffer= (void *) & p3_data;
+
+ p1_data= 12;
+ p2_data= 24;
+ p3_data= 99;
+
+ rc= mysql_stmt_bind_param(stmt, my_bind);
+ check_execute(stmt, rc);
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ /* Before fetching the result set, parameters are unchanged */
+ DIE_UNLESS(p1_data == 12);
+ DIE_UNLESS(p2_data == 24);
+ DIE_UNLESS(p3_data == 99);
+
+ rc= my_process_stmt_result(stmt);
+ DIE_UNLESS(rc == 0); /* 0 rows */
+
+ if (have_BIDIR_PARAM)
+ {
+ /* After fetching the result set, output parameters are changed */
+ DIE_UNLESS(p1_data == 12);
+ DIE_UNLESS(p2_data == 36);
+ DIE_UNLESS(p3_data == 136);
+ }
+ else
+ {
+ DIE_UNLESS(p1_data == 12);
+ DIE_UNLESS(p2_data == 24);
+ DIE_UNLESS(p3_data == 99);
+ }
+
+ rc= mysql_query(mysql, "DROP PROCEDURE proc_17898_a");
+ DIE_UNLESS(rc == 0);
+
+ mysql_stmt_close(stmt);
+
+ DBUG_VOID_RETURN;
+}
+
/*
Read and parse arguments and MySQL options from my.cnf
@@ -16335,6 +16445,7 @@ static struct my_tests_st my_tests[]= {
{ "test_status", test_status },
{ "test_bug24179", test_bug24179 },
{ "test_ps_query_cache", test_ps_query_cache },
+ { "test_bug17898_a", test_bug17898_a },
{ 0, 0 }
};
| Thread |
|---|
| • bk commit into 5.1 tree (malff:1.2591) | marc.alff | 20 May |