mirror of
https://github.com/MariaDB/server.git
synced 2025-01-20 14:02:32 +01:00
ef15a335b3
---------------------------------------------------------- revno: 2630.4.38 committer: Konstantin Osipov <konstantin@mysql.com> branch nick: mysql-6.0-4144 timestamp: Wed 2008-06-25 22:07:06 +0400 message: WL#4144 - Lock MERGE engine children. Committing a version of the patch merged with WL#3726 on behalf of Ingo. Step #1: Move locking from parent to children. MERGE children are now left in the query list of tables after inserted there in open_tables(). So they are locked by lock_tables() as all other tables are. The MERGE parent does not store locks any more. It appears in a MYSQL_LOCK with zero lock data. This is kind of a "dummy" lock. All other lock handling is also done directly on the children. To protect against parent or child modifications during LOCK TABLES, the children are detached after every statement and attached before every statement, even under LOCK TABLES. The children table list is removed from the query list of tables on every detach and on close of the parent. Step #2: Move MERGE specific functionality from SQL layer into table handler. Functionality moved from SQL layer (mainly sql_base.cc) to the table handler (ha_myisammrg.cc). Unnecessary code is removed from the SQL layer. Step #3: Moved all MERGE specific members from TABLE to ha_myisammrg. Moved members from TABLE to ha_myisammrg. Renamed some mebers. Fixed comments. Step #4: Valgrind and coverage testing Valgrind did not uncover new problems. Added purecov comments. Added a new test for DATA/INDEX DIRECTORY options. Changed handling of ::reset() for non-attached children. Fixed the merge-big test. Step #5: Fixed crashes detected during review Changed detection when to attach/detach. Added new tests. Backport also the fix for Bug#44040 "MySQL allows creating a MERGE table upon VIEWs but crashes when using it"
106 lines
4.3 KiB
C++
106 lines
4.3 KiB
C++
/* Copyright (C) 2000-2006 MySQL AB
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; version 2 of the License.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
|
|
|
|
#ifdef USE_PRAGMA_INTERFACE
|
|
#pragma interface /* gcc class implementation */
|
|
#endif
|
|
|
|
/* class for the the myisam merge handler */
|
|
|
|
#include <myisammrg.h>
|
|
|
|
class ha_myisammrg: public handler
|
|
{
|
|
MYRG_INFO *file;
|
|
my_bool is_cloned; /* This instance has been cloned */
|
|
|
|
public:
|
|
MEM_ROOT children_mem_root; /* mem root for children list */
|
|
TABLE_LIST *children_l; /* children list */
|
|
TABLE_LIST **children_last_l; /* children list end */
|
|
TABLE_LIST *next_child_attach; /* next child to attach */
|
|
uint test_if_locked; /* flags from ::open() */
|
|
bool need_compat_check; /* if need compatibility check */
|
|
|
|
ha_myisammrg(handlerton *hton, TABLE_SHARE *table_arg);
|
|
~ha_myisammrg();
|
|
const char *table_type() const { return "MRG_MyISAM"; }
|
|
const char **bas_ext() const;
|
|
const char *index_type(uint key_number);
|
|
ulonglong table_flags() const
|
|
{
|
|
return (HA_REC_NOT_IN_SEQ | HA_AUTO_PART_KEY | HA_NO_TRANSACTIONS |
|
|
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
|
|
HA_NULL_IN_KEY | HA_CAN_INDEX_BLOBS | HA_FILE_BASED |
|
|
HA_ANY_INDEX_MAY_BE_UNIQUE | HA_CAN_BIT_FIELD |
|
|
HA_HAS_RECORDS |
|
|
HA_NO_COPY_ON_ALTER |
|
|
HA_DUPLICATE_POS);
|
|
}
|
|
ulong index_flags(uint inx, uint part, bool all_parts) const
|
|
{
|
|
return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
|
|
0 : HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
|
|
HA_READ_ORDER | HA_KEYREAD_ONLY);
|
|
}
|
|
uint max_supported_keys() const { return MI_MAX_KEY; }
|
|
uint max_supported_key_length() const { return MI_MAX_KEY_LENGTH; }
|
|
uint max_supported_key_part_length() const { return MI_MAX_KEY_LENGTH; }
|
|
double scan_time()
|
|
{ return ulonglong2double(stats.data_file_length) / IO_SIZE + file->tables; }
|
|
|
|
int open(const char *name, int mode, uint test_if_locked);
|
|
int add_children_list(void);
|
|
int attach_children(void);
|
|
int detach_children(void);
|
|
virtual handler *clone(MEM_ROOT *mem_root);
|
|
int close(void);
|
|
int write_row(uchar * buf);
|
|
int update_row(const uchar * old_data, uchar * new_data);
|
|
int delete_row(const uchar * buf);
|
|
int index_read_map(uchar *buf, const uchar *key, key_part_map keypart_map,
|
|
enum ha_rkey_function find_flag);
|
|
int index_read_idx_map(uchar *buf, uint index, const uchar *key,
|
|
key_part_map keypart_map,
|
|
enum ha_rkey_function find_flag);
|
|
int index_read_last_map(uchar *buf, const uchar *key, key_part_map keypart_map);
|
|
int index_next(uchar * buf);
|
|
int index_prev(uchar * buf);
|
|
int index_first(uchar * buf);
|
|
int index_last(uchar * buf);
|
|
int index_next_same(uchar *buf, const uchar *key, uint keylen);
|
|
int rnd_init(bool scan);
|
|
int rnd_next(uchar *buf);
|
|
int rnd_pos(uchar * buf, uchar *pos);
|
|
void position(const uchar *record);
|
|
ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key);
|
|
int info(uint);
|
|
int reset(void);
|
|
int extra(enum ha_extra_function operation);
|
|
int extra_opt(enum ha_extra_function operation, ulong cache_size);
|
|
int external_lock(THD *thd, int lock_type);
|
|
uint lock_count(void) const;
|
|
int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info);
|
|
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
|
|
enum thr_lock_type lock_type);
|
|
void update_create_info(HA_CREATE_INFO *create_info);
|
|
void append_create_info(String *packet);
|
|
MYRG_INFO *myrg_info() { return file; }
|
|
TABLE *table_ptr() { return table; }
|
|
bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes);
|
|
int check(THD* thd, HA_CHECK_OPT* check_opt);
|
|
ha_rows records();
|
|
};
|