1
by brian
clean slate |
1 |
/* Copyright (C) 2000-2005 MySQL AB && Innobase Oy
|
2 |
||
3 |
This program is free software; you can redistribute it and/or modify
|
|
4 |
it under the terms of the GNU General Public License as published by
|
|
5 |
the Free Software Foundation; version 2 of the License.
|
|
6 |
||
7 |
This program is distributed in the hope that it will be useful,
|
|
8 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
9 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
10 |
GNU General Public License for more details.
|
|
11 |
||
12 |
You should have received a copy of the GNU General Public License
|
|
13 |
along with this program; if not, write to the Free Software
|
|
14 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
15 |
||
16 |
/*
|
|
17 |
This file is based on ha_berkeley.h of MySQL distribution
|
|
18 |
||
19 |
This file defines the Innodb handler: the interface between MySQL and
|
|
20 |
Innodb
|
|
21 |
*/
|
|
22 |
||
23 |
#ifdef USE_PRAGMA_INTERFACE
|
|
24 |
#pragma interface /* gcc class implementation */ |
|
25 |
#endif
|
|
26 |
||
27 |
typedef struct st_innobase_share { |
|
28 |
THR_LOCK lock; |
|
29 |
pthread_mutex_t mutex; |
|
30 |
char *table_name; |
|
31 |
uint table_name_length,use_count; |
|
32 |
} INNOBASE_SHARE; |
|
33 |
||
34 |
||
35 |
struct dict_index_struct; |
|
36 |
struct row_prebuilt_struct; |
|
37 |
||
38 |
typedef struct dict_index_struct dict_index_t; |
|
39 |
typedef struct row_prebuilt_struct row_prebuilt_t; |
|
40 |
||
41 |
/* The class defining a handle to an Innodb table */
|
|
42 |
class ha_innobase: public handler |
|
43 |
{
|
|
44 |
row_prebuilt_t* prebuilt; /* prebuilt struct in InnoDB, used |
|
45 |
to save CPU time with prebuilt data
|
|
46 |
structures*/
|
|
47 |
THD* user_thd; /* the thread handle of the user |
|
48 |
currently using the handle; this is
|
|
49 |
set in external_lock function */
|
|
50 |
THR_LOCK_DATA lock; |
|
51 |
INNOBASE_SHARE *share; |
|
52 |
||
53 |
uchar* upd_buff; /* buffer used in updates */ |
|
54 |
uchar* key_val_buff; /* buffer used in converting |
|
55 |
search key values from MySQL format
|
|
56 |
to Innodb format */
|
|
57 |
ulong upd_and_key_val_buff_len; |
|
58 |
/* the length of each of the previous
|
|
59 |
two buffers */
|
|
60 |
Table_flags int_table_flags; |
|
61 |
uint primary_key; |
|
62 |
ulong start_of_scan; /* this is set to 1 when we are |
|
63 |
starting a table scan but have not
|
|
64 |
yet fetched any row, else 0 */
|
|
65 |
uint last_match_mode;/* match mode of the latest search: |
|
66 |
ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX,
|
|
67 |
or undefined */
|
|
68 |
uint num_write_row; /* number of write_row() calls */ |
|
69 |
||
70 |
uint store_key_val_for_row(uint keynr, char* buff, uint buff_len, |
|
71 |
const uchar* record); |
|
72 |
int update_thd(THD* thd); |
|
73 |
int change_active_index(uint keynr); |
|
74 |
int general_fetch(uchar* buf, uint direction, uint match_mode); |
|
75 |
int innobase_read_and_init_auto_inc(longlong* ret); |
|
76 |
ulong innobase_autoinc_lock(); |
|
77 |
ulong innobase_set_max_autoinc(ulonglong auto_inc); |
|
78 |
ulong innobase_reset_autoinc(ulonglong auto_inc); |
|
79 |
ulong innobase_get_auto_increment(ulonglong* value); |
|
80 |
dict_index_t* innobase_get_index(uint keynr); |
|
81 |
||
82 |
/* Init values for the class: */
|
|
83 |
public: |
|
84 |
ha_innobase(handlerton *hton, TABLE_SHARE *table_arg); |
|
85 |
~ha_innobase() {} |
|
86 |
/*
|
|
87 |
Get the row type from the storage engine. If this method returns
|
|
88 |
ROW_TYPE_NOT_USED, the information in HA_CREATE_INFO should be used.
|
|
89 |
*/
|
|
90 |
enum row_type get_row_type() const; |
|
91 |
||
92 |
const char* table_type() const { return("InnoDB");} |
|
93 |
const char *index_type(uint key_number) { return "BTREE"; } |
|
94 |
const char** bas_ext() const; |
|
95 |
Table_flags table_flags() const; |
|
96 |
ulong index_flags(uint idx, uint part, bool all_parts) const |
|
97 |
{
|
|
98 |
return (HA_READ_NEXT | |
|
99 |
HA_READ_PREV | |
|
100 |
HA_READ_ORDER | |
|
101 |
HA_READ_RANGE | |
|
102 |
HA_KEYREAD_ONLY | |
|
103 |
((idx == primary_key)? 0 : HA_DO_INDEX_COND_PUSHDOWN)); |
|
104 |
}
|
|
105 |
uint max_supported_keys() const { return MAX_KEY; } |
|
106 |
/* An InnoDB page must store >= 2 keys;
|
|
107 |
a secondary key record must also contain the
|
|
108 |
primary key value:
|
|
109 |
max key length is therefore set to slightly
|
|
110 |
less than 1 / 4 of page size which is 16 kB;
|
|
111 |
but currently MySQL does not work with keys
|
|
112 |
whose size is > MAX_KEY_LENGTH */
|
|
113 |
uint max_supported_key_length() const { return 3500; } |
|
114 |
uint max_supported_key_part_length() const; |
|
115 |
const key_map *keys_to_use_for_scanning() { return &key_map_full; } |
|
116 |
||
117 |
int open(const char *name, int mode, uint test_if_locked); |
|
118 |
int close(void); |
|
119 |
double scan_time(); |
|
120 |
double read_time(uint index, uint ranges, ha_rows rows); |
|
121 |
||
122 |
int write_row(uchar * buf); |
|
123 |
int update_row(const uchar * old_data, uchar * new_data); |
|
124 |
int delete_row(const uchar * buf); |
|
125 |
bool was_semi_consistent_read(); |
|
126 |
void try_semi_consistent_read(bool yes); |
|
127 |
void unlock_row(); |
|
128 |
||
129 |
int index_init(uint index, bool sorted); |
|
130 |
int index_end(); |
|
131 |
int index_read(uchar * buf, const uchar * key, |
|
132 |
uint key_len, enum ha_rkey_function find_flag); |
|
133 |
int index_read_idx(uchar * buf, uint index, const uchar * key, |
|
134 |
uint key_len, enum ha_rkey_function find_flag); |
|
135 |
int index_read_last(uchar * buf, const uchar * key, uint key_len); |
|
136 |
int index_next(uchar * buf); |
|
137 |
int index_next_same(uchar * buf, const uchar *key, uint keylen); |
|
138 |
int index_prev(uchar * buf); |
|
139 |
int index_first(uchar * buf); |
|
140 |
int index_last(uchar * buf); |
|
141 |
||
142 |
int rnd_init(bool scan); |
|
143 |
int rnd_end(); |
|
144 |
int rnd_next(uchar *buf); |
|
145 |
int rnd_pos(uchar * buf, uchar *pos); |
|
146 |
||
147 |
void position(const uchar *record); |
|
148 |
int info(uint); |
|
149 |
int analyze(THD* thd,HA_CHECK_OPT* check_opt); |
|
150 |
int optimize(THD* thd,HA_CHECK_OPT* check_opt); |
|
151 |
int discard_or_import_tablespace(my_bool discard); |
|
152 |
int extra(enum ha_extra_function operation); |
|
153 |
int reset(); |
|
154 |
int lock_table(THD *thd, int lock_type, int lock_timeout) |
|
155 |
{
|
|
156 |
/*
|
|
157 |
Preliminarily call the pre-existing internal method for
|
|
158 |
transactional locking and ignore non-transactional locks.
|
|
159 |
*/
|
|
160 |
if (!lock_timeout) |
|
161 |
{
|
|
162 |
/* Preliminarily show both possible errors for NOWAIT. */
|
|
163 |
if (lock_type == F_WRLCK) |
|
164 |
return HA_ERR_UNSUPPORTED; |
|
165 |
else
|
|
166 |
return HA_ERR_LOCK_WAIT_TIMEOUT; |
|
167 |
}
|
|
168 |
return transactional_table_lock(thd, lock_type); |
|
169 |
}
|
|
170 |
int external_lock(THD *thd, int lock_type); |
|
171 |
int transactional_table_lock(THD *thd, int lock_type); |
|
172 |
int start_stmt(THD *thd, thr_lock_type lock_type); |
|
173 |
void position(uchar *record); |
|
174 |
ha_rows records_in_range(uint inx, key_range *min_key, key_range |
|
175 |
*max_key); |
|
176 |
ha_rows estimate_rows_upper_bound(); |
|
177 |
||
178 |
void update_create_info(HA_CREATE_INFO* create_info); |
|
179 |
int create(const char *name, register TABLE *form, |
|
180 |
HA_CREATE_INFO *create_info); |
|
181 |
int delete_all_rows(); |
|
182 |
int delete_table(const char *name); |
|
183 |
int rename_table(const char* from, const char* to); |
|
184 |
int check(THD* thd, HA_CHECK_OPT* check_opt); |
|
185 |
char* update_table_comment(const char* comment); |
|
186 |
char* get_foreign_key_create_info(); |
|
187 |
int get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list); |
|
188 |
bool can_switch_engines(); |
|
189 |
uint referenced_by_foreign_key(); |
|
190 |
void free_foreign_key_create_info(char* str); |
|
191 |
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, |
|
192 |
enum thr_lock_type lock_type); |
|
193 |
void init_table_handle_for_HANDLER(); |
|
194 |
virtual void get_auto_increment(ulonglong offset, ulonglong increment, |
|
195 |
ulonglong nb_desired_values, |
|
196 |
ulonglong *first_value, |
|
197 |
ulonglong *nb_reserved_values); |
|
198 |
int reset_auto_increment(ulonglong value); |
|
199 |
||
200 |
virtual bool get_error_message(int error, String *buf); |
|
201 |
||
202 |
uint8 table_cache_type() { return HA_CACHE_TBL_ASKTRANSACT; } |
|
203 |
/*
|
|
204 |
ask handler about permission to cache table during query registration
|
|
205 |
*/
|
|
206 |
my_bool register_query_cache_table(THD *thd, char *table_key, |
|
207 |
uint key_length, |
|
208 |
qc_engine_callback *call_back, |
|
209 |
ulonglong *engine_data); |
|
210 |
static char *get_mysql_bin_log_name(); |
|
211 |
static ulonglong get_mysql_bin_log_pos(); |
|
212 |
bool primary_key_is_clustered() { return true; } |
|
213 |
int cmp_ref(const uchar *ref1, const uchar *ref2); |
|
214 |
bool check_if_incompatible_data(HA_CREATE_INFO *info, |
|
215 |
uint table_changes); |
|
216 |
public: |
|
217 |
/**
|
|
218 |
* Multi Range Read interface
|
|
219 |
*/
|
|
220 |
int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param, |
|
221 |
uint n_ranges, uint mode, HANDLER_BUFFER *buf); |
|
222 |
int multi_range_read_next(char **range_info); |
|
223 |
ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, |
|
224 |
void *seq_init_param, |
|
225 |
uint n_ranges, uint *bufsz, |
|
226 |
uint *flags, COST_VECT *cost); |
|
227 |
int multi_range_read_info(uint keyno, uint n_ranges, uint keys, |
|
228 |
uint *bufsz, uint *flags, COST_VECT *cost); |
|
229 |
DsMrr_impl ds_mrr; |
|
230 |
||
231 |
int read_range_first(const key_range *start_key, const key_range *end_key, |
|
232 |
bool eq_range_arg, bool sorted); |
|
233 |
int read_range_next(); |
|
234 |
Item *idx_cond_push(uint keyno, Item* idx_cond); |
|
235 |
};
|
|
236 |
||
237 |
/* Some accessor functions which the InnoDB plugin needs, but which
|
|
238 |
can not be added to mysql/plugin.h as part of the public interface;
|
|
239 |
the definitions are bracketed with #ifdef INNODB_COMPATIBILITY_HOOKS */
|
|
240 |
||
241 |
#ifndef INNODB_COMPATIBILITY_HOOKS
|
|
242 |
#error InnoDB needs MySQL to be built with #define INNODB_COMPATIBILITY_HOOKS
|
|
243 |
#endif
|
|
244 |
||
245 |
extern "C" { |
|
246 |
struct charset_info_st *thd_charset(MYSQL_THD thd); |
|
247 |
char **thd_query(MYSQL_THD thd); |
|
248 |
||
249 |
/** Get the file name of the MySQL binlog.
|
|
250 |
* @return the name of the binlog file
|
|
251 |
*/
|
|
252 |
const char* mysql_bin_log_file_name(void); |
|
253 |
||
254 |
/** Get the current position of the MySQL binlog.
|
|
255 |
* @return byte offset from the beginning of the binlog
|
|
256 |
*/
|
|
257 |
ulonglong mysql_bin_log_file_pos(void); |
|
258 |
||
259 |
/**
|
|
260 |
Check if a user thread is a replication slave thread
|
|
261 |
@param thd user thread
|
|
262 |
@retval 0 the user thread is not a replication slave thread
|
|
263 |
@retval 1 the user thread is a replication slave thread
|
|
264 |
*/
|
|
265 |
int thd_slave_thread(const MYSQL_THD thd); |
|
266 |
||
267 |
/**
|
|
268 |
Check if a user thread is running a non-transactional update
|
|
269 |
@param thd user thread
|
|
270 |
@retval 0 the user thread is not running a non-transactional update
|
|
271 |
@retval 1 the user thread is running a non-transactional update
|
|
272 |
*/
|
|
273 |
int thd_non_transactional_update(const MYSQL_THD thd); |
|
274 |
||
275 |
/**
|
|
276 |
Get the user thread's binary logging format
|
|
277 |
@param thd user thread
|
|
278 |
@return Value to be used as index into the binlog_format_names array
|
|
279 |
*/
|
|
280 |
int thd_binlog_format(const MYSQL_THD thd); |
|
281 |
||
282 |
/**
|
|
283 |
Mark transaction to rollback and mark error as fatal to a sub-statement.
|
|
284 |
@param thd Thread handle
|
|
285 |
@param all TRUE <=> rollback main transaction.
|
|
286 |
*/
|
|
287 |
void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all); |
|
288 |
}
|