Commit 0a1dc8af authored by unknown's avatar unknown

Merge of recent MyISAM changes into Maria. Testsuite passes as much

as in the main 5.1 (partition and ndb_alter_table fail).


mysql-test/r/maria.result:
  merge from MyISAM
mysql-test/r/ps_maria.result:
  merge from MyISAM
mysql-test/t/maria.test:
  merge from MyISAM
sql/mysql_priv.h:
  fix after wrong merge
sql/mysqld.cc:
  fix after wrong merge
sql/set_var.cc:
  adding _db like other engines have
storage/maria/Makefile.am:
  merge from MyISAM
storage/maria/ha_maria.cc:
  merge from MyISAM
storage/maria/ha_maria.h:
  merge from MyISAM
storage/maria/ma_check.c:
  merge from MyISAM
storage/maria/ma_delete.c:
  merge from MyISAM
storage/maria/ma_init.c:
  maria_inited should rather be my_bool
storage/maria/ma_locking.c:
  merge from MyISAM
storage/maria/ma_packrec.c:
  merge from MyISAM
storage/maria/ma_panic.c:
  maria_panic() should not take mutex if engine has not been inited.
storage/maria/ma_rkey.c:
  merge from MyISAM
storage/maria/ma_write.c:
  merge from MyISAM
storage/maria/maria_def.h:
  merge from MyISAM. maria_inited is needed for maria_panic().
storage/maria/maria_ftdump.c:
  merge from MyISAM
parent abdc4682
......@@ -517,6 +517,34 @@ select c1 from t1 order by c1 limit 1;
c1
a
drop table t1;
create table t1 (a int not null, primary key(a));
create table t2 (a int not null, b int not null, primary key(a,b));
insert into t1 values (1),(2),(3),(4),(5),(6);
insert into t2 values (1,1),(2,1);
lock tables t1 read local, t2 read local;
select straight_join * from t1,t2 force index (primary) where t1.a=t2.a;
a a b
1 1 1
2 2 1
insert into t2 values(2,0);
select straight_join * from t1,t2 force index (primary) where t1.a=t2.a;
a a b
1 1 1
2 2 1
drop table t1,t2;
CREATE TABLE t1 (c1 varchar(250) NOT NULL);
CREATE TABLE t2 (c1 varchar(250) NOT NULL, PRIMARY KEY (c1));
INSERT INTO t1 VALUES ('test000001'), ('test000002'), ('test000003');
INSERT INTO t2 VALUES ('test000002'), ('test000003'), ('test000004');
LOCK TABLES t1 READ LOCAL, t2 READ LOCAL;
SELECT t1.c1 AS t1c1, t2.c1 AS t2c1 FROM t1, t2
WHERE t1.c1 = t2.c1 HAVING t1c1 != t2c1;
t1c1 t2c1
INSERT INTO t2 VALUES ('test000001'), ('test000005');
SELECT t1.c1 AS t1c1, t2.c1 AS t2c1 FROM t1, t2
WHERE t1.c1 = t2.c1 HAVING t1c1 != t2c1;
t1c1 t2c1
DROP TABLE t1,t2;
CREATE TABLE t1 (`a` int(11) NOT NULL default '0', `b` int(11) NOT NULL default '0', UNIQUE KEY `a` USING RTREE (`a`,`b`));
Got one of the listed errors
create table t1 (a int, b varchar(200), c text not null) checksum=1;
......
This diff is collapsed.
......@@ -493,6 +493,42 @@ insert into t1 values ('a'), ('b');
select c1 from t1 order by c1 limit 1;
drop table t1;
#
# Bug #14400 Join could miss concurrently inserted row
#
# Partial key.
create table t1 (a int not null, primary key(a));
create table t2 (a int not null, b int not null, primary key(a,b));
insert into t1 values (1),(2),(3),(4),(5),(6);
insert into t2 values (1,1),(2,1);
lock tables t1 read local, t2 read local;
select straight_join * from t1,t2 force index (primary) where t1.a=t2.a;
connect (root,localhost,root,,test,$MASTER_MYPORT,master.sock);
insert into t2 values(2,0);
disconnect root;
connection default;
select straight_join * from t1,t2 force index (primary) where t1.a=t2.a;
drop table t1,t2;
#
# Full key.
CREATE TABLE t1 (c1 varchar(250) NOT NULL);
CREATE TABLE t2 (c1 varchar(250) NOT NULL, PRIMARY KEY (c1));
INSERT INTO t1 VALUES ('test000001'), ('test000002'), ('test000003');
INSERT INTO t2 VALUES ('test000002'), ('test000003'), ('test000004');
LOCK TABLES t1 READ LOCAL, t2 READ LOCAL;
SELECT t1.c1 AS t1c1, t2.c1 AS t2c1 FROM t1, t2
WHERE t1.c1 = t2.c1 HAVING t1c1 != t2c1;
connect (con1,localhost,root,,);
connection con1;
INSERT INTO t2 VALUES ('test000001'), ('test000005');
disconnect con1;
connection default;
SELECT t1.c1 AS t1c1, t2.c1 AS t2c1 FROM t1, t2
WHERE t1.c1 = t2.c1 HAVING t1c1 != t2c1;
DROP TABLE t1,t2;
# End of 4.0 tests
#
# Test RTREE index
#
......
......@@ -1651,6 +1651,9 @@ extern SHOW_COMP_OPTION have_ndbcluster;
extern SHOW_COMP_OPTION have_partition_db;
extern SHOW_COMP_OPTION have_merge_db;
extern SHOW_COMP_OPTION have_maria_db;
extern handlerton *partition_hton;
extern handlerton *myisam_hton;
extern handlerton *heap_hton;
extern SHOW_COMP_OPTION have_row_based_replication;
extern SHOW_COMP_OPTION have_openssl, have_symlink, have_dlopen;
......
......@@ -7095,6 +7095,11 @@ static void mysql_init_variables(void)
#else
have_csv_db= SHOW_OPTION_NO;
#endif
#ifdef WITH_MARIA_STORAGE_ENGINE
have_maria_db= SHOW_OPTION_YES;
#else
have_maria_db= SHOW_OPTION_NO;
#endif
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
have_ndbcluster= SHOW_OPTION_DISABLED;
#else
......
......@@ -686,7 +686,7 @@ sys_var_have_variable sys_have_federated_db("have_federated_engine",
&have_federated_db);
sys_var_have_variable sys_have_geometry("have_geometry", &have_geometry);
sys_var_have_variable sys_have_innodb("have_innodb", &have_innodb);
sys_var_have_variable sys_have_maria("have_maria", &have_maria);
sys_var_have_variable sys_have_maria_db("have_maria", &have_maria_db);
sys_var_have_variable sys_have_merge_db("have_merge", &have_merge_db);
sys_var_have_variable sys_have_ndbcluster("have_ndbcluster", &have_ndbcluster);
sys_var_have_variable sys_have_openssl("have_openssl", &have_openssl);
......@@ -818,7 +818,7 @@ SHOW_VAR init_vars[]= {
{sys_have_federated_db.name,(char*) &have_federated_db, SHOW_HAVE},
{sys_have_geometry.name, (char*) &have_geometry, SHOW_HAVE},
{sys_have_innodb.name, (char*) &have_innodb, SHOW_HAVE},
{sys_have_maria.name, (char*) &have_maria, SHOW_HAVE},
{sys_have_maria_db.name, (char*) &have_maria_db, SHOW_HAVE},
{sys_have_merge_db.name, (char*) &have_merge_db, SHOW_HAVE},
{sys_have_ndbcluster.name, (char*) &have_ndbcluster, SHOW_HAVE},
{sys_have_openssl.name, (char*) &have_openssl, SHOW_HAVE},
......
......@@ -31,7 +31,7 @@ DEFS = @DEFS@
# "." is needed first because tests in unittest need libmaria
SUBDIRS = . unittest
EXTRA_DIST = ma_test_all.sh ma_test_all.res ma_ft_stem.c CMakeLists.txt
EXTRA_DIST = ma_test_all.sh ma_test_all.res ma_ft_stem.c CMakeLists.txt plug.in
pkgdata_DATA = ma_test_all ma_test_all.res
pkglib_LIBRARIES = libmaria.a
bin_PROGRAMS = maria_chk maria_pack maria_ftdump
......
......@@ -58,9 +58,11 @@ TYPELIB maria_stats_method_typelib=
** MARIA tables
*****************************************************************************/
static handler *maria_create_handler(TABLE_SHARE * table, MEM_ROOT *mem_root)
static handler *maria_create_handler(handlerton *hton,
TABLE_SHARE * table,
MEM_ROOT *mem_root)
{
return new (mem_root) ha_maria(table);
return new (mem_root) ha_maria(hton, table);
}
......@@ -147,8 +149,8 @@ void _ma_check_print_warning(HA_CHECK *param, const char *fmt, ...)
}
ha_maria::ha_maria(TABLE_SHARE *table_arg):
handler(&maria_hton, table_arg), file(0),
ha_maria::ha_maria(handlerton *hton, TABLE_SHARE *table_arg):
handler(hton, table_arg), file(0),
int_table_flags(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
HA_DUPLICATE_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY |
HA_FILE_BASED | HA_CAN_GEOMETRY | HA_NO_TRANSACTIONS |
......@@ -158,6 +160,15 @@ can_enable_indexes(1)
{}
handler *ha_maria::clone(MEM_ROOT *mem_root)
{
ha_maria *new_handler= static_cast <ha_maria *>(handler::clone(mem_root));
if (new_handler)
new_handler->file->state= file->state;
return new_handler;
}
static const char *ha_maria_exts[]=
{
MARIA_NAME_IEXT,
......@@ -355,7 +366,11 @@ int ha_maria::write_row(byte * buf)
or a new row, then update the auto_increment value in the record.
*/
if (table->next_number_field && buf == table->record[0])
update_auto_increment();
{
int error;
if ((error= update_auto_increment()))
return error;
}
return maria_write(file, buf);
}
......@@ -1818,20 +1833,28 @@ bool ha_maria::check_if_incompatible_data(HA_CREATE_INFO *info,
return COMPATIBLE_DATA_YES;
}
handlerton maria_hton;
extern int maria_panic(enum ha_panic_function flag);
int maria_panic(handlerton *hton, ha_panic_function flag)
{
return maria_panic(flag);
}
static int ha_maria_init()
static int ha_maria_init(void *p)
{
maria_hton.state=SHOW_OPTION_YES;
maria_hton.db_type=DB_TYPE_MARIA;
maria_hton.create=maria_create_handler;
maria_hton.panic=maria_panic;
maria_hton.flags=HTON_CAN_RECREATE;
handlerton *maria_hton;
maria_hton= (handlerton *)p;
maria_hton->state= SHOW_OPTION_YES;
maria_hton->db_type= DB_TYPE_MARIA;
maria_hton->create= maria_create_handler;
maria_hton->panic= maria_panic;
/* TODO: decide if we support Maria being used for log tables */
maria_hton->flags= HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES;
return test(maria_init());
}
struct st_mysql_storage_engine maria_storage_engine=
{ MYSQL_HANDLERTON_INTERFACE_VERSION, &maria_hton };
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
mysql_declare_plugin(maria)
{
......@@ -1840,9 +1863,12 @@ mysql_declare_plugin(maria)
"Maria",
"MySQL AB",
"Traditional transactional MySQL tables",
PLUGIN_LICENSE_GPL,
ha_maria_init, /* Plugin Init */
NULL, /* Plugin Deinit */
0x0100, /* 1.0 */
0
NULL, /* status variables */
NULL, /* system variables */
NULL /* config options */
}
mysql_declare_plugin_end;
......@@ -42,9 +42,9 @@ class ha_maria :public handler
int repair(THD * thd, HA_CHECK &param, bool optimize);
public:
ha_maria(TABLE_SHARE * table_arg);
~ha_maria()
{}
ha_maria(handlerton *hton, TABLE_SHARE * table_arg);
~ha_maria() {}
handler *clone(MEM_ROOT *mem_root);
const char *table_type() const
{ return "MARIA"; }
const char *index_type(uint key_number);
......
......@@ -1371,8 +1371,9 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
param->temp_filename);
goto err;
}
if (maria_filecopy(param,new_file,info->dfile,0L,new_header_length,
"datafile-header"))
if (new_header_length &&
maria_filecopy(param,new_file,info->dfile,0L,new_header_length,
"datafile-header"))
goto err;
info->s->state.dellink= HA_OFFSET_ERROR;
info->rec_cache.file=new_file;
......@@ -2056,8 +2057,9 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
param->temp_filename);
goto err;
}
if (maria_filecopy(param, new_file,info->dfile,0L,new_header_length,
"datafile-header"))
if (new_header_length &&
maria_filecopy(param, new_file,info->dfile,0L,new_header_length,
"datafile-header"))
goto err;
if (param->testflag & T_UNPACK)
{
......@@ -2450,8 +2452,9 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
param->temp_filename);
goto err;
}
if (maria_filecopy(param, new_file,info->dfile,0L,new_header_length,
"datafile-header"))
if (new_header_length &&
maria_filecopy(param, new_file,info->dfile,0L,new_header_length,
"datafile-header"))
goto err;
if (param->testflag & T_UNPACK)
{
......
......@@ -442,7 +442,7 @@ static int del(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *k
else
{
DBUG_PRINT("test",("Inserting of key when deleting"));
if (_ma_get_last_key(info,keyinfo,leaf_buff,keybuff,endpos,
if (!_ma_get_last_key(info,keyinfo,leaf_buff,keybuff,endpos,
&tmp))
goto err;
ret_value= _ma_insert(info,keyinfo,key,leaf_buff,endpos,keybuff,
......
......@@ -19,7 +19,7 @@
#include "maria_def.h"
#include <ft_global.h>
static int maria_inited= 0;
my_bool maria_inited= FALSE;
pthread_mutex_t THR_LOCK_maria;
/*
......@@ -40,7 +40,7 @@ int maria_init(void)
{
if (!maria_inited)
{
maria_inited= 1;
maria_inited= TRUE;
pthread_mutex_init(&THR_LOCK_maria,MY_MUTEX_INIT_SLOW);
}
return 0;
......@@ -51,7 +51,7 @@ void maria_end(void)
{
if (maria_inited)
{
maria_inited= 0;
maria_inited= FALSE;
ft_free_stopwords();
pthread_mutex_destroy(&THR_LOCK_maria);
}
......
......@@ -183,6 +183,21 @@ int maria_lock_database(MARIA_HA *info, int lock_type)
break; /* Impossible */
}
}
#ifdef __WIN__
else
{
/*
Check for bad file descriptors if this table is part
of a merge union. Failing to capture this may cause
a crash on windows if the table is renamed and
later on referenced by the merge table.
*/
if( info->owned_by_merge && (info->s)->kfile < 0 )
{
error = HA_ERR_NO_SUCH_TABLE;
}
}
#endif
pthread_mutex_unlock(&share->intern_lock);
DBUG_RETURN(error);
} /* maria_lock_database */
......
......@@ -231,11 +231,19 @@ my_bool _ma_read_pack_info(MARIA_HA *info, pbool fix_keys)
{
for (i=0 ; i < share->base.keys ; i++)
{
share->keyinfo[i].keylength+=(uint16) diff_length;
share->keyinfo[i].minlength+=(uint16) diff_length;
share->keyinfo[i].maxlength+=(uint16) diff_length;
share->keyinfo[i].seg[share->keyinfo[i].keysegs].length=
(uint16) rec_reflength;
MARIA_KEYDEF *keyinfo= &share->keyinfo[i];
keyinfo->keylength+= (uint16) diff_length;
keyinfo->minlength+= (uint16) diff_length;
keyinfo->maxlength+= (uint16) diff_length;
keyinfo->seg[keyinfo->flag & HA_FULLTEXT ?
FT_SEGS : keyinfo->keysegs].length= (uint16) rec_reflength;
}
if (share->ft2_keyinfo.seg)
{
MARIA_KEYDEF *ft2_keyinfo= &share->ft2_keyinfo;
ft2_keyinfo->keylength+= (uint16) diff_length;
ft2_keyinfo->minlength+= (uint16) diff_length;
ft2_keyinfo->maxlength+= (uint16) diff_length;
}
}
......
......@@ -44,6 +44,8 @@ int maria_panic(enum ha_panic_function flag)
MARIA_HA *info;
DBUG_ENTER("maria_panic");
if (!maria_inited)
DBUG_RETURN(0);
pthread_mutex_lock(&THR_LOCK_maria);
for (list_element=maria_open_list ; list_element ; list_element=next_open)
{
......
......@@ -93,29 +93,42 @@ int maria_rkey(MARIA_HA *info, byte *buf, int inx, const byte *key, uint key_len
maria_read_vec[search_flag], info->s->state.key_root[inx]))
{
/*
If we are searching for an exact key (including the data pointer)
and this was added by an concurrent insert,
then the result is "key not found".
If we searching for a partial key (or using >, >=, < or <=) and
the data is outside of the data file, we need to continue searching
for the first key inside the data file
*/
if ((search_flag == HA_READ_KEY_EXACT) &&
(info->lastpos >= info->state->data_file_length))
if (info->lastpos >= info->state->data_file_length &&
(search_flag != HA_READ_KEY_EXACT ||
last_used_keyseg != keyinfo->seg + keyinfo->keysegs))
{
my_errno= HA_ERR_KEY_NOT_FOUND;
info->lastpos= HA_OFFSET_ERROR;
}
else while (info->lastpos >= info->state->data_file_length)
{
/*
Skip rows that are inserted by other threads since we got a lock
Note that this can only happen if we are not searching after an
exact key, because the keys are sorted according to position
*/
if (_ma_search_next(info, keyinfo, info->lastkey,
info->lastkey_length,
maria_readnext_vec[search_flag],
info->s->state.key_root[inx]))
break;
do
{
uint not_used[2];
/*
Skip rows that are inserted by other threads since we got a lock
Note that this can only happen if we are not searching after an
full length exact key, because the keys are sorted
according to position
*/
if (_ma_search_next(info, keyinfo, info->lastkey,
info->lastkey_length,
maria_readnext_vec[search_flag],
info->s->state.key_root[inx]))
break;
/*
Check that the found key does still match the search.
_ma_search_next() delivers the next key regardless of its
value.
*/
if (search_flag == HA_READ_KEY_EXACT &&
ha_key_cmp(keyinfo->seg, key_buff, info->lastkey, use_key_length,
SEARCH_FIND, not_used))
{
my_errno= HA_ERR_KEY_NOT_FOUND;
info->lastpos= HA_OFFSET_ERROR;
break;
}
} while (info->lastpos >= info->state->data_file_length);
}
}
}
......
......@@ -162,13 +162,13 @@ int maria_write(MARIA_HA *info, byte *record)
/*
Update status of the table. We need to do so after each row write
for the log tables, as we want the new row to become visible to
other threads as soon as possible. We lock mutex here to follow
pthread memory visibility rules.
other threads as soon as possible. We don't lock mutex here
(as it is required by pthread memory visibility rules) as (1) it's
not critical to use outdated share->is_log_table value (2) locking
mutex here for every write is too expensive.
*/
pthread_mutex_lock(&share->intern_lock);
if (share->is_log_table)
_ma_update_status((void*) info);
pthread_mutex_unlock(&share->intern_lock);
allow_break(); /* Allow SIGHUP & SIGINT */
DBUG_RETURN(0);
......
......@@ -305,7 +305,14 @@ struct st_maria_info
my_bool page_changed;
/* If info->buff has to be reread for rnext */
my_bool buff_used;
/*
TODO: decide if we will have Maria-MERGE tables, and if no,
remove some members here.
*/
my_bool once_flags; /* For MARIAMRG */
#ifdef __WIN__
my_bool owned_by_merge; /* This Maria table is part of a merge union */
#endif
#ifdef THREAD
THR_LOCK_DATA lock;
#endif
......@@ -431,6 +438,7 @@ extern LIST *maria_open_list;
extern uchar NEAR maria_file_magic[], NEAR maria_pack_file_magic[];
extern uint NEAR maria_read_vec[], NEAR maria_readnext_vec[];
extern uint maria_quick_table_bits;
extern my_bool maria_inited;
/* This is used by _ma_calc_xxx_key_length och _ma_store_key */
......
......@@ -128,7 +128,6 @@ int main(int argc,char *argv[])
if (count || stats)
{
doc_cnt++;
if (strcmp(buf, buf2))
{
if (*buf2)
......@@ -153,6 +152,7 @@ int main(int argc,char *argv[])
keylen2=keylen;
doc_cnt=0;
}
doc_cnt+= (subkeys >= 0 ? 1 : -subkeys);
}
if (dump)
{
......@@ -168,7 +168,6 @@ int main(int argc,char *argv[])
if (count || stats)
{
doc_cnt++;
if (*buf2)
{
uniq++;
......
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