From 96f06f952d087bd47225cc2784edbb0510fad818 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 20 Sep 2017 16:52:11 +0300 Subject: [PATCH] =?UTF-8?q?MDEV-13847=20Allow=20ALTER=20TABLE=E2=80=A6ADD?= =?UTF-8?q?=20SPATIAL=20INDEX=E2=80=A6ALGORITHM=3DINPLACE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MDEV-13851 Always check table options in ALTER TABLE…ALGORITHM=INPLACE In the merge of MySQL 5.7.9 to MariaDB 10.2.2, some code was included that prevents ADD SPATIAL INDEX from being executed with ALGORITHM=INPLACE. Also, the constant ADD_SPATIAL_INDEX was introduced as an alias to ADD_INDEX. We will remove that alias now, and properly implement the same ADD SPATIAL INDEX restrictions as MySQL 5.7 does: 1. table-rebuilding operations are not allowed if SPATIAL INDEX survive it 2. ALTER TABLE…ADD SPATIAL INDEX…LOCK=NONE is not allowed ha_innobase::prepare_inplace_alter_table(): If the ALTER TABLE requires actions within InnoDB, enforce the table options (MDEV-13851). In this way, we will keep denying ADD SPATIAL INDEX for tables that use encryption (MDEV-11974), even if ALGORITHM=INPLACE is used. --- .../encryption/r/innodb-spatial-index.result | 10 +- .../encryption/t/innodb-spatial-index.test | 13 ++- .../innodb_gis/r/alter_spatial_index.result | 92 ++++++++++++++++--- .../innodb_gis/t/alter_spatial_index.test | 80 +++++++--------- .../suite/innodb_zip/r/create_options.result | 12 +-- .../suite/innodb_zip/t/create_options.test | 3 +- sql/handler.h | 4 - storage/innobase/handler/handler0alter.cc | 58 ++++-------- storage/innobase/include/ha_prototypes.h | 1 - 9 files changed, 158 insertions(+), 115 deletions(-) diff --git a/mysql-test/suite/encryption/r/innodb-spatial-index.result b/mysql-test/suite/encryption/r/innodb-spatial-index.result index 852be0b9a73..c2a41ac4c2e 100644 --- a/mysql-test/suite/encryption/r/innodb-spatial-index.result +++ b/mysql-test/suite/encryption/r/innodb-spatial-index.result @@ -9,10 +9,14 @@ ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong creat DROP TABLE t1; CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256), coordinate POINT NOT NULL) ENCRYPTED=YES ENGINE=INNODB; +ALTER TABLE t1 ADD SPATIAL INDEX b(coordinate), ALGORITHM=COPY; +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") +ALTER TABLE t1 ADD SPATIAL INDEX b(coordinate), FORCE, ALGORITHM=INPLACE; +ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ENCRYPTED' +ALTER TABLE t1 ADD SPATIAL INDEX(coordinate); +ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ENCRYPTED' CREATE SPATIAL INDEX b on t1(coordinate); -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") -ALTER TABLE t1 ADD SPATIAL INDEX b(coordinate); -ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") +ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ENCRYPTED' DROP TABLE t1; CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256), coordinate POINT NOT NULL) ENCRYPTED=DEFAULT ENGINE=INNODB; diff --git a/mysql-test/suite/encryption/t/innodb-spatial-index.test b/mysql-test/suite/encryption/t/innodb-spatial-index.test index de78461c765..6b6191c69cb 100644 --- a/mysql-test/suite/encryption/t/innodb-spatial-index.test +++ b/mysql-test/suite/encryption/t/innodb-spatial-index.test @@ -31,12 +31,17 @@ DROP TABLE t1; # CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256), coordinate POINT NOT NULL) ENCRYPTED=YES ENGINE=INNODB; +# FIXME: MDEV-13851 Encrypted table refuses some form of ALGORITHM=COPY, +# but allows rebuild by FORCE --replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ --error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ADD SPATIAL INDEX b(coordinate), ALGORITHM=COPY; +--error ER_ILLEGAL_HA_CREATE_OPTION +ALTER TABLE t1 ADD SPATIAL INDEX b(coordinate), FORCE, ALGORITHM=INPLACE; +--error ER_ILLEGAL_HA_CREATE_OPTION +ALTER TABLE t1 ADD SPATIAL INDEX(coordinate); +--error ER_ILLEGAL_HA_CREATE_OPTION CREATE SPATIAL INDEX b on t1(coordinate); ---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ ---error ER_CANT_CREATE_TABLE -ALTER TABLE t1 ADD SPATIAL INDEX b(coordinate); DROP TABLE t1; CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, @@ -69,4 +74,4 @@ INSERT INTO t2 values(1, 'secret', ST_GeomFromText('POINT(903994614 180726515)') SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION > 0; SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; -DROP TABLE t1, t2; \ No newline at end of file +DROP TABLE t1, t2; diff --git a/mysql-test/suite/innodb_gis/r/alter_spatial_index.result b/mysql-test/suite/innodb_gis/r/alter_spatial_index.result index a6279bdb196..5d6e5787d8c 100644 --- a/mysql-test/suite/innodb_gis/r/alter_spatial_index.result +++ b/mysql-test/suite/innodb_gis/r/alter_spatial_index.result @@ -47,10 +47,20 @@ VALUES(10,ST_GeomFromText('POINT(160 160)'),ST_GeomFromText('LINESTRING(140 140, ST_GeomFromText('POLYGON((5010 5010,5020 5020,5030 5030,5040 5030,5020 5010,5010 5010))'), ST_GeomFromText('POLYGON((5010 5010,5020 5020,5030 5030,5040 5030,5020 5010,5010 5010))')); ALTER TABLE tab ADD SPATIAL INDEX idx2(c2 ASC); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE tab ADD SPATIAL KEY idx3(c3 DESC); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE tab ADD SPATIAL INDEX idx4(c4 ASC) COMMENT 'testing spatial index on Polygon'; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE tab ADD SPATIAL KEY idx5(c5 ASC) COMMENT 'testing spatial index on Geometry'; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE tab ADD INDEX idx6(c4(10)) USING BTREE; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 SET @g1 = ST_GeomFromText( 'POLYGON((7 1,6 2,6 3,10 3,10 1,7 1))'); SELECT c1,ST_Astext(c2),ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1); c1 ST_Astext(c2) ST_Astext(c4) @@ -140,8 +150,14 @@ c1 ST_Astext(c2) ST_Astext(c4) 1 POINT(1000 1000) POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) DELETE FROM tab WHERE ST_Crosses(tab.c4, @g1); ALTER TABLE tab CHANGE COLUMN c2 c22 POINT NOT NULL; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE tab CHANGE COLUMN c3 c33 LINESTRING NOT NULL; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE tab CHANGE COLUMN c4 c44 POLYGON NOT NULL; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 SHOW CREATE TABLE tab; Table Create Table tab CREATE TABLE `tab` ( @@ -166,8 +182,14 @@ tab 1 idx4 1 c44 A # 32 NULL SPATIAL testing spatial index on Polygon tab 1 idx5 1 c5 A # 32 NULL SPATIAL testing spatial index on Geometry tab 1 idx6 1 c44 A # 10 NULL BTREE ALTER TABLE tab CHANGE COLUMN c22 c2 POINT NOT NULL; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE tab CHANGE COLUMN c33 c3 LINESTRING NOT NULL; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE tab CHANGE COLUMN c44 c4 POLYGON NOT NULL; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 SHOW CREATE TABLE tab; Table Create Table tab CREATE TABLE `tab` ( @@ -210,7 +232,11 @@ DELETE FROM tab WHERE MBREquals(tab.c4, @g1); SELECT c1,ST_Astext(c2),ST_Astext(c4) FROM tab WHERE MBREquals(tab.c4, @g1); c1 ST_Astext(c2) ST_Astext(c4) ALTER TABLE tab DROP PRIMARY KEY; +affected rows: 4 +info: Records: 4 Duplicates: 0 Warnings: 0 ALTER TABLE tab ADD PRIMARY KEY(c2) ; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); SELECT c1,ST_Astext(c2),ST_Astext(c4) FROM tab WHERE ST_Touches(tab.c4, @g1); c1 ST_Astext(c2) ST_Astext(c4) @@ -254,7 +280,11 @@ SELECT c1,ST_Astext(c2),ST_Astext(c4) FROM tab WHERE MBROverlaps(tab.c4, @g1) OR c1 ST_Astext(c2) ST_Astext(c4) INSERT INTO tab SELECT * FROM tab1; ALTER TABLE tab DROP PRIMARY KEY; +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 ALTER TABLE tab DROP INDEX idx2; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR CREATE TEMPORARY TABLE temp_tab AS SELECT * FROM tab where c1 = c2; INSERT INTO temp_tab SELECT * FROM tab; @@ -306,8 +336,14 @@ tab 1 idx5 1 c5 A # 32 NULL SPATIAL testing spatial index on Geometry tab 1 idx6 1 c4 A # 10 NULL BTREE DELETE FROM tab; ALTER TABLE tab ADD PRIMARY KEY(c2); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 CREATE SPATIAL INDEX idx2 ON tab(c2 ASC); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE tab ADD CONSTRAINT const_1 UNIQUE(c2); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 SHOW CREATE TABLE tab; Table Create Table tab CREATE TABLE `tab` ( @@ -339,9 +375,17 @@ ST_GeomFromText('POLYGON((30 30,40 40,50 50,30 50,30 40,30 30))'), ST_GeomFromText('POLYGON((30 30,40 40,50 50,30 50,30 40,30 30))')); DELETE FROM tab; ALTER TABLE tab DROP PRIMARY KEY ; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE tab DROP KEY const_1; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE tab ADD PRIMARY KEY(c5(10)); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE tab ADD CONSTRAINT const_1 UNIQUE(c5(10)); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 SHOW CREATE TABLE tab; Table Create Table tab CREATE TABLE `tab` ( @@ -419,13 +463,25 @@ ANALYZE TABLE tab; Table Op Msg_type Msg_text test.tab analyze status OK ALTER TABLE tab ADD SPATIAL INDEX idx2(c2 ASC); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE tab ADD SPATIAL KEY idx3(c3 DESC); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE tab ADD SPATIAL INDEX idx4(c4 ASC) COMMENT 'testing spatial index on Polygon'; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE tab ADD SPATIAL KEY idx5(c5 ASC) COMMENT 'testing spatial index on Geometry'; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE tab ADD INDEX idx6(c4(10)) USING BTREE; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE tab MODIFY COLUMN c2 GEOMETRY NOT NULL; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE tab add COLUMN c8 POINT NOT NULL, ALGORITHM = INPLACE, LOCK=NONE; -ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Do not support online operation on table with GIS index. Try ALGORITHM=COPY +ERROR 0A000: LOCK=NONE is not supported. Reason: Do not support online operation on table with GIS index. Try LOCK=SHARED SHOW CREATE TABLE tab; Table Create Table tab CREATE TABLE `tab` ( @@ -459,6 +515,8 @@ DELETE FROM tab WHERE MBRContains(tab.c4, @g1); SELECT c1,ST_Astext(c2),ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c2) ST_Astext(c4) ALTER TABLE tab MODIFY COLUMN c4 GEOMETRY NOT NULL; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 SHOW CREATE TABLE tab; Table Create Table tab CREATE TABLE `tab` ( @@ -507,8 +565,14 @@ test.tab analyze status OK SET @g1 = ST_GeomFromText('POLYGON((4010 4010,4020 4020,4030 4030,4040 4030,4020 4010,4010 4010))'); SET @g2 = ST_GeomFromText('LINESTRING(1 1,2 2,3 3)'); ALTER TABLE tab MODIFY COLUMN c2 POINT NOT NULL; +affected rows: 8 +info: Records: 8 Duplicates: 0 Warnings: 0 ALTER TABLE tab MODIFY COLUMN c3 LINESTRING NOT NULL; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE tab MODIFY COLUMN c4 POLYGON NOT NULL; +affected rows: 8 +info: Records: 8 Duplicates: 0 Warnings: 0 SHOW CREATE TABLE tab; Table Create Table tab CREATE TABLE `tab` ( @@ -585,7 +649,11 @@ DROP TABLE tab; CREATE TABLE parent (id POINT, PRIMARY KEY(id)) ENGINE=InnoDB; CREATE TABLE child (id GEOMETRY NOT NULL, parent_id POINT NOT NULL) ENGINE=InnoDB; ALTER TABLE parent ADD SPATIAL INDEX idx1(id ASC); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE child ADD SPATIAL INDEX idx2(parent_id ASC); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 SHOW CREATE TABLE parent; Table Create Table parent CREATE TABLE `parent` ( @@ -613,7 +681,11 @@ DROP table child,parent; CREATE TABLE parent (id GEOMETRY, PRIMARY KEY(id(10))) ENGINE=InnoDB; CREATE TABLE child (id GEOMETRY NOT NULL, parent_id GEOMETRY NOT NULL) ENGINE=InnoDB; ALTER TABLE parent ADD SPATIAL INDEX idx1(id ASC) ; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE child ADD SPATIAL INDEX idx2(parent_id ASC); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 SHOW CREATE TABLE parent; Table Create Table parent CREATE TABLE `parent` ( @@ -641,11 +713,12 @@ create table t1 (c1 int) engine=innodb; insert into t1 values(NULL); alter table t1 add b geometry, add spatial index(b), algorithm=inplace; ERROR 42000: All parts of a SPATIAL index must be NOT NULL -alter table t1 add b geometry, algorithm=inplace; -update t1 set b = st_geomfromtext('point(0 0)'); -alter table t1 add spatial index(b), algorithm=inplace; -ERROR 42000: All parts of a SPATIAL index must be NOT NULL -delete from t1; +alter table t1 add b geometry not null, add spatial index(b), algorithm=inplace; +ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field +alter table t1 add b geometry not null default st_geomfromtext('POINT(0 0)'), +add spatial index(b), algorithm=inplace; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 DROP table t1; create table t1 (c1 int) engine=innodb; insert into t1 values(NULL); @@ -653,11 +726,8 @@ alter table t1 add b geometry, add spatial index(b), algorithm=copy; ERROR 42000: All parts of a SPATIAL index must be NOT NULL alter table t1 add b geometry not null, add spatial index(b), algorithm=copy; ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field -update t1 set b = st_geomfromtext('point(0 0)'); -ERROR 42S22: Unknown column 'b' in 'field list' -alter table t1 add spatial index(b), algorithm=copy; -ERROR 42000: Key column 'b' doesn't exist in table -delete from t1; +alter table t1 add b geometry not null default st_geomfromtext('POINT(0 0)'), +add spatial index(b), algorithm=copy; DROP table t1; # # BUG#20111575 ALTER TABLE...ADD SPATIAL INDEX...LOCK NONE IS REFUSED diff --git a/mysql-test/suite/innodb_gis/t/alter_spatial_index.test b/mysql-test/suite/innodb_gis/t/alter_spatial_index.test index 80ecf95bef9..f02c2f9cd1a 100644 --- a/mysql-test/suite/innodb_gis/t/alter_spatial_index.test +++ b/mysql-test/suite/innodb_gis/t/alter_spatial_index.test @@ -86,6 +86,7 @@ ST_GeomFromText('POLYGON((5010 5010,5020 5020,5030 5030,5040 5030,5020 5010,5010 ST_GeomFromText('POLYGON((5010 5010,5020 5020,5030 5030,5040 5030,5020 5010,5010 5010))')); +--enable_info ALTER TABLE tab ADD SPATIAL INDEX idx2(c2 ASC); ALTER TABLE tab ADD SPATIAL KEY idx3(c3 DESC); @@ -95,7 +96,7 @@ ALTER TABLE tab ADD SPATIAL INDEX idx4(c4 ASC) COMMENT 'testing spatial index on ALTER TABLE tab ADD SPATIAL KEY idx5(c5 ASC) COMMENT 'testing spatial index on Geometry'; ALTER TABLE tab ADD INDEX idx6(c4(10)) USING BTREE; - +--disable_info # Test the MBRContains SET @g1 = ST_GeomFromText( 'POLYGON((7 1,6 2,6 3,10 3,10 1,7 1))'); @@ -195,22 +196,26 @@ SELECT c1,ST_Astext(c2),ST_Astext(c4) FROM tab WHERE ST_Crosses(tab.c4, @g1); DELETE FROM tab WHERE ST_Crosses(tab.c4, @g1); +--enable_info ALTER TABLE tab CHANGE COLUMN c2 c22 POINT NOT NULL; ALTER TABLE tab CHANGE COLUMN c3 c33 LINESTRING NOT NULL; ALTER TABLE tab CHANGE COLUMN c4 c44 POLYGON NOT NULL; +--disable_info SHOW CREATE TABLE tab; --replace_column 7 # SHOW INDEX FROM tab; +--enable_info ALTER TABLE tab CHANGE COLUMN c22 c2 POINT NOT NULL; ALTER TABLE tab CHANGE COLUMN c33 c3 LINESTRING NOT NULL; ALTER TABLE tab CHANGE COLUMN c44 c4 POLYGON NOT NULL; +--disable_info SHOW CREATE TABLE tab; @@ -234,9 +239,11 @@ DELETE FROM tab WHERE MBREquals(tab.c4, @g1); SELECT c1,ST_Astext(c2),ST_Astext(c4) FROM tab WHERE MBREquals(tab.c4, @g1); +--enable_info ALTER TABLE tab DROP PRIMARY KEY; ALTER TABLE tab ADD PRIMARY KEY(c2) ; +--disable_info SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); @@ -298,9 +305,11 @@ SELECT c1,ST_Astext(c2),ST_Astext(c4) FROM tab WHERE MBROverlaps(tab.c4, @g1) OR INSERT INTO tab SELECT * FROM tab1; +--enable_info ALTER TABLE tab DROP PRIMARY KEY; ALTER TABLE tab DROP INDEX idx2; +--disable_info # Check spatial index on temp tables SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR @@ -342,11 +351,13 @@ SHOW INDEX FROM tab; DELETE FROM tab; +--enable_info ALTER TABLE tab ADD PRIMARY KEY(c2); CREATE SPATIAL INDEX idx2 ON tab(c2 ASC); ALTER TABLE tab ADD CONSTRAINT const_1 UNIQUE(c2); +--disable_info SHOW CREATE TABLE tab; @@ -362,6 +373,7 @@ ST_GeomFromText('POLYGON((30 30,40 40,50 50,30 50,30 40,30 30))')); DELETE FROM tab; +--enable_info ALTER TABLE tab DROP PRIMARY KEY ; ALTER TABLE tab DROP KEY const_1; @@ -369,6 +381,7 @@ ALTER TABLE tab DROP KEY const_1; ALTER TABLE tab ADD PRIMARY KEY(c5(10)); ALTER TABLE tab ADD CONSTRAINT const_1 UNIQUE(c5(10)); +--disable_info SHOW CREATE TABLE tab; @@ -445,6 +458,7 @@ ST_GeomFromText('POLYGON((5010 5010,5020 5020,5030 5030,5040 5030,5020 5010,5010 ANALYZE TABLE tab; +--enable_info ALTER TABLE tab ADD SPATIAL INDEX idx2(c2 ASC); ALTER TABLE tab ADD SPATIAL KEY idx3(c3 DESC); @@ -466,6 +480,7 @@ ALTER TABLE tab MODIFY COLUMN c2 GEOMETRY NOT NULL; --error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON ALTER TABLE tab add COLUMN c8 POINT NOT NULL, ALGORITHM = INPLACE, LOCK=NONE; +--disable_info SHOW CREATE TABLE tab; @@ -483,10 +498,12 @@ DELETE FROM tab WHERE MBRContains(tab.c4, @g1); SELECT c1,ST_Astext(c2),ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; +--enable_info # --error ER_CANT_CREATE_GEOMETRY_OBJECT # ALTER TABLE tab MODIFY COLUMN c2 POLYGON NOT NULL; ALTER TABLE tab MODIFY COLUMN c4 GEOMETRY NOT NULL; +--disable_info SHOW CREATE TABLE tab; @@ -520,11 +537,13 @@ SET @g1 = ST_GeomFromText('POLYGON((4010 4010,4020 4020,4030 4030,4040 4030,4020 SET @g2 = ST_GeomFromText('LINESTRING(1 1,2 2,3 3)'); # When Point type data exist in the column allow DDL operation +--enable_info ALTER TABLE tab MODIFY COLUMN c2 POINT NOT NULL; ALTER TABLE tab MODIFY COLUMN c3 LINESTRING NOT NULL; ALTER TABLE tab MODIFY COLUMN c4 POLYGON NOT NULL; +--disable_info SHOW CREATE TABLE tab; @@ -571,6 +590,7 @@ DELETE FROM tab WHERE ST_Touches(tab.c4, @g1) OR ST_Touches(tab.c3,@g2); SELECT c1,ST_Astext(c2),ST_AsText(c3),ST_Astext(c4) FROM tab WHERE ST_Touches(tab.c4, @g1) OR ST_Touches(tab.c3,@g2); +--enable_info # --error ER_SPATIAL_MUST_HAVE_GEOM_COL --error ER_WRONG_ARGUMENTS ALTER TABLE tab MODIFY COLUMN c4 INT NOT NULL; @@ -578,6 +598,7 @@ ALTER TABLE tab MODIFY COLUMN c4 INT NOT NULL; # --error ER_SPATIAL_MUST_HAVE_GEOM_COL --error ER_WRONG_ARGUMENTS ALTER TABLE tab MODIFY COLUMN c4 BLOB NOT NULL; +--disable_info # Test InnoDB to Myisam to InnoDB ALTER TABLE tab ENGINE Myisam; @@ -615,9 +636,11 @@ CREATE TABLE parent (id POINT, PRIMARY KEY(id)) ENGINE=InnoDB; CREATE TABLE child (id GEOMETRY NOT NULL, parent_id POINT NOT NULL) ENGINE=InnoDB; +--enable_info ALTER TABLE parent ADD SPATIAL INDEX idx1(id ASC); ALTER TABLE child ADD SPATIAL INDEX idx2(parent_id ASC); +--disable_info SHOW CREATE TABLE parent; @@ -646,9 +669,11 @@ CREATE TABLE parent (id GEOMETRY, PRIMARY KEY(id(10))) ENGINE=InnoDB; CREATE TABLE child (id GEOMETRY NOT NULL, parent_id GEOMETRY NOT NULL) ENGINE=InnoDB; +--enable_info ALTER TABLE parent ADD SPATIAL INDEX idx1(id ASC) ; ALTER TABLE child ADD SPATIAL INDEX idx2(parent_id ASC); +--disable_info SHOW CREATE TABLE parent; @@ -678,29 +703,13 @@ alter table t1 add b geometry, add spatial index(b), algorithm=inplace; # Add spatial index fail, since there's invalid geo data. # The case has to be commented because it no longer fails and following cases # don't expect the effect of such a statement. -#--error ER_CANT_CREATE_GEOMETRY_OBJECT -# alter table t1 add b geometry not null, add spatial index(b), algorithm=inplace; +--error ER_CANT_CREATE_GEOMETRY_OBJECT + alter table t1 add b geometry not null, add spatial index(b), algorithm=inplace; -# Add a geometry column. -alter table t1 add b geometry, algorithm=inplace; - -# Add spatial index fail, since there's a NULL or invalid geo data. -# The case has to be commented because it no longer fails and following cases -# don't expect the effect of such a statement. -#--error ER_CANT_CREATE_GEOMETRY_OBJECT -#alter table t1 add spatial index(b), algorithm=inplace; - -# Update invalide geo data to point(0 0). -update t1 set b = st_geomfromtext('point(0 0)'); - -# Add spatial index success. ---error ER_SPATIAL_CANT_HAVE_NULL -alter table t1 add spatial index(b), algorithm=inplace; - -# Delete rows. -delete from t1; - -#cleanup +--enable_info +alter table t1 add b geometry not null default st_geomfromtext('POINT(0 0)'), +add spatial index(b), algorithm=inplace; +--disable_info DROP table t1; # Check add spatial index when table already has rows (copy). @@ -712,32 +721,11 @@ insert into t1 values(NULL); alter table t1 add b geometry, add spatial index(b), algorithm=copy; # Add spatial index fail, since there's a NULL or invalid geo data. -# --error ER_INVALID_USE_OF_NULL --error ER_CANT_CREATE_GEOMETRY_OBJECT alter table t1 add b geometry not null, add spatial index(b), algorithm=copy; -# Add a geometry column. -# --error ER_INVALID_USE_OF_NULL -# alter table t1 add b geometry not null, algorithm=copy; - -# Add spatial index. -# The case has to be commented because it no longer fails and following cases -# don't expect the effect of such a statement. -#--error ER_CANT_CREATE_GEOMETRY_OBJECT -#alter table t1 add spatial index(b), algorithm=copy; - -# Update invalide geo data to point(0 0). ---error ER_BAD_FIELD_ERROR -update t1 set b = st_geomfromtext('point(0 0)'); - -# Add spatial index success. ---error ER_KEY_COLUMN_DOES_NOT_EXITS -alter table t1 add spatial index(b), algorithm=copy; - -# Delete rows. -delete from t1; - -#cleanup +alter table t1 add b geometry not null default st_geomfromtext('POINT(0 0)'), +add spatial index(b), algorithm=copy; DROP table t1; --echo # diff --git a/mysql-test/suite/innodb_zip/r/create_options.result b/mysql-test/suite/innodb_zip/r/create_options.result index 1c152229b3c..4e38bec08e3 100644 --- a/mysql-test/suite/innodb_zip/r/create_options.result +++ b/mysql-test/suite/innodb_zip/r/create_options.result @@ -325,19 +325,17 @@ SET GLOBAL innodb_file_format=Antelope; Warnings: Warning 131 Using innodb_file_format is deprecated and the parameter may be removed in future releases. See http://dev.mysql.com/doc/refman/5.7/en/innodb-file-format.html ALTER TABLE t1 ADD COLUMN f1 INT; -Warnings: +ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ROW_FORMAT' +SHOW WARNINGS; +Level Code Message Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=4. Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. -Warning 1478 InnoDB: assuming ROW_FORMAT=DYNAMIC. +Error 1478 Table storage engine 'InnoDB' does not support the create option 'ROW_FORMAT' SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `i` int(11) DEFAULT NULL, - `f1` int(11) DEFAULT NULL + `i` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4 -SHOW WARNINGS; -Level Code Message ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; SHOW WARNINGS; Level Code Message diff --git a/mysql-test/suite/innodb_zip/t/create_options.test b/mysql-test/suite/innodb_zip/t/create_options.test index e7303dee8f3..58fd764932c 100644 --- a/mysql-test/suite/innodb_zip/t/create_options.test +++ b/mysql-test/suite/innodb_zip/t/create_options.test @@ -249,9 +249,10 @@ SET GLOBAL innodb_file_format=Barracuda; DROP TABLE t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; SET GLOBAL innodb_file_format=Antelope; +--error ER_ILLEGAL_HA_CREATE_OPTION ALTER TABLE t1 ADD COLUMN f1 INT; -SHOW CREATE TABLE t1; SHOW WARNINGS; +SHOW CREATE TABLE t1; ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; SHOW WARNINGS; ALTER TABLE t1 ADD COLUMN f2 INT; diff --git a/sql/handler.h b/sql/handler.h index d021edf28d2..e64d407f202 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1852,10 +1852,6 @@ public: // Add non-unique, non-primary index static const HA_ALTER_FLAGS ADD_INDEX = 1ULL << 0; - // - // Adds a spatial index. At the moment all engines treat it - // identically to the ADD_INDEX, so it gets the same code - static const HA_ALTER_FLAGS ADD_SPATIAL_INDEX = ADD_INDEX; // Drop non-unique, non-primary index static const HA_ALTER_FLAGS DROP_INDEX = 1ULL << 1; diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 352b223ab69..ee8e06ea19f 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -71,8 +71,7 @@ static const char *MSG_UNSUPPORTED_ALTER_ONLINE_ON_VIRTUAL_COLUMN= /** Operations for creating secondary indexes (no rebuild needed) */ static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ONLINE_CREATE = Alter_inplace_info::ADD_INDEX - | Alter_inplace_info::ADD_UNIQUE_INDEX - | Alter_inplace_info::ADD_SPATIAL_INDEX; + | Alter_inplace_info::ADD_UNIQUE_INDEX; /** Operations for rebuilding a table in place */ static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ALTER_REBUILD @@ -702,11 +701,11 @@ ha_innobase::check_if_supported_inplace_alter( codes for certain types. In some cases the signed/unsigned bit was generated differently too. - Online ALTER would change the mtype/unsigned_flag (to what the + Inplace ALTER would change the mtype/unsigned_flag (to what the current code generates) without changing the underlying data represenation, and it might result in data corruption. - Don't do online ALTER if mtype/unsigned_flag are wrong. + Don't do inplace ALTER if mtype/unsigned_flag are wrong. */ for (ulint i = 0, icol= 0; i < table->s->fields; i++) { const Field* field = table->field[i]; @@ -897,29 +896,6 @@ ha_innobase::check_if_supported_inplace_alter( DBUG_ASSERT(!m_prebuilt->table->fts || m_prebuilt->table->fts->doc_col < dict_table_get_n_user_cols(m_prebuilt->table)); - /* Spatial indexes should use copy method for now. - TOO: remove this when below ADD_SPATIAL_INDEX supported. */ - for (uint i = 0; i < ha_alter_info->index_add_count; i++) { - const KEY* key = - &ha_alter_info->key_info_buffer[ - ha_alter_info->index_add_buffer[i]]; - if (key->flags & HA_SPATIAL) { - ha_alter_info->unsupported_reason = innobase_get_err_msg( - ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_GIS); - - DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); - } - } - -#ifdef MYSQL_SPATIAL_INDEX - if (ha_alter_info->handler_flags - & Alter_inplace_info::ADD_SPATIAL_INDEX) { - ha_alter_info->unsupported_reason = innobase_get_err_msg( - ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_GIS); - online = false; - } -#endif - if (m_prebuilt->table->fts && innobase_fulltext_exist(altered_table)) { /* FULLTEXT indexes are supposed to remain. */ @@ -964,7 +940,7 @@ ha_innobase::check_if_supported_inplace_alter( operation is possible. */ } else if (((ha_alter_info->handler_flags & Alter_inplace_info::ADD_PK_INDEX) - || innobase_need_rebuild(ha_alter_info, table)) + || innobase_need_rebuild(ha_alter_info, table)) && (innobase_fulltext_exist(altered_table) || innobase_spatial_exist(altered_table))) { /* Refuse to rebuild the table online, if @@ -982,8 +958,6 @@ ha_innobase::check_if_supported_inplace_alter( ha_alter_info->unsupported_reason = innobase_get_err_msg( ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_GIS); - - DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); } else { ha_alter_info->unsupported_reason = innobase_get_err_msg( @@ -991,10 +965,15 @@ ha_innobase::check_if_supported_inplace_alter( } } else if ((ha_alter_info->handler_flags & Alter_inplace_info::ADD_INDEX)) { - /* Building a full-text index requires a lock. - We could do without a lock if the table already contains - an FTS_DOC_ID column, but in that case we would have - to apply the modification log to the full-text indexes. */ + /* ADD FULLTEXT|SPATIAL INDEX requires a lock. + + We could do ADD FULLTEXT INDEX without a lock if the + table already contains an FTS_DOC_ID column, but in + that case we would have to apply the modification log + to the full-text indexes. + + We could also do ADD SPATIAL INDEX by implementing + row_log_apply() for it. */ for (uint i = 0; i < ha_alter_info->index_add_count; i++) { const KEY* key = @@ -1011,6 +990,12 @@ ha_innobase::check_if_supported_inplace_alter( online = false; break; } + if (key->flags & HA_SPATIAL) { + ha_alter_info->unsupported_reason = innobase_get_err_msg( + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_GIS); + online = false; + break; + } } } @@ -5621,10 +5606,7 @@ ha_innobase::prepare_inplace_alter_table( /* The clustered index is corrupted. */ my_error(ER_CHECK_NO_SUCH_TABLE, MYF(0)); DBUG_RETURN(true); - } - - if (ha_alter_info->handler_flags - & Alter_inplace_info::CHANGE_CREATE_OPTION) { + } else { const char* invalid_opt = info.create_options_are_invalid(); /* Check engine specific table options */ diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h index 7b3726b1fef..459304fc712 100644 --- a/storage/innobase/include/ha_prototypes.h +++ b/storage/innobase/include/ha_prototypes.h @@ -43,7 +43,6 @@ class THD; #undef MYSQL_PFS #undef MYSQL_RENAME_INDEX #undef MYSQL_REPLACE_TRX_IN_THD -#undef MYSQL_SPATIAL_INDEX #undef MYSQL_STORE_FTS_DOC_ID /*******************************************************************//**