Commit 9c89cca5 authored by Dmitry Lenev's avatar Dmitry Lenev

Fix for bug#11766714 (former bug @59888) "debug assertion when

attempt to create spatial index on char > 31 bytes".

Attempt to create spatial index on char field with length
greater than 31 byte led to assertion failure on server
compiled with safemutex support.

The problem occurred in mi_create() function which was called
to create a new version of table being altered. This function
failed since it detected an attempt to create a spatial key
on non-binary column and tried to return an error.
On its error path it tried to unlock THR_LOCK_myisam mutex
which has not been not locked at this point. Indeed such an
incorrect behavior was caught by safemutex wrapper and caused
assertion failure.

This patch fixes the problem by ensuring that mi_create()
doesn't releases THR_LOCK_myisam mutex on error path if it was
not acquired.

mysql-test/r/gis.result:
  Added test for bug @59888 "debug assertion when attempt to
  create spatial index on char > 31 bytes".
mysql-test/t/gis.test:
  Added test for bug @59888 "debug assertion when attempt to
  create spatial index on char > 31 bytes".
storage/myisam/mi_create.c:
  Changed mi_create() not to release THR_LOCK_myisam mutex on
  error path if it was not acquired.
parent 86721715
...@@ -1034,4 +1034,12 @@ p ...@@ -1034,4 +1034,12 @@ p
NULL NULL
NULL NULL
drop table t1; drop table t1;
#
# Test for bug #59888 "debug assertion when attempt to create spatial index
# on char > 31 bytes".
#
create table t1(a char(32) not null) engine=myisam;
create spatial index i on t1 (a);
ERROR HY000: Can't create table '#sql-temporary' (errno: 140)
drop table t1;
End of 5.1 tests End of 5.1 tests
...@@ -754,4 +754,16 @@ insert into t1 values (geomfromtext("point(1 0)")); ...@@ -754,4 +754,16 @@ insert into t1 values (geomfromtext("point(1 0)"));
select * from (select polygon(t1.a) as p from t1 order by t1.a) d; select * from (select polygon(t1.a) as p from t1 order by t1.a) d;
drop table t1; drop table t1;
--echo #
--echo # Test for bug #59888 "debug assertion when attempt to create spatial index
--echo # on char > 31 bytes".
--echo #
create table t1(a char(32) not null) engine=myisam;
--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
--error ER_CANT_CREATE_TABLE
create spatial index i on t1 (a);
drop table t1;
--echo End of 5.1 tests --echo End of 5.1 tests
...@@ -272,7 +272,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, ...@@ -272,7 +272,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
keyseg->type != HA_KEYTYPE_VARBINARY2) keyseg->type != HA_KEYTYPE_VARBINARY2)
{ {
my_errno=HA_WRONG_CREATE_OPTION; my_errno=HA_WRONG_CREATE_OPTION;
goto err; goto err_no_lock;
} }
} }
keydef->keysegs+=sp_segs; keydef->keysegs+=sp_segs;
...@@ -281,7 +281,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, ...@@ -281,7 +281,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
min_key_length_skip+=SPLEN*2*SPDIMS; min_key_length_skip+=SPLEN*2*SPDIMS;
#else #else
my_errno= HA_ERR_UNSUPPORTED; my_errno= HA_ERR_UNSUPPORTED;
goto err; goto err_no_lock;
#endif /*HAVE_SPATIAL*/ #endif /*HAVE_SPATIAL*/
} }
else if (keydef->flag & HA_FULLTEXT) else if (keydef->flag & HA_FULLTEXT)
...@@ -297,7 +297,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, ...@@ -297,7 +297,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
keyseg->type != HA_KEYTYPE_VARTEXT2) keyseg->type != HA_KEYTYPE_VARTEXT2)
{ {
my_errno=HA_WRONG_CREATE_OPTION; my_errno=HA_WRONG_CREATE_OPTION;
goto err; goto err_no_lock;
} }
if (!(keyseg->flag & HA_BLOB_PART) && if (!(keyseg->flag & HA_BLOB_PART) &&
(keyseg->type == HA_KEYTYPE_VARTEXT1 || (keyseg->type == HA_KEYTYPE_VARTEXT1 ||
...@@ -422,7 +422,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, ...@@ -422,7 +422,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
if (keydef->keysegs > MI_MAX_KEY_SEG) if (keydef->keysegs > MI_MAX_KEY_SEG)
{ {
my_errno=HA_WRONG_CREATE_OPTION; my_errno=HA_WRONG_CREATE_OPTION;
goto err; goto err_no_lock;
} }
/* /*
key_segs may be 0 in the case when we only want to be able to key_segs may be 0 in the case when we only want to be able to
...@@ -447,7 +447,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, ...@@ -447,7 +447,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
length >= MI_MAX_KEY_BUFF) length >= MI_MAX_KEY_BUFF)
{ {
my_errno=HA_WRONG_CREATE_OPTION; my_errno=HA_WRONG_CREATE_OPTION;
goto err; goto err_no_lock;
} }
set_if_bigger(max_key_block_length,keydef->block_length); set_if_bigger(max_key_block_length,keydef->block_length);
keydef->keylength= (uint16) key_length; keydef->keylength= (uint16) key_length;
...@@ -494,7 +494,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, ...@@ -494,7 +494,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
"indexes and/or unique constraints.", "indexes and/or unique constraints.",
MYF(0), name + dirname_length(name)); MYF(0), name + dirname_length(name));
my_errno= HA_WRONG_CREATE_OPTION; my_errno= HA_WRONG_CREATE_OPTION;
goto err; goto err_no_lock;
} }
bmove(share.state.header.file_version,(uchar*) myisam_file_magic,4); bmove(share.state.header.file_version,(uchar*) myisam_file_magic,4);
...@@ -827,12 +827,14 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, ...@@ -827,12 +827,14 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
errpos=0; errpos=0;
pthread_mutex_unlock(&THR_LOCK_myisam); pthread_mutex_unlock(&THR_LOCK_myisam);
if (my_close(file,MYF(0))) if (my_close(file,MYF(0)))
goto err; goto err_no_lock;
my_free((char*) rec_per_key_part,MYF(0)); my_free((char*) rec_per_key_part,MYF(0));
DBUG_RETURN(0); DBUG_RETURN(0);
err: err:
pthread_mutex_unlock(&THR_LOCK_myisam); pthread_mutex_unlock(&THR_LOCK_myisam);
err_no_lock:
save_errno=my_errno; save_errno=my_errno;
switch (errpos) { switch (errpos) {
case 3: case 3:
......
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