summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/my_base.h2
-rw-r--r--mysql-test/r/ndb_alter_table.result2
-rw-r--r--mysql-test/t/ndb_alter_table.test2
-rw-r--r--mysql-test/t/ndb_basic.test17
-rw-r--r--mysql-test/t/ps.test28
-rw-r--r--mysql-test/t/select.test11
-rw-r--r--sql-common/client.c7
-rw-r--r--sql/ha_ndbcluster.cc22
-rw-r--r--sql/item.cc12
-rw-r--r--sql/mysql_priv.h2
-rw-r--r--sql/sql_table.cc30
-rw-r--r--sql/table.cc6
-rw-r--r--vio/vio.c2
-rw-r--r--vio/vio_priv.h1
-rw-r--r--vio/viossl.c19
15 files changed, 110 insertions, 53 deletions
diff --git a/include/my_base.h b/include/my_base.h
index ba3edfad0c8..f05d547027f 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -248,7 +248,7 @@ enum ha_base_keytype {
#define HA_OPTION_CHECKSUM 32
#define HA_OPTION_DELAY_KEY_WRITE 64
#define HA_OPTION_NO_PACK_KEYS 128 /* Reserved for MySQL */
-#define HA_OPTION_CREATE_FROM_ENGINE 256
+#define HA_OPTION_CREATE_FROM_ENGINE 256
#define HA_OPTION_TEMP_COMPRESS_RECORD ((uint) 16384) /* set by isamchk */
#define HA_OPTION_READ_ONLY_DATA ((uint) 32768) /* Set by isamchk */
diff --git a/mysql-test/r/ndb_alter_table.result b/mysql-test/r/ndb_alter_table.result
index ae64a5f9d3f..acb67250c26 100644
--- a/mysql-test/r/ndb_alter_table.result
+++ b/mysql-test/r/ndb_alter_table.result
@@ -179,7 +179,7 @@ a b c
2 two two
alter table t1 drop index c;
select * from t1 where b = 'two';
-ERROR HY000: Table definition has changed, please retry transaction
+ERROR HY000: Can't lock file (errno: 241)
select * from t1 where b = 'two';
a b c
2 two two
diff --git a/mysql-test/t/ndb_alter_table.test b/mysql-test/t/ndb_alter_table.test
index 70c48bba112..0a0211c8c83 100644
--- a/mysql-test/t/ndb_alter_table.test
+++ b/mysql-test/t/ndb_alter_table.test
@@ -153,7 +153,7 @@ connection server1;
alter table t1 drop index c;
connection server2;
# This should fail since index information is not automatically refreshed
---error 1412
+--error 1015
select * from t1 where b = 'two';
select * from t1 where b = 'two';
connection server1;
diff --git a/mysql-test/t/ndb_basic.test b/mysql-test/t/ndb_basic.test
index 1a351018b8d..0510651a417 100644
--- a/mysql-test/t/ndb_basic.test
+++ b/mysql-test/t/ndb_basic.test
@@ -606,6 +606,14 @@ select * from t1 order by counter;
drop table t1;
+#
+# BUG#14514 Creating table with packed key fails silently
+#
+
+CREATE TABLE t1 ( b INT ) PACK_KEYS = 0 ENGINE = ndb;
+select * from t1;
+drop table t1;
+
# End of 4.1 tests
#
@@ -615,12 +623,3 @@ create table atablewithareallylongandirritatingname (a int);
insert into atablewithareallylongandirritatingname values (2);
select * from atablewithareallylongandirritatingname;
drop table atablewithareallylongandirritatingname;
-
-
-#
-# BUG#14514
-#
-
-CREATE TABLE t1 ( b INT ) PACK_KEYS = 0 ENGINE = ndb;
-select * from t1;
-drop table t1;
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index 94ee2b1ca39..774424a8d55 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -842,4 +842,32 @@ set @@tx_isolation=default;
execute stmt;
deallocate prepare stmt;
+#
+# Bug#14410 "Crash in Enum or Set type in CREATE TABLE and PS/SP"
+#
+# Part I. Make sure the typelib for ENUM is created in the statement memory
+# root.
+prepare stmt from "create temporary table t1 (letter enum('','a','b','c')
+not null)";
+execute stmt;
+drop table t1;
+execute stmt;
+drop table t1;
+execute stmt;
+drop table t1;
+# Part II. Make sure that when the default value is converted to UTF-8,
+# the new item is # created in the statement memory root.
+set names latin1;
+prepare stmt from "create table t1 (a enum('test') default 'test')
+ character set utf8";
+execute stmt;
+drop table t1;
+execute stmt;
+drop table t1;
+execute stmt;
+drop table t1;
+# Cleanup
+set names default;
+deallocate prepare stmt;
+
# End of 4.1 tests
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index 33a3ff578f8..4eaa8eca052 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -2253,6 +2253,17 @@ insert into t1 values (1,1);
insert into t2 values (1,1),(1,2);
select distinct count(f2) >0 from t1 left join t2 on f1=f3 group by f1;
drop table t1,t2;
+
+#
+# Bug #14482 Server crash when subselecting from the same table
+#
+create table t1 (f1 int,f2 int);
+insert into t1 values(1,1);
+create table t2 (f3 int, f4 int, primary key(f3,f4));
+insert into t2 values(1,1);
+select * from t1 where f1 in (select f3 from t2 where (f3,f4)= (select f3,f4 from t2));
+drop table t1,t2;
+
# End of 4.1 tests
#
diff --git a/sql-common/client.c b/sql-common/client.c
index cc90b2a105a..976d59d83a4 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -1495,12 +1495,17 @@ mysql_ssl_set(MYSQL *mysql __attribute__((unused)) ,
static void
mysql_ssl_free(MYSQL *mysql __attribute__((unused)))
{
+ struct st_VioSSLConnectorFd *st=
+ (struct st_VioSSLConnectorFd*) mysql->connector_fd;
DBUG_ENTER("mysql_ssl_free");
+
my_free(mysql->options.ssl_key, MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.ssl_cert, MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.ssl_ca, MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.ssl_capath, MYF(MY_ALLOW_ZERO_PTR));
- my_free(mysql->options.ssl_cipher, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.ssl_cipher, MYF(MY_ALLOW_ZERO_PTR));
+ if (st)
+ SSL_CTX_free(st->ssl_context);
my_free(mysql->connector_fd,MYF(MY_ALLOW_ZERO_PTR));
mysql->options.ssl_key = 0;
mysql->options.ssl_cert = 0;
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index cdd406d473c..1156ba1317f 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -3332,17 +3332,20 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
DBUG_PRINT("info", ("Table schema version: %d",
tab->getObjectVersion()));
}
- if (m_table != (void *)tab)
- {
- m_table= (void *)tab;
- m_table_version = tab->getObjectVersion();
- }
- else if (m_table_version < tab->getObjectVersion())
+ if (m_table_version < tab->getObjectVersion())
{
/*
The table has been altered, caller has to retry
*/
- DBUG_RETURN(my_errno= HA_ERR_TABLE_DEF_CHANGED);
+ NdbError err= ndb->getNdbError(NDB_INVALID_SCHEMA_OBJECT);
+ DBUG_RETURN(ndb_to_mysql_error(&err));
+ }
+ if (m_table != (void *)tab)
+ {
+ m_table= (void *)tab;
+ m_table_version = tab->getObjectVersion();
+ if (!(my_errno= build_index_list(ndb, table, ILBP_OPEN)))
+ DBUG_RETURN(my_errno);
}
m_table_info= tab_info;
}
@@ -3880,9 +3883,8 @@ int ha_ndbcluster::create(const char *name,
uint pack_length, length, i, pk_length= 0;
const void *data, *pack_data;
char name2[FN_HEADLEN];
- bool create_from_engine= test(info->table_options &
- HA_OPTION_CREATE_FROM_ENGINE);
-
+ bool create_from_engine= (info->table_options & HA_OPTION_CREATE_FROM_ENGINE);
+
DBUG_ENTER("ha_ndbcluster::create");
DBUG_PRINT("enter", ("name: %s", name));
fn_format(name2, name, "", "",2); // Remove the .frm extension
diff --git a/sql/item.cc b/sql/item.cc
index 6d5855cd0ca..a091552aa34 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -5260,7 +5260,7 @@ Item_result item_cmp_type(Item_result a,Item_result b)
void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
{
Item *item= *ref;
- Item *new_item;
+ Item *new_item= NULL;
if (item->basic_const_item())
return; // Can't be better
Item_result res_type=item_cmp_type(comp_item->result_type(),
@@ -5293,7 +5293,16 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
break;
}
case ROW_RESULT:
+ if (item->type() == Item::ROW_ITEM && comp_item->type() == Item::ROW_ITEM)
{
+ /*
+ Substitute constants only in Item_rows. Don't affect other Items
+ with ROW_RESULT (eg Item_singlerow_subselect).
+
+ For such Items more optimal is to detect if it is constant and replace
+ it with Item_row. This would optimize queries like this:
+ SELECT * FROM t1 WHERE (a,b) = (SELECT a,b FROM t2 LIMIT 1);
+ */
Item_row *item_row= (Item_row*) item;
Item_row *comp_item_row= (Item_row*) comp_item;
uint col;
@@ -5311,6 +5320,7 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
resolve_const_item(thd, item_row->addr(col), comp_item_row->el(col));
break;
}
+ /* Fallthrough */
case REAL_RESULT:
{ // It must REAL_RESULT
double result= item->val_real();
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 4f5a0032531..6a1a65b963a 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1362,7 +1362,7 @@ int calc_weekday(long daynr,bool sunday_first_day_of_week);
uint calc_week(TIME *l_time, uint week_behaviour, uint *year);
void find_date(char *pos,uint *vek,uint flag);
TYPELIB *convert_strings_to_array_type(my_string *typelibs, my_string *end);
-TYPELIB *typelib(List<String> &strings);
+TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings);
ulong get_form_pos(File file, uchar *head, TYPELIB *save_names);
ulong make_new_entry(File file,uchar *fileinfo,TYPELIB *formnames,
const char *newname);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index e8ffdc23ec5..03ed0fe4e66 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -725,7 +725,14 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
*/
if (!interval)
{
- interval= sql_field->interval= typelib(sql_field->interval_list);
+ /*
+ Create the typelib in prepared statement memory if we're
+ executing one.
+ */
+ MEM_ROOT *stmt_root= thd->current_arena->mem_root;
+
+ interval= sql_field->interval= typelib(stmt_root,
+ sql_field->interval_list);
List_iterator<String> it(sql_field->interval_list);
String conv, *tmp;
for (uint i= 0; (tmp= it++); i++)
@@ -736,7 +743,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
{
uint cnv_errs;
conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
- interval->type_names[i]= strmake_root(thd->mem_root, conv.ptr(),
+ interval->type_names[i]= strmake_root(stmt_root, conv.ptr(),
conv.length());
interval->type_lengths[i]= conv.length();
}
@@ -756,8 +763,23 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
*/
if (sql_field->def && cs != sql_field->def->collation.collation)
{
- if (!(sql_field->def=
- sql_field->def->safe_charset_converter(cs)))
+ Item_arena backup_arena;
+ bool need_to_change_arena=
+ !thd->current_arena->is_conventional_execution();
+ if (need_to_change_arena)
+ {
+ /* Asser that we don't do that at every PS execute */
+ DBUG_ASSERT(thd->current_arena->is_first_stmt_execute() ||
+ thd->current_arena->is_first_sp_execute());
+ thd->set_n_backup_item_arena(thd->current_arena, &backup_arena);
+ }
+
+ sql_field->def= sql_field->def->safe_charset_converter(cs);
+
+ if (need_to_change_arena)
+ thd->restore_backup_item_arena(thd->current_arena, &backup_arena);
+
+ if (! sql_field->def)
{
/* Could not convert */
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
diff --git a/sql/table.cc b/sql/table.cc
index 8068a839052..8b22610a95e 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1247,15 +1247,15 @@ fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint types,
} /* fix_type_pointers */
-TYPELIB *typelib(List<String> &strings)
+TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings)
{
- TYPELIB *result=(TYPELIB*) sql_alloc(sizeof(TYPELIB));
+ TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
if (!result)
return 0;
result->count=strings.elements;
result->name="";
uint nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1);
- if (!(result->type_names= (const char**) sql_alloc(nbytes)))
+ if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
return 0;
result->type_lengths= (uint*) (result->type_names + result->count + 1);
List_iterator<String> it(strings);
diff --git a/vio/vio.c b/vio/vio.c
index ff93cff959f..bc286b2d2bb 100644
--- a/vio/vio.c
+++ b/vio/vio.c
@@ -87,7 +87,7 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
#ifdef HAVE_OPENSSL
if (type == VIO_TYPE_SSL)
{
- vio->viodelete =vio_ssl_delete;
+ vio->viodelete =vio_delete;
vio->vioerrno =vio_ssl_errno;
vio->read =vio_ssl_read;
vio->write =vio_ssl_write;
diff --git a/vio/vio_priv.h b/vio/vio_priv.h
index c1c78cc6efa..eb495025ddd 100644
--- a/vio/vio_priv.h
+++ b/vio/vio_priv.h
@@ -28,7 +28,6 @@ void vio_ignore_timeout(Vio *vio, uint which, uint timeout);
#ifdef HAVE_OPENSSL
#include "my_net.h" /* needed because of struct in_addr */
-void vio_ssl_delete(Vio* vio);
int vio_ssl_read(Vio *vio,gptr buf, int size);
int vio_ssl_write(Vio *vio,const gptr buf,int size);
void vio_ssl_timeout(Vio *vio, uint which, uint timeout);
diff --git a/vio/viossl.c b/vio/viossl.c
index e6af07c4b0b..1273814c551 100644
--- a/vio/viossl.c
+++ b/vio/viossl.c
@@ -69,25 +69,6 @@ report_errors()
DBUG_VOID_RETURN;
}
-/*
- Delete a vio object
-
- SYNPOSIS
- vio_ssl_delete()
- vio Vio object. May be 0.
-*/
-
-
-void vio_ssl_delete(Vio * vio)
-{
- if (vio)
- {
- if (vio->type != VIO_CLOSED)
- vio_close(vio);
- my_free((gptr) vio,MYF(0));
- }
-}
-
int vio_ssl_errno(Vio *vio __attribute__((unused)))
{