From 4c80e67ff8ebc7cca3f2b49801c48b4555a4b883 Mon Sep 17 00:00:00 2001 From: Rucha Deodhar Date: Wed, 7 Jan 2026 02:17:25 +0530 Subject: [PATCH 1/2] MDEV-36764: Unexpected collation when using json_table Analysis: The collation is hard coded. Fix: The table initially had system character set hardcoded. However, a table field should derive character set and collation from table and table should derive it from database. Hence made necessary change to reflect that. --- mysql-test/suite/json/r/json_table.result | 30 +++++++++++++++---- .../suite/json/r/json_table_mysql.result | 9 +++--- mysql-test/suite/json/t/json_table.test | 18 +++++++++++ sql/json_table.cc | 3 +- 4 files changed, 49 insertions(+), 11 deletions(-) diff --git a/mysql-test/suite/json/r/json_table.result b/mysql-test/suite/json/r/json_table.result index 9f874d6264e8c..e406087751981 100644 --- a/mysql-test/suite/json/r/json_table.result +++ b/mysql-test/suite/json/r/json_table.result @@ -269,7 +269,7 @@ from t1, json_table(t1.json, '$' columns (value varchar(32) PATH '$.value')) T; show create table tj1; Table Create Table tj1 CREATE TABLE `tj1` ( - `value` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL + `value` varchar(32) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci drop table t1; drop table tj1; @@ -1100,7 +1100,7 @@ name VARCHAR(10) PATH '$.name' ) ) AS jt; collation(name) -utf8mb4_general_ci +latin1_swedish_ci SELECT collation(name) FROM json_table('[{"name":"Jeans"}]', '$[*]' COLUMNS( @@ -1108,7 +1108,7 @@ name VARCHAR(10) COLLATE DEFAULT PATH '$.name' ) ) AS jt; collation(name) -utf8mb4_general_ci +latin1_swedish_ci SELECT collation(name) FROM json_table('[{"name":"Jeans"}]', '$[*]' COLUMNS( @@ -1116,7 +1116,7 @@ name VARCHAR(10) BINARY PATH '$.name' ) ) AS jt; collation(name) -utf8mb4_bin +latin1_bin CREATE VIEW v1 AS SELECT * FROM json_table('[{"name":"Jeans"}]', '$[*]' @@ -1129,7 +1129,7 @@ View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `jt`.`name` AS `name` from JSON_TABLE('[{"name":"Jeans"}]', '$[*]' COLUMNS (`name` varchar(10) PATH '$.name')) `jt` latin1 latin1_swedish_ci SELECT collation(name) FROM v1; collation(name) -utf8mb4_general_ci +latin1_swedish_ci DROP VIEW v1; CREATE VIEW v1 AS SELECT * @@ -1143,7 +1143,7 @@ View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `jt`.`name` AS `name` from JSON_TABLE('[{"name":"Jeans"}]', '$[*]' COLUMNS (`name` varchar(10) PATH '$.name')) `jt` latin1 latin1_swedish_ci SELECT collation(name) FROM v1; collation(name) -utf8mb4_general_ci +latin1_swedish_ci DROP VIEW v1; CREATE VIEW v1 AS SELECT * @@ -1280,4 +1280,22 @@ Second Element { "value": 2 } DROP VIEW test_view; +# +# MDEV-36764: Unexpected collation when using json_table +# +CREATE DATABASE collation_testing CHARACTER SET='utf8mb4' COLLATE='utf8mb4_uca1400_ai_ci'; +USE collation_testing; +CREATE TABLE table_with_longtext_column (column_with_json LONGTEXT); +INSERT INTO table_with_longtext_column VALUES ('[{"property": "value"}]'); +SELECT COLLATION(column_with_json) FROM table_with_longtext_column; +COLLATION(column_with_json) +utf8mb4_uca1400_ai_ci +SELECT COLLATION(JSON_VALUE(column_with_json, "$.value")) FROM table_with_longtext_column; +COLLATION(JSON_VALUE(column_with_json, "$.value")) +utf8mb4_uca1400_ai_ci +SELECT COLLATION(virtual_table_from_json.property) FROM JSON_TABLE((SELECT column_with_json FROM table_with_longtext_column),'$[*]' COLUMNS (property varchar(100) path '$.property')) AS virtual_table_from_json; +COLLATION(virtual_table_from_json.property) +utf8mb4_uca1400_ai_ci +DROP TABLE table_with_longtext_column; +DROP DATABASE collation_testing; # End of 10.11 test diff --git a/mysql-test/suite/json/r/json_table_mysql.result b/mysql-test/suite/json/r/json_table_mysql.result index 8380ba0772065..566180f22fd31 100644 --- a/mysql-test/suite/json/r/json_table_mysql.result +++ b/mysql-test/suite/json/r/json_table_mysql.result @@ -1123,7 +1123,7 @@ SELECT col_varchar_key FROM JSON_TABLE( (col_varchar_key VARCHAR(10) PATH "$.col_key")) AS innr1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY innr1 ALL NULL NULL NULL NULL 40 Table function: json_table; Using where +2 MATERIALIZED innr1 ALL NULL NULL NULL NULL 40 Table function: json_table SELECT * FROM t1 WHERE col_varchar_key IN ( SELECT col_varchar_key FROM JSON_TABLE( '[{"col_key": 1},{"col_key": 2}]', "$[*]" COLUMNS @@ -1136,7 +1136,8 @@ SELECT col_varchar_key FROM JSON_TABLE( (col_varchar_key VARCHAR(10) PATH "$.col_key")) AS innr1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 -1 PRIMARY innr1 ALL NULL NULL NULL NULL 40 Table function: json_table; Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +1 PRIMARY eq_ref distinct_key distinct_key 13 func 1 Using where +2 MATERIALIZED innr1 ALL NULL NULL NULL NULL 40 Table function: json_table DROP TABLE t1; # # Bug#26711551: WL8867:CONDITIONAL JUMP IN JSON_TABLE_COLUMN::CLEANUP @@ -1467,7 +1468,7 @@ FROM JSON_TABLE('"test"', '$' COLUMNS(col VARCHAR(10) PATH '$')) AS a; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `col` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL + `col` varchar(10) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci SET @@SESSION.collation_connection = latin1_bin; CREATE TABLE t2 SELECT a.col @@ -1475,7 +1476,7 @@ FROM JSON_TABLE('"test"', '$' COLUMNS(col VARCHAR(10) PATH '$')) AS a; SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( - `col` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL + `col` varchar(10) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci DROP TABLE t1, t2; SET @@SESSION.character_set_connection = DEFAULT; diff --git a/mysql-test/suite/json/t/json_table.test b/mysql-test/suite/json/t/json_table.test index aac9005cbd6b3..bab6d4b777f4d 100644 --- a/mysql-test/suite/json/t/json_table.test +++ b/mysql-test/suite/json/t/json_table.test @@ -1103,4 +1103,22 @@ SELECT * FROM JSON_TABLE(' DROP VIEW test_view; + +--echo # +--echo # MDEV-36764: Unexpected collation when using json_table +--echo # + +CREATE DATABASE collation_testing CHARACTER SET='utf8mb4' COLLATE='utf8mb4_uca1400_ai_ci'; +USE collation_testing; + +CREATE TABLE table_with_longtext_column (column_with_json LONGTEXT); +INSERT INTO table_with_longtext_column VALUES ('[{"property": "value"}]'); + +SELECT COLLATION(column_with_json) FROM table_with_longtext_column; +SELECT COLLATION(JSON_VALUE(column_with_json, "$.value")) FROM table_with_longtext_column; +SELECT COLLATION(virtual_table_from_json.property) FROM JSON_TABLE((SELECT column_with_json FROM table_with_longtext_column),'$[*]' COLUMNS (property varchar(100) path '$.property')) AS virtual_table_from_json; + +DROP TABLE table_with_longtext_column; +DROP DATABASE collation_testing; + --echo # End of 10.11 test diff --git a/sql/json_table.cc b/sql/json_table.cc index 35a02eb2bbe8d..e5ac60085bf19 100644 --- a/sql/json_table.cc +++ b/sql/json_table.cc @@ -707,6 +707,7 @@ TABLE *Create_json_table::start(THD *thd, TABLE_SHARE *share; DBUG_ENTER("Create_json_table::start"); + param->table_charset= thd->variables.collation_database; param->tmp_name= "json"; if (!(table= Create_tmp_table::start(thd, param, table_alias))) DBUG_RETURN(0); @@ -758,7 +759,7 @@ bool Create_json_table::add_json_table_fields(THD *thd, TABLE *table, uint fieldnr= 0; MEM_ROOT *mem_root_save= thd->mem_root; List_iterator_fast jc_i(jt->m_columns); - Column_derived_attributes da(&my_charset_utf8mb4_general_ci); + Column_derived_attributes da(share->table_charset); DBUG_ENTER("add_json_table_fields"); thd->mem_root= &table->mem_root; From 8744ed87f7bf35f09977cf929331a225f73f19a4 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 26 Jun 2026 21:47:23 +0200 Subject: [PATCH 2/2] MDEV-25817 proxy protocol: successful login does not reset connect errors With proxy protocol thd_set_peer_addr() runs twice (proxy host, then the real client from the proxy header). Connect errors are accounted against the real client, but check_connection() incorrectly uses condition on the proxy host's count, rather than real client's address. Fix: reset both the proxy host, and real client's connect errors on successful connection. Added tests for incomplete handshake, and reset behavior, under proxy protocol, for both real client errors, and proxy host errors. --- include/mysql_com.h | 2 + mysql-test/main/mysql_client_test.result | 2 + mysql-test/main/mysql_client_test.test | 2 + sql/net_serv.cc | 14 +- sql/sql_connect.cc | 16 +- tests/mysql_client_test.c | 225 +++++++++++++++++++++++ 6 files changed, 251 insertions(+), 10 deletions(-) diff --git a/include/mysql_com.h b/include/mysql_com.h index 1b796ce402490..42b378677dcb7 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -488,6 +488,8 @@ typedef struct st_net { unsigned char compress; my_bool pkt_nr_can_be_reset; my_bool using_proxy_protocol; + /* proxy protocol: real client address has connect errors to reset on login */ + my_bool have_proxy_protocol_connect_errors; /* Pointer to query object in query cache, do not equal NULL (0) for queries in cache that have not stored its results yet diff --git a/mysql-test/main/mysql_client_test.result b/mysql-test/main/mysql_client_test.result index 4c7b20314c05d..45b654560a680 100644 --- a/mysql-test/main/mysql_client_test.result +++ b/mysql-test/main/mysql_client_test.result @@ -8,6 +8,8 @@ SET @old_general_log= @@global.general_log; SET @old_slow_query_log= @@global.slow_query_log; call mtr.add_suppression(" Error reading file './client_test_db/test_frm_bug.frm'"); call mtr.add_suppression(" IP address .* could not be resolved"); +call mtr.add_suppression("Aborted connection .* host: '192.0.2.50'"); +call mtr.add_suppression("Aborted connection .* host: 'santa.claus.ipv4.example.com'"); ok # cat MYSQL_TMP_DIR/test_wl4435.out.log diff --git a/mysql-test/main/mysql_client_test.test b/mysql-test/main/mysql_client_test.test index f99aecace80d3..64a5411995bb3 100644 --- a/mysql-test/main/mysql_client_test.test +++ b/mysql-test/main/mysql_client_test.test @@ -15,6 +15,8 @@ SET @old_slow_query_log= @@global.slow_query_log; call mtr.add_suppression(" Error reading file './client_test_db/test_frm_bug.frm'"); call mtr.add_suppression(" IP address .* could not be resolved"); +call mtr.add_suppression("Aborted connection .* host: '192.0.2.50'"); +call mtr.add_suppression("Aborted connection .* host: 'santa.claus.ipv4.example.com'"); # We run with different binaries for normal and --embedded-server # diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 35b2a24a2d2c9..38a4c0269ce61 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -164,6 +164,7 @@ my_bool my_net_init(NET *net, Vio *vio, void *thd, uint my_flags) net->last_errno=0; net->pkt_nr_can_be_reset= 0; net->using_proxy_protocol= 0; + net->have_proxy_protocol_connect_errors= 0; net->thread_specific_malloc= MY_TEST(my_flags & MY_THREAD_SPECIFIC); net->thd= 0; #ifdef MYSQL_SERVER @@ -219,6 +220,7 @@ void net_end(NET *net) my_free(net->buff); net->buff=0; net->using_proxy_protocol= 0; + net->have_proxy_protocol_connect_errors= 0; DBUG_VOID_RETURN; } @@ -958,11 +960,15 @@ static handle_proxy_header_result handle_proxy_header(NET *net) /* proxy header indicates LOCAL connection, no action necessary */ return RETRY; /* Change peer address in THD and ACL structures.*/ - uint host_errors; + uint host_errors= 0; net->using_proxy_protocol= 1; - return (handle_proxy_header_result)thd_set_peer_addr(thd, - &(peer_info.peer_addr), NULL, peer_info.port, - false, &host_errors); + handle_proxy_header_result res= + (handle_proxy_header_result) thd_set_peer_addr(thd, &(peer_info.peer_addr), + NULL, peer_info.port, false, &host_errors); + /* Record the real client's connect errors for the login-success reset. */ + if (host_errors) + net->have_proxy_protocol_connect_errors= 1; + return res; #endif } diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index f7712b9abc1dc..ed866ab0b3921 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -1024,6 +1024,9 @@ static int check_connection(THD *thd) uint connect_errors= 0; int auth_rc; NET *net= &thd->net; + /* Socket peer IP address, the proxy host under PROXY protocol */ + char ip[NI_MAXHOST]; + ip[0]= 0; DBUG_PRINT("info", ("New connection received on %s", vio_description(net->vio))); @@ -1035,7 +1038,6 @@ static int check_connection(THD *thd) if (!thd->main_security_ctx.host) // If TCP/IP connection { my_bool peer_rc; - char ip[NI_MAXHOST]; uint16 peer_port; peer_rc= vio_peer_addr(net->vio, ip, &peer_port, NI_MAXHOST); @@ -1153,14 +1155,16 @@ static int check_connection(THD *thd) } auth_rc= acl_authenticate(thd, 0); - if (auth_rc == 0 && connect_errors != 0) + if (auth_rc == 0) { /* - A client connection from this IP was successful, - after some previous failures. - Reset the connection error counter. + Successful login resets connect errors, for both the socket peer and, + under PROXY protocol, the real client - each by its own error count. */ - reset_host_connect_errors(thd->main_security_ctx.ip); + if (connect_errors) + reset_host_connect_errors(ip); + if (net->have_proxy_protocol_connect_errors) + reset_host_connect_errors(thd->main_security_ctx.ip); } return auth_rc; diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index dba0b4c63e703..bea479e86f1cc 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -38,6 +38,9 @@ #include "mysql_client_fw.c" #ifndef _WIN32 #include +#include +#include +#include #endif #include "my_valgrind.h" @@ -20855,6 +20858,226 @@ static void test_proxy_header_dbug_remote_connection() } +/* + Open a raw TCP connection and let the handshake fail (server reads EOF) to + add one max_connect_errors error. With a header it counts against 'client_ip'; + with NULL no header is sent, so against the socket peer (the proxy host). +*/ +static void proxy_send_handshake_error(const char *client_ip) +{ + struct addrinfo hints, *ai= NULL, *p; + char portbuf[20], header[128]; + int connected= 0; + my_socket s= INVALID_SOCKET; + + snprintf(portbuf, sizeof(portbuf), "%u", opt_port); + memset(&hints, 0, sizeof(hints)); + hints.ai_family= AF_UNSPEC; + hints.ai_socktype= SOCK_STREAM; + if (getaddrinfo(opt_host ? opt_host : "localhost", portbuf, &hints, &ai)) + return; + + for (p= ai; p; p= p->ai_next) + { + s= socket(p->ai_family, p->ai_socktype, p->ai_protocol); + if (s == INVALID_SOCKET) + continue; + if (connect(s, p->ai_addr, (int) p->ai_addrlen) == 0) + { + connected= 1; + break; + } + closesocket(s); + s= INVALID_SOCKET; + } + freeaddrinfo(ai); + if (!connected) + return; + + if (client_ip) + { + int hdr_len= snprintf(header, sizeof(header), + "PROXY TCP4 %s 127.0.0.1 12345 %u\r\n", + client_ip, opt_port); + send(s, header, hdr_len, 0); + } + /* Half-close our write side so the server's handshake read hits EOF. */ + shutdown(s, IF_WIN(SD_SEND,SHUT_WR)); + /* Drain until the server closes, ensuring the error has been accounted. */ + { + char buf[256]; + while (recv(s, buf, sizeof(buf), 0) > 0) + ; + } + closesocket(s); +} + +/* + Connect through PROXY protocol, advertising 'client_ip' as the client. + On success returns the connection (caller closes it); on failure returns NULL + and stores the client error code in *out_errno. +*/ +static MYSQL *proxy_connect_as(const char *client_ip, const char *user, + const char *passwd, unsigned int *out_errno) +{ + MYSQL *m= mysql_client_init(NULL); + char header[128]; + int proto= MYSQL_PROTOCOL_TCP; + DIE_UNLESS(m != NULL); + snprintf(header, sizeof(header), "PROXY TCP4 %s 127.0.0.1 12345 %u\r\n", + client_ip, opt_port); + mysql_optionsv(m, MARIADB_OPT_PROXY_HEADER, header, strlen(header)); + mysql_optionsv(m, MYSQL_OPT_PROTOCOL, &proto); + if (!mysql_real_connect(m, opt_host, user, passwd, NULL, opt_port, NULL, 0)) + { + if (out_errno) + *out_errno= mysql_errno(m); + mysql_close(m); + return NULL; + } + if (out_errno) + *out_errno= 0; + return m; +} + +/* + MDEV-25817: with PROXY protocol a successful login must reset the proxied + client's connect-error counter; the reset used to be gated on the proxy + host's count, so it never fired. +*/ +static void test_proxy_header_connect_errors_reset() +{ + const char *client_ip= "192.0.2.50"; + char query[256]; + unsigned int conn_errno= 0; + int rc, i; + MYSQL *m; + + myheader("test_proxy_header_connect_errors_reset"); + + rc= mysql_query(mysql, + "SET @saved_max_connect_errors= @@global.max_connect_errors"); + myquery(rc); + rc= mysql_query(mysql, "SET @@global.max_connect_errors=3"); + myquery(rc); + rc= mysql_query(mysql, "FLUSH HOSTS"); + myquery(rc); + + snprintf(query, sizeof(query), + "CREATE USER 'u'@'%s' IDENTIFIED BY 'password'", client_ip); + rc= mysql_query(mysql, query); + myquery(rc); + + /* max_connect_errors handshake errors block the host. */ + for (i= 0; i < 3; i++) + proxy_send_handshake_error(client_ip); + m= proxy_connect_as(client_ip, "u", "password", &conn_errno); + DIE_UNLESS(m == NULL && conn_errno == ER_HOST_IS_BLOCKED); + + rc= mysql_query(mysql, "FLUSH HOSTS"); + myquery(rc); + + /* Two handshake errors, still below max_connect_errors (3). */ + proxy_send_handshake_error(client_ip); + proxy_send_handshake_error(client_ip); + + /* Below the limit: must connect, and this success must reset the counter. */ + m= proxy_connect_as(client_ip, "u", "password", &conn_errno); + DIE_UNLESS(m != NULL); + mysql_close(m); + + /* Two more: with the reset count is 2 (<3, connectable); without it 4 + (>=3, blocked). */ + proxy_send_handshake_error(client_ip); + proxy_send_handshake_error(client_ip); + + m= proxy_connect_as(client_ip, "u", "password", &conn_errno); + DIE_UNLESS(m != NULL); /* ER_HOST_IS_BLOCKED with unfixed MDEV-25817 */ + mysql_close(m); + + snprintf(query, sizeof(query), "DROP USER 'u'@'%s'", client_ip); + rc= mysql_query(mysql, query); + myquery(rc); + rc= mysql_query(mysql, + "SET global max_connect_errors=@saved_max_connect_errors"); + myquery(rc); + rc= mysql_query(mysql, "FLUSH HOSTS"); + myquery(rc); +} + +/* + A successful proxied login must also reset the proxy host (socket peer), not + only the proxied client - else connections that never finish the handshake + (e.g. port checks) could block the proxy and lock out everyone behind it. + Debug injection fakes the socket peer to a non-loopback address (192.0.2.4) + and name resolution so it is accounted. +*/ +static void test_proxy_header_proxy_host_connect_errors_reset() +{ +#ifndef DBUG_OFF + const char *proxied_client= "192.0.2.5"; /* in getaddrinfo_fake_good_ipv4 */ + unsigned int conn_errno= 0; + int rc, i; + MYSQL *m; + + myheader("test_proxy_header_proxy_host_connect_errors_reset"); + + rc= mysql_query(mysql, "SET @save_dbug= @@global.debug_dbug"); + myquery(rc); + rc= mysql_query(mysql, "SET GLOBAL debug_dbug='+d,vio_peer_addr_fake_ipv4," + "getnameinfo_fake_ipv4,getaddrinfo_fake_good_ipv4'"); + myquery(rc); + rc= mysql_query(mysql, + "SET @save_max_connect_errors= @@global.max_connect_errors"); + myquery(rc); + rc= mysql_query(mysql, "SET @@global.max_connect_errors=3"); + myquery(rc); + rc= mysql_query(mysql, "FLUSH HOSTS"); + myquery(rc); + + rc= mysql_query(mysql, + "CREATE USER 'u'@'santa.claus.ipv4.example.com' IDENTIFIED BY 'password'"); + myquery(rc); + + /* Errors with no header count against the socket peer (proxy host); + max_connect_errors of them block it. */ + for (i= 0; i < 3; i++) + proxy_send_handshake_error(NULL); + m= proxy_connect_as(proxied_client, "u", "password", &conn_errno); + DIE_UNLESS(m == NULL && conn_errno == ER_HOST_IS_BLOCKED); + + rc= mysql_query(mysql, "FLUSH HOSTS"); + myquery(rc); + + /* Two proxy-host handshake errors, below max_connect_errors (3). */ + proxy_send_handshake_error(NULL); + proxy_send_handshake_error(NULL); + + /* Success: client has no errors, so this must reset the proxy host's two. */ + m= proxy_connect_as(proxied_client, "u", "password", &conn_errno); + DIE_UNLESS(m != NULL); + mysql_close(m); + + /* Two more: with the reset proxy host is at 2 (<3); without it 4 (>=3). */ + proxy_send_handshake_error(NULL); + proxy_send_handshake_error(NULL); + + m= proxy_connect_as(proxied_client, "u", "password", &conn_errno); + DIE_UNLESS(m != NULL); /* ER_HOST_IS_BLOCKED if proxy host not reset */ + mysql_close(m); + + rc= mysql_query(mysql, "DROP USER 'u'@'santa.claus.ipv4.example.com'"); + myquery(rc); + rc= mysql_query(mysql, + "SET GLOBAL max_connect_errors= @save_max_connect_errors"); + myquery(rc); + rc= mysql_query(mysql, "SET GLOBAL debug_dbug= @save_dbug"); + myquery(rc); + rc= mysql_query(mysql, "FLUSH HOSTS"); + myquery(rc); +#endif /* !DBUG_OFF */ +} + static void test_proxy_header() { myheader("test_proxy_header"); @@ -20865,6 +21088,8 @@ static void test_proxy_header() test_proxy_header_ignore(); test_proxy_header_limits(); test_proxy_header_dbug_remote_connection(); + test_proxy_header_connect_errors_reset(); + test_proxy_header_proxy_host_connect_errors_reset(); }