Commit 18435149 authored by Antony T Curtis's avatar Antony T Curtis

fix federated_server test, possible null ptr deref

parent 49b519ca
...@@ -9,5 +9,4 @@ ...@@ -9,5 +9,4 @@
# Do not use any TAB characters for whitespace. # Do not use any TAB characters for whitespace.
# #
############################################################################## ##############################################################################
federated_server : needs fixup
...@@ -175,6 +175,8 @@ CREATE TABLE db_bogus.t1 ( ...@@ -175,6 +175,8 @@ CREATE TABLE db_bogus.t1 (
) )
; ;
INSERT INTO db_bogus.t1 VALUES ('2','this is bogus'); INSERT INTO db_bogus.t1 VALUES ('2','this is bogus');
create user test_fed@localhost identified by 'foo';
grant all on db_legitimate.* to test_fed@localhost;
create server 's1' foreign data wrapper 'mysql' options create server 's1' foreign data wrapper 'mysql' options
(HOST '127.0.0.1', (HOST '127.0.0.1',
DATABASE 'db_legitimate', DATABASE 'db_legitimate',
...@@ -211,15 +213,14 @@ id name ...@@ -211,15 +213,14 @@ id name
alter server s1 options (database 'db_bogus'); alter server s1 options (database 'db_bogus');
flush tables; flush tables;
select * from federated.t1; select * from federated.t1;
id name ERROR HY000: There was a problem processing the query on the foreign data source. Data source error: : 1044 : Access denied for user 'test_fed'@'localhost' to databa
2 this is bogus
drop server if exists 's1'; drop server if exists 's1';
ERROR 42000: Access denied; you need the SUPER privilege for this operation ERROR 42000: Access denied; you need the SUPER privilege for this operation
create server 's1' foreign data wrapper 'mysql' options create server 's1' foreign data wrapper 'mysql' options
(HOST '127.0.0.1', (HOST '127.0.0.1',
DATABASE 'db_legitimate', DATABASE 'db_legitimate',
USER 'root', USER 'test_fed',
PASSWORD '', PASSWORD 'foo',
PORT SLAVE_PORT, PORT SLAVE_PORT,
SOCKET '', SOCKET '',
OWNER 'root'); OWNER 'root');
...@@ -228,8 +229,8 @@ drop server 's1'; ...@@ -228,8 +229,8 @@ drop server 's1';
create server 's1' foreign data wrapper 'mysql' options create server 's1' foreign data wrapper 'mysql' options
(HOST '127.0.0.1', (HOST '127.0.0.1',
DATABASE 'db_legitimate', DATABASE 'db_legitimate',
USER 'root', USER 'test_fed',
PASSWORD '', PASSWORD 'foo',
PORT SLAVE_PORT, PORT SLAVE_PORT,
SOCKET '', SOCKET '',
OWNER 'root'); OWNER 'root');
...@@ -237,6 +238,7 @@ flush tables; ...@@ -237,6 +238,7 @@ flush tables;
select * from federated.t1; select * from federated.t1;
id name id name
1 this is legitimate 1 this is legitimate
drop user test_fed@localhost;
drop database db_legitimate; drop database db_legitimate;
drop database db_bogus; drop database db_bogus;
drop user guest_super@localhost; drop user guest_super@localhost;
...@@ -275,6 +277,6 @@ call p1(); ...@@ -275,6 +277,6 @@ call p1();
drop procedure p1; drop procedure p1;
drop server if exists s; drop server if exists s;
DROP TABLE IF EXISTS federated.t1; DROP TABLE IF EXISTS federated.t1;
DROP DATABASE federated; DROP DATABASE IF EXISTS federated;
DROP TABLE IF EXISTS federated.t1; DROP TABLE IF EXISTS federated.t1;
DROP DATABASE federated; DROP DATABASE IF EXISTS federated;
...@@ -239,6 +239,7 @@ alter server s1 options (database 'db_bogus'); ...@@ -239,6 +239,7 @@ alter server s1 options (database 'db_bogus');
connection master; connection master;
flush tables; flush tables;
--error ER_QUERY_ON_FOREIGN_DATA_SOURCE
select * from federated.t1; select * from federated.t1;
connection conn_select; connection conn_select;
...@@ -249,8 +250,8 @@ drop server if exists 's1'; ...@@ -249,8 +250,8 @@ drop server if exists 's1';
eval create server 's1' foreign data wrapper 'mysql' options eval create server 's1' foreign data wrapper 'mysql' options
(HOST '127.0.0.1', (HOST '127.0.0.1',
DATABASE 'db_legitimate', DATABASE 'db_legitimate',
USER 'root', USER 'test_fed',
PASSWORD '', PASSWORD 'foo',
PORT $SLAVE_MYPORT, PORT $SLAVE_MYPORT,
SOCKET '', SOCKET '',
OWNER 'root'); OWNER 'root');
...@@ -261,8 +262,8 @@ drop server 's1'; ...@@ -261,8 +262,8 @@ drop server 's1';
eval create server 's1' foreign data wrapper 'mysql' options eval create server 's1' foreign data wrapper 'mysql' options
(HOST '127.0.0.1', (HOST '127.0.0.1',
DATABASE 'db_legitimate', DATABASE 'db_legitimate',
USER 'root', USER 'test_fed',
PASSWORD '', PASSWORD 'foo',
PORT $SLAVE_MYPORT, PORT $SLAVE_MYPORT,
SOCKET '', SOCKET '',
OWNER 'root'); OWNER 'root');
...@@ -273,6 +274,7 @@ select * from federated.t1; ...@@ -273,6 +274,7 @@ select * from federated.t1;
# clean up test # clean up test
connection slave; connection slave;
drop user test_fed@localhost;
drop database db_legitimate; drop database db_legitimate;
drop database db_bogus; drop database db_bogus;
......
...@@ -308,7 +308,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ...@@ -308,7 +308,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#define MYSQL_SERVER 1q #ifndef MYSQL_SERVER
#define MYSQL_SERVER 1
#endif
#include "mysql_priv.h" #include "mysql_priv.h"
#include <mysql/plugin.h> #include <mysql/plugin.h>
...@@ -1621,7 +1623,13 @@ static int free_server(federatedx_txn *txn, FEDERATEDX_SERVER *server) ...@@ -1621,7 +1623,13 @@ static int free_server(federatedx_txn *txn, FEDERATEDX_SERVER *server)
{ {
MEM_ROOT mem_root; MEM_ROOT mem_root;
txn->close(server); if (!txn)
{
federatedx_txn tmp_txn;
tmp_txn.close(server);
}
else
txn->close(server);
DBUG_ASSERT(server->io_count == 0); DBUG_ASSERT(server->io_count == 0);
...@@ -1772,6 +1780,7 @@ int ha_federatedx::open(const char *name, int mode, uint test_if_locked) ...@@ -1772,6 +1780,7 @@ int ha_federatedx::open(const char *name, int mode, uint test_if_locked)
int ha_federatedx::close(void) int ha_federatedx::close(void)
{ {
int retval, error; int retval, error;
THD *thd= current_thd;
DBUG_ENTER("ha_federatedx::close"); DBUG_ENTER("ha_federatedx::close");
/* free the result set */ /* free the result set */
...@@ -1779,8 +1788,9 @@ int ha_federatedx::close(void) ...@@ -1779,8 +1788,9 @@ int ha_federatedx::close(void)
retval= free_result(); retval= free_result();
/* Disconnect from mysql */ /* Disconnect from mysql */
txn->release(&io); if ((txn= get_txn(thd, true)))
txn->release(&io);
DBUG_ASSERT(io == NULL); DBUG_ASSERT(io == NULL);
if ((error= free_share(txn, share))) if ((error= free_share(txn, share)))
...@@ -2124,6 +2134,8 @@ int ha_federatedx::end_bulk_insert(bool abort) ...@@ -2124,6 +2134,8 @@ int ha_federatedx::end_bulk_insert(bool abort)
if (bulk_insert.str && bulk_insert.length && !abort) if (bulk_insert.str && bulk_insert.length && !abort)
{ {
if ((error= txn->acquire(share, FALSE, &io)))
DBUG_RETURN(error);
if (io->query(bulk_insert.str, bulk_insert.length)) if (io->query(bulk_insert.str, bulk_insert.length))
error= stash_remote_error(); error= stash_remote_error();
else else
...@@ -2637,7 +2649,7 @@ int ha_federatedx::read_range_first(const key_range *start_key, ...@@ -2637,7 +2649,7 @@ int ha_federatedx::read_range_first(const key_range *start_key,
&table->key_info[active_index], &table->key_info[active_index],
start_key, end_key, 0, eq_range_arg); start_key, end_key, 0, eq_range_arg);
if ((retval= txn->acquire(share, FALSE, &io))) if ((retval= txn->acquire(share, TRUE, &io)))
DBUG_RETURN(retval); DBUG_RETURN(retval);
if (stored_result) if (stored_result)
...@@ -2775,14 +2787,16 @@ int ha_federatedx::rnd_end() ...@@ -2775,14 +2787,16 @@ int ha_federatedx::rnd_end()
int ha_federatedx::free_result() int ha_federatedx::free_result()
{ {
int error; int error;
federatedx_io *tmp_io= 0, **iop;
DBUG_ASSERT(stored_result); DBUG_ASSERT(stored_result);
if ((error= txn->acquire(share, FALSE, &io))) if (!*(iop= &io) && (error= txn->acquire(share, TRUE, (iop= &tmp_io))))
{ {
DBUG_ASSERT(0); // Fail when testing DBUG_ASSERT(0); // Fail when testing
return error; return error;
} }
io->free_result(stored_result); (*iop)->free_result(stored_result);
stored_result= 0; stored_result= 0;
txn->release(&tmp_io);
return 0; return 0;
} }
...@@ -2967,7 +2981,7 @@ int ha_federatedx::info(uint flag) ...@@ -2967,7 +2981,7 @@ int ha_federatedx::info(uint flag)
{ {
char error_buffer[FEDERATEDX_QUERY_BUFFER_SIZE]; char error_buffer[FEDERATEDX_QUERY_BUFFER_SIZE];
uint error_code; uint error_code;
federatedx_io *org_io= io; federatedx_io *tmp_io= 0, **iop= 0;
DBUG_ENTER("ha_federatedx::info"); DBUG_ENTER("ha_federatedx::info");
error_code= ER_QUERY_ON_FOREIGN_DATA_SOURCE; error_code= ER_QUERY_ON_FOREIGN_DATA_SOURCE;
...@@ -2975,7 +2989,7 @@ int ha_federatedx::info(uint flag) ...@@ -2975,7 +2989,7 @@ int ha_federatedx::info(uint flag)
/* we want not to show table status if not needed to do so */ /* we want not to show table status if not needed to do so */
if (flag & (HA_STATUS_VARIABLE | HA_STATUS_CONST | HA_STATUS_AUTO)) if (flag & (HA_STATUS_VARIABLE | HA_STATUS_CONST | HA_STATUS_AUTO))
{ {
if ((error_code= txn->acquire(share, TRUE, &io))) if (!*(iop= &io) && (error_code= txn->acquire(share, TRUE, (iop= &tmp_io))))
goto fail; goto fail;
} }
...@@ -2988,28 +3002,27 @@ int ha_federatedx::info(uint flag) ...@@ -2988,28 +3002,27 @@ int ha_federatedx::info(uint flag)
if (flag & HA_STATUS_CONST) if (flag & HA_STATUS_CONST)
stats.block_size= 4096; stats.block_size= 4096;
if (io->table_metadata(&stats, share->table_name, share->table_name_length, if ((*iop)->table_metadata(&stats, share->table_name,
flag)) share->table_name_length, flag))
goto error; goto error;
} }
if (flag & HA_STATUS_AUTO) if (flag & HA_STATUS_AUTO)
stats.auto_increment_value= io->last_insert_id(); stats.auto_increment_value= (*iop)->last_insert_id();
/* /*
If ::info created it's own transaction, close it. This happens in case If ::info created it's own transaction, close it. This happens in case
of show table status; of show table status;
*/ */
if (org_io != io) txn->release(&tmp_io);
txn->release(&io);
DBUG_RETURN(0); DBUG_RETURN(0);
error: error:
if (io) if (iop && *iop)
{ {
my_sprintf(error_buffer, (error_buffer, ": %d : %s", my_sprintf(error_buffer, (error_buffer, ": %d : %s",
io->error_code(), io->error_str())); (*iop)->error_code(), (*iop)->error_str()));
my_error(error_code, MYF(0), error_buffer); my_error(error_code, MYF(0), error_buffer);
} }
else else
...@@ -3019,6 +3032,7 @@ int ha_federatedx::info(uint flag) ...@@ -3019,6 +3032,7 @@ int ha_federatedx::info(uint flag)
my_error(error_code, MYF(0), ER(error_code)); my_error(error_code, MYF(0), ER(error_code));
} }
fail: fail:
txn->release(&tmp_io);
DBUG_RETURN(error_code); DBUG_RETURN(error_code);
} }
......
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