summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Widenius <monty@mariadb.org>2018-09-16 11:22:32 +0300
committerMichael Widenius <monty@mariadb.org>2018-09-16 11:23:27 +0300
commitbd7c31621ff8f490866a5a5dfb1d99de35d062a4 (patch)
tree1763b8529de813625202134063e37591aed7a0f0
parent4dc20ff687d50b2a5d889653c11674fb1d310cf8 (diff)
downloadmariadb-git-bd7c31621ff8f490866a5a5dfb1d99de35d062a4.tar.gz
MDEV-17065 Crash on SHOW CREATE TABLE with CHECK CONSTRAINT
The problem was that the original alias was replaced with a new allocated string, but constraint item's are still pointing to the original alias. Fixed by storing the original alias used when printing constraint in the tables mem_root.
-rw-r--r--mysql-test/r/constraints.result37
-rw-r--r--mysql-test/t/constraints.test25
-rw-r--r--sql/table.cc13
3 files changed, 73 insertions, 2 deletions
diff --git a/mysql-test/r/constraints.result b/mysql-test/r/constraints.result
index 57cfbfb3d37..3c061989fd3 100644
--- a/mysql-test/r/constraints.result
+++ b/mysql-test/r/constraints.result
@@ -74,3 +74,40 @@ CREATE TABLE t_illegal (col_1 INT CHECK something (whatever));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'something (whatever))' at line 1
CREATE TABLE t_illegal (col_1 INT CHECK something);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'something)' at line 1
+CREATE TABLE long_enough_name (
+pk int(11) NOT NULL,
+f1 int(11) DEFAULT NULL,
+f2 int(11) NOT NULL,
+f3 int(11) DEFAULT NULL,
+f4 timestamp NOT NULL DEFAULT current_timestamp(),
+f5 varchar(32) COLLATE utf8_bin NOT NULL DEFAULT 'foo',
+f6 smallint(6) NOT NULL DEFAULT 1,
+f7 int(11) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY idx1 (f7),
+KEY idx2 (f1),
+KEY idx3 (f2),
+KEY idx4 (f3),
+CONSTRAINT constr CHECK (f6 >= 0)
+);
+SELECT * FROM long_enough_name AS tbl;
+pk f1 f2 f3 f4 f5 f6 f7
+SHOW CREATE TABLE long_enough_name;
+Table Create Table
+long_enough_name CREATE TABLE `long_enough_name` (
+ `pk` int(11) NOT NULL,
+ `f1` int(11) DEFAULT NULL,
+ `f2` int(11) NOT NULL,
+ `f3` int(11) DEFAULT NULL,
+ `f4` timestamp NOT NULL DEFAULT current_timestamp(),
+ `f5` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT 'foo',
+ `f6` smallint(6) NOT NULL DEFAULT 1,
+ `f7` int(11) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `idx1` (`f7`),
+ KEY `idx2` (`f1`),
+ KEY `idx3` (`f2`),
+ KEY `idx4` (`f3`),
+ CONSTRAINT `constr` CHECK (`f6` >= 0)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE long_enough_name;
diff --git a/mysql-test/t/constraints.test b/mysql-test/t/constraints.test
index 1997c23bfa9..fe51e5060dc 100644
--- a/mysql-test/t/constraints.test
+++ b/mysql-test/t/constraints.test
@@ -77,3 +77,28 @@ CREATE TABLE t_illegal (col_1 INT CHECK something (whatever));
--error ER_PARSE_ERROR
CREATE TABLE t_illegal (col_1 INT CHECK something);
+#
+# MDEV-17065 Crash on SHOW CREATE TABLE with CHECK CONSTRAINT
+#
+
+CREATE TABLE long_enough_name (
+pk int(11) NOT NULL,
+f1 int(11) DEFAULT NULL,
+f2 int(11) NOT NULL,
+f3 int(11) DEFAULT NULL,
+f4 timestamp NOT NULL DEFAULT current_timestamp(),
+f5 varchar(32) COLLATE utf8_bin NOT NULL DEFAULT 'foo',
+f6 smallint(6) NOT NULL DEFAULT 1,
+f7 int(11) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY idx1 (f7),
+KEY idx2 (f1),
+KEY idx3 (f2),
+KEY idx4 (f3),
+CONSTRAINT constr CHECK (f6 >= 0)
+);
+
+SELECT * FROM long_enough_name AS tbl;
+SHOW CREATE TABLE long_enough_name;
+
+DROP TABLE long_enough_name;
diff --git a/sql/table.cc b/sql/table.cc
index 585cb13a86c..f557799e7dd 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -3007,6 +3007,8 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
{
enum open_frm_error error;
uint records, i, bitmap_size, bitmap_count;
+ size_t tmp_length;
+ const char *tmp_alias;
bool error_reported= FALSE;
uchar *record, *bitmaps;
Field **field_ptr;
@@ -3033,8 +3035,15 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
}
init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0));
- if (outparam->alias.copy(alias, strlen(alias), table_alias_charset))
+ /*
+ We have to store the original alias in mem_root as constraints and virtual
+ functions may store pointers to it
+ */
+ tmp_length= strlen(alias);
+ if (!(tmp_alias= strmake_root(&outparam->mem_root, alias, tmp_length)))
goto err;
+
+ outparam->alias.set(tmp_alias, tmp_length, table_alias_charset);
outparam->quick_keys.init();
outparam->covering_keys.init();
outparam->intersect_keys.init();
@@ -4487,7 +4496,7 @@ void TABLE::init(THD *thd, TABLE_LIST *tl)
s->table_name.str,
tl->alias);
/* Fix alias if table name changes. */
- if (strcmp(alias.c_ptr(), tl->alias))
+ if (!alias.alloced_length() || strcmp(alias.c_ptr(), tl->alias))
alias.copy(tl->alias, strlen(tl->alias), alias.charset());
tablenr= thd->current_tablenr++;