summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Elkin <andrei.elkin@mariadb.com>2020-03-03 13:11:28 +0200
committerAndrei Elkin <andrei.elkin@mariadb.com>2020-03-03 13:12:40 +0200
commit36cebe53a3645bf1e665ffdf5b552cabcc1e8e56 (patch)
tree35103f8d1b5529a04d88f73e35d5915a98d49a25
parent94acfb2a5820d0980203c3a22f8a5fcfa8199236 (diff)
downloadmariadb-git-bb-10.5-pre_XA.tar.gz
MDEV-21856 XID_t::formatID has to be constrained to 4 byte sizebb-10.5-pre_XA
Engine (Innodb) and XA replication MDEV-742 requires the XID member be of a constant minimum across supported platform ulong size which is 4 bytes. That is implemented. Specifically -1 of uint32 is INVALID format id value to mark xids internally, and xid value that consist of it won't be accepted. Additionally two more values are reserved for future to make up the max XID::formatID = (1<<32) - 4.
-rw-r--r--mysql-test/main/xa.result7
-rw-r--r--mysql-test/main/xa.test16
-rw-r--r--sql/handler.h8
-rw-r--r--sql/sql_yacc.yy2
4 files changed, 31 insertions, 2 deletions
diff --git a/mysql-test/main/xa.result b/mysql-test/main/xa.result
index 030415a5320..bd2946247d8 100644
--- a/mysql-test/main/xa.result
+++ b/mysql-test/main/xa.result
@@ -1,4 +1,11 @@
call mtr.add_suppression("Deadlock found when trying to get lock; try restarting transaction");
+XA START 'btw_may_not_be_empty','', 4294967295;
+ERROR XAE05: XAER_INVAL: Invalid arguments (or unsupported command)
+XA START 'btw_may_not_be_empty','', 4294967293;
+ERROR XAE05: XAER_INVAL: Invalid arguments (or unsupported command)
+XA START 'btw_may_not_be_empty','', 4294967292;
+XA END 'btw_may_not_be_empty','', 4294967292;
+XA ROLLBACK 'btw_may_not_be_empty','', 4294967292;
drop table if exists t1, t2;
create table t1 (a int) engine=innodb;
xa start 'test1';
diff --git a/mysql-test/main/xa.test b/mysql-test/main/xa.test
index 41c1f5a8859..55c41452635 100644
--- a/mysql-test/main/xa.test
+++ b/mysql-test/main/xa.test
@@ -10,6 +10,22 @@
call mtr.add_suppression("Deadlock found when trying to get lock; try restarting transaction");
+# Range of valid formatID of XID's [ gtrid, bqual [ , formatID ] ]
+# is constrained to max(uint32) - 3.
+# and -1 is an invalid value.
+
+--let $max_uint32 = `SELECT (1 << 32) - 1`
+--let $max_id = `SELECT $max_uint32 - 3`
+--let $max_plus_1 = `SELECT $max_id + 1`
+
+--error ER_XAER_INVAL
+--eval XA START 'btw_may_not_be_empty','', $max_uint32
+--error ER_XAER_INVAL
+--eval XA START 'btw_may_not_be_empty','', $max_plus_1
+--eval XA START 'btw_may_not_be_empty','', $max_id
+--eval XA END 'btw_may_not_be_empty','', $max_id
+--eval XA ROLLBACK 'btw_may_not_be_empty','', $max_id
+
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
diff --git a/sql/handler.h b/sql/handler.h
index 0a561ec8b3f..92c2a61ed0e 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -829,6 +829,10 @@ typedef ulonglong my_xid; // this line is the same as in log_event.h
@see MYSQL_XID in mysql/plugin.h
*/
struct xid_t {
+ static const uint32 INVALID_format_id= UINT32_MAX;
+ // Two more values reserved for Todo: MDEV-21777
+ static const uint32 MAX_format_id= UINT32_MAX - 3;
+
long formatID;
long gtrid_length;
long bqual_length;
@@ -864,8 +868,8 @@ struct xid_t {
bqual_length= b;
memcpy(data, d, g+b);
}
- bool is_null() const { return formatID == -1; }
- void null() { formatID= -1; }
+ bool is_null() const { return formatID == INVALID_format_id; }
+ void null() { formatID= INVALID_format_id; }
my_xid quick_get_my_xid()
{
my_xid tmp;
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index f24da3ed412..4c714902175 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -17542,6 +17542,8 @@ xid:
MYSQL_YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE);
if (unlikely(!(Lex->xid=(XID *)thd->alloc(sizeof(XID)))))
MYSQL_YYABORT;
+ if ($5 > XID::MAX_format_id)
+ my_yyabort_error((ER_XAER_INVAL, MYF(0), ""));
Lex->xid->set($5, $1->ptr(), $1->length(), $3->ptr(), $3->length());
}
;