Commit 2401930b authored by Lena Startseva's avatar Lena Startseva

MDEV-31005: Make working cursor-protocol

Added ability to disable/enable (--disable_cursor_protocol/
--enable_cursor_protocol) cursor-protocol in tests. If
"--disable_cursor_protocol" is used then ps-protocol is also
disabled. With cursor-protocol prepare statement is executed
only once. For "--cursor-protocol" added filter for queries:
it is executed only for "SELECT" queries.
parent 03807c84
...@@ -164,6 +164,7 @@ static struct property prop_list[] = { ...@@ -164,6 +164,7 @@ static struct property prop_list[] = {
{ &ps_protocol_enabled, 0, 0, 0, "$ENABLED_PS_PROTOCOL" }, { &ps_protocol_enabled, 0, 0, 0, "$ENABLED_PS_PROTOCOL" },
{ &ps2_protocol_enabled, 0, 0, 0, "$ENABLED_PS2_PROTOCOL" }, { &ps2_protocol_enabled, 0, 0, 0, "$ENABLED_PS2_PROTOCOL" },
{ &view_protocol_enabled, 0, 0, 0, "$ENABLED_VIEW_PROTOCOL"}, { &view_protocol_enabled, 0, 0, 0, "$ENABLED_VIEW_PROTOCOL"},
{ &cursor_protocol_enabled, 0, 0, 0, "$ENABLED_CURSOR_PROTOCOL"},
{ &service_connection_enabled, 0, 1, 0, "$ENABLED_SERVICE_CONNECTION"}, { &service_connection_enabled, 0, 1, 0, "$ENABLED_SERVICE_CONNECTION"},
{ &disable_query_log, 0, 0, 1, "$ENABLED_QUERY_LOG" }, { &disable_query_log, 0, 0, 1, "$ENABLED_QUERY_LOG" },
{ &disable_result_log, 0, 0, 1, "$ENABLED_RESULT_LOG" }, { &disable_result_log, 0, 0, 1, "$ENABLED_RESULT_LOG" },
...@@ -181,6 +182,7 @@ enum enum_prop { ...@@ -181,6 +182,7 @@ enum enum_prop {
P_PS, P_PS,
P_PS2, P_PS2,
P_VIEW, P_VIEW,
P_CURSOR,
P_CONN, P_CONN,
P_QUERY, P_QUERY,
P_RESULT, P_RESULT,
...@@ -273,6 +275,7 @@ static regex_t ps_re; /* the query can be run using PS protocol */ ...@@ -273,6 +275,7 @@ static regex_t ps_re; /* the query can be run using PS protocol */
static regex_t ps2_re; /* the query can be run using PS protocol with second execution*/ static regex_t ps2_re; /* the query can be run using PS protocol with second execution*/
static regex_t sp_re; /* the query can be run as a SP */ static regex_t sp_re; /* the query can be run as a SP */
static regex_t view_re; /* the query can be run as a view*/ static regex_t view_re; /* the query can be run as a view*/
static regex_t cursor_re; /* the query can be run with cursor protocol*/
static void init_re(void); static void init_re(void);
static int match_re(regex_t *, char *); static int match_re(regex_t *, char *);
...@@ -391,6 +394,7 @@ enum enum_commands { ...@@ -391,6 +394,7 @@ enum enum_commands {
Q_CHARACTER_SET, Q_DISABLE_PS_PROTOCOL, Q_ENABLE_PS_PROTOCOL, Q_CHARACTER_SET, Q_DISABLE_PS_PROTOCOL, Q_ENABLE_PS_PROTOCOL,
Q_DISABLE_PS2_PROTOCOL, Q_ENABLE_PS2_PROTOCOL, Q_DISABLE_PS2_PROTOCOL, Q_ENABLE_PS2_PROTOCOL,
Q_DISABLE_VIEW_PROTOCOL, Q_ENABLE_VIEW_PROTOCOL, Q_DISABLE_VIEW_PROTOCOL, Q_ENABLE_VIEW_PROTOCOL,
Q_DISABLE_CURSOR_PROTOCOL, Q_ENABLE_CURSOR_PROTOCOL,
Q_DISABLE_SERVICE_CONNECTION, Q_ENABLE_SERVICE_CONNECTION, Q_DISABLE_SERVICE_CONNECTION, Q_ENABLE_SERVICE_CONNECTION,
Q_ENABLE_NON_BLOCKING_API, Q_DISABLE_NON_BLOCKING_API, Q_ENABLE_NON_BLOCKING_API, Q_DISABLE_NON_BLOCKING_API,
Q_DISABLE_RECONNECT, Q_ENABLE_RECONNECT, Q_DISABLE_RECONNECT, Q_ENABLE_RECONNECT,
...@@ -487,6 +491,8 @@ const char *command_names[]= ...@@ -487,6 +491,8 @@ const char *command_names[]=
"enable_ps2_protocol", "enable_ps2_protocol",
"disable_view_protocol", "disable_view_protocol",
"enable_view_protocol", "enable_view_protocol",
"disable_cursor_protocol",
"enable_cursor_protocol",
"disable_service_connection", "disable_service_connection",
"enable_service_connection", "enable_service_connection",
"enable_non_blocking_api", "enable_non_blocking_api",
...@@ -8658,13 +8664,22 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, ...@@ -8658,13 +8664,22 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command,
#if MYSQL_VERSION_ID >= 50000 #if MYSQL_VERSION_ID >= 50000
if (cursor_protocol_enabled) if (cursor_protocol_enabled)
{ {
ps2_protocol_enabled = 0;
/* /*
Use cursor when retrieving result Use cursor for queries matching the filter,
else reset cursor type
*/ */
ulong type= CURSOR_TYPE_READ_ONLY; if (match_re(&cursor_re, query))
if (mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type)) {
die("mysql_stmt_attr_set(STMT_ATTR_CURSOR_TYPE) failed': %d %s", /*
mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); Use cursor when retrieving result
*/
ulong type= CURSOR_TYPE_READ_ONLY;
if (mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type))
die("mysql_stmt_attr_set(STMT_ATTR_CURSOR_TYPE) failed': %d %s",
mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
}
} }
#endif #endif
...@@ -8726,9 +8741,10 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, ...@@ -8726,9 +8741,10 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command,
{ {
/* /*
When running in cursor_protocol get the warnings from execute here When running in cursor_protocol get the warnings from execute here
and keep them in a separate string for later. and keep them in a separate string for later. Cursor_protocol is used
only for queries matching the filter "cursor_re".
*/ */
if (cursor_protocol_enabled && !disable_warnings) if (cursor_protocol_enabled && match_re(&cursor_re, query) && !disable_warnings)
append_warnings(&ds_execute_warnings, mysql); append_warnings(&ds_execute_warnings, mysql);
if (!disable_result_log && if (!disable_result_log &&
...@@ -8876,6 +8892,16 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, ...@@ -8876,6 +8892,16 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command,
var_set_errno(mysql_stmt_errno(stmt)); var_set_errno(mysql_stmt_errno(stmt));
display_optimizer_trace(cn, ds); display_optimizer_trace(cn, ds);
#if MYSQL_VERSION_ID >= 50000
if (cursor_protocol_enabled)
{
ulong type= CURSOR_TYPE_NO_CURSOR;
if (mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type))
die("mysql_stmt_attr_set(STMT_ATTR_CURSOR_TYPE) failed': %d %s",
mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
}
#endif
revert_properties(); revert_properties();
/* Close the statement if reconnect, need new prepare */ /* Close the statement if reconnect, need new prepare */
...@@ -9742,10 +9768,19 @@ void init_re(void) ...@@ -9742,10 +9768,19 @@ void init_re(void)
"^(" "^("
"[[:space:]]*SELECT[[:space:]])"; "[[:space:]]*SELECT[[:space:]])";
/*
Filter for queries that can be run with
cursor protocol
*/
const char *cursor_re_str =
"^("
"[[:space:]]*SELECT[[:space:]])";
init_re_comp(&ps_re, ps_re_str); init_re_comp(&ps_re, ps_re_str);
init_re_comp(&ps2_re, ps2_re_str); init_re_comp(&ps2_re, ps2_re_str);
init_re_comp(&sp_re, sp_re_str); init_re_comp(&sp_re, sp_re_str);
init_re_comp(&view_re, view_re_str); init_re_comp(&view_re, view_re_str);
init_re_comp(&cursor_re, cursor_re_str);
} }
...@@ -9783,6 +9818,7 @@ void free_re(void) ...@@ -9783,6 +9818,7 @@ void free_re(void)
regfree(&ps2_re); regfree(&ps2_re);
regfree(&sp_re); regfree(&sp_re);
regfree(&view_re); regfree(&view_re);
regfree(&cursor_re);
} }
/****************************************************************************/ /****************************************************************************/
...@@ -10572,6 +10608,17 @@ int main(int argc, char **argv) ...@@ -10572,6 +10608,17 @@ int main(int argc, char **argv)
case Q_ENABLE_VIEW_PROTOCOL: case Q_ENABLE_VIEW_PROTOCOL:
set_property(command, P_VIEW, view_protocol); set_property(command, P_VIEW, view_protocol);
break; break;
case Q_DISABLE_CURSOR_PROTOCOL:
set_property(command, P_CURSOR, 0);
if (cursor_protocol)
set_property(command, P_PS, 0);
/* Close any open statements */
close_statements();
break;
case Q_ENABLE_CURSOR_PROTOCOL:
set_property(command, P_CURSOR, cursor_protocol);
set_property(command, P_PS, ps_protocol);
break;
case Q_DISABLE_SERVICE_CONNECTION: case Q_DISABLE_SERVICE_CONNECTION:
set_property(command, P_CONN, 0); set_property(command, P_CONN, 0);
/* Close only util connections */ /* Close only util connections */
......
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