1#ifndef HA_PARTITION_INCLUDED
2#define HA_PARTITION_INCLUDED
3
4/*
5 Copyright (c) 2005, 2012, Oracle and/or its affiliates.
6 Copyright (c) 2009, 2013, Monty Program Ab & SkySQL Ab.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; version 2 of the License.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
20
21#include "sql_partition.h" /* part_id_range, partition_element */
22#include "queues.h" /* QUEUE */
23
24#define PARTITION_BYTES_IN_POS 2
25
26
27/** Struct used for partition_name_hash */
28typedef struct st_part_name_def
29{
30 uchar *partition_name;
31 uint length;
32 uint32 part_id;
33 my_bool is_subpart;
34} PART_NAME_DEF;
35
36/** class where to save partitions Handler_share's */
37class Parts_share_refs
38{
39public:
40 uint num_parts; /**< Size of ha_share array */
41 Handler_share **ha_shares; /**< Storage for each part */
42 Parts_share_refs()
43 {
44 num_parts= 0;
45 ha_shares= NULL;
46 }
47 ~Parts_share_refs()
48 {
49 uint i;
50 for (i= 0; i < num_parts; i++)
51 delete ha_shares[i];
52 delete[] ha_shares;
53 }
54 bool init(uint arg_num_parts)
55 {
56 DBUG_ASSERT(!num_parts && !ha_shares);
57 num_parts= arg_num_parts;
58 /* Allocate an array of Handler_share pointers */
59 ha_shares= new Handler_share *[num_parts];
60 if (!ha_shares)
61 {
62 num_parts= 0;
63 return true;
64 }
65 memset(ha_shares, 0, sizeof(Handler_share*) * num_parts);
66 return false;
67 }
68};
69
70class ha_partition;
71
72/* Partition Full Text Search info */
73struct st_partition_ft_info
74{
75 struct _ft_vft *please;
76 st_partition_ft_info *next;
77 ha_partition *file;
78 FT_INFO **part_ft_info;
79};
80
81
82#ifdef HAVE_PSI_MUTEX_INTERFACE
83extern PSI_mutex_key key_partition_auto_inc_mutex;
84#endif
85
86/**
87 Partition specific Handler_share.
88*/
89class Partition_share : public Handler_share
90{
91public:
92 bool auto_inc_initialized;
93 mysql_mutex_t auto_inc_mutex; /**< protecting auto_inc val */
94 ulonglong next_auto_inc_val; /**< first non reserved value */
95 /**
96 Hash of partition names. Initialized in the first ha_partition::open()
97 for the table_share. After that it is read-only, i.e. no locking required.
98 */
99 bool partition_name_hash_initialized;
100 HASH partition_name_hash;
101 /** Storage for each partitions Handler_share */
102 Parts_share_refs partitions_share_refs;
103 Partition_share()
104 : auto_inc_initialized(false),
105 next_auto_inc_val(0),
106 partition_name_hash_initialized(false),
107 partition_names(NULL)
108 {
109 mysql_mutex_init(key_partition_auto_inc_mutex,
110 &auto_inc_mutex,
111 MY_MUTEX_INIT_FAST);
112 }
113
114 ~Partition_share()
115 {
116 mysql_mutex_destroy(&auto_inc_mutex);
117 if (partition_names)
118 {
119 my_free(partition_names);
120 }
121 if (partition_name_hash_initialized)
122 {
123 my_hash_free(&partition_name_hash);
124 }
125 }
126
127 bool init(uint num_parts);
128
129 /**
130 Release reserved auto increment values not used.
131 @param thd Thread.
132 @param table_share Table Share
133 @param next_insert_id Next insert id (first non used auto inc value).
134 @param max_reserved End of reserved auto inc range.
135 */
136 void release_auto_inc_if_possible(THD *thd, TABLE_SHARE *table_share,
137 const ulonglong next_insert_id,
138 const ulonglong max_reserved);
139
140 /** lock mutex protecting auto increment value next_auto_inc_val. */
141 inline void lock_auto_inc()
142 {
143 mysql_mutex_lock(&auto_inc_mutex);
144 }
145 /** unlock mutex protecting auto increment value next_auto_inc_val. */
146 inline void unlock_auto_inc()
147 {
148 mysql_mutex_unlock(&auto_inc_mutex);
149 }
150 /**
151 Populate partition_name_hash with partition and subpartition names
152 from part_info.
153 @param part_info Partition info containing all partitions metadata.
154
155 @return Operation status.
156 @retval false Success.
157 @retval true Failure.
158 */
159 bool populate_partition_name_hash(partition_info *part_info);
160 /** Get partition name.
161
162 @param part_id Partition id (for subpartitioned table only subpartition
163 names will be returned.)
164
165 @return partition name or NULL if error.
166 */
167 const char *get_partition_name(size_t part_id) const;
168private:
169 const uchar **partition_names;
170 /**
171 Insert [sub]partition name into partition_name_hash
172 @param name Partition name.
173 @param part_id Partition id.
174 @param is_subpart True if subpartition else partition.
175
176 @return Operation status.
177 @retval false Success.
178 @retval true Failure.
179 */
180 bool insert_partition_name_in_hash(const char *name,
181 uint part_id,
182 bool is_subpart);
183};
184
185typedef struct st_partition_key_multi_range
186{
187 uint id;
188 uchar *key[2];
189 uint length[2];
190 KEY_MULTI_RANGE key_multi_range;
191 range_id_t ptr;
192 st_partition_key_multi_range *next;
193} PARTITION_KEY_MULTI_RANGE;
194
195
196typedef struct st_partition_part_key_multi_range
197{
198 PARTITION_KEY_MULTI_RANGE *partition_key_multi_range;
199 st_partition_part_key_multi_range *next;
200} PARTITION_PART_KEY_MULTI_RANGE;
201
202
203class ha_partition;
204typedef struct st_partition_part_key_multi_range_hld
205{
206 ha_partition *partition;
207 uint32 part_id;
208 PARTITION_PART_KEY_MULTI_RANGE *partition_part_key_multi_range;
209} PARTITION_PART_KEY_MULTI_RANGE_HLD;
210
211
212extern "C" int cmp_key_part_id(void *key_p, uchar *ref1, uchar *ref2);
213extern "C" int cmp_key_rowid_part_id(void *ptr, uchar *ref1, uchar *ref2);
214
215class ha_partition :public handler
216{
217private:
218 enum partition_index_scan_type
219 {
220 partition_index_read= 0,
221 partition_index_first= 1,
222 partition_index_last= 3,
223 partition_index_read_last= 4,
224 partition_read_range = 5,
225 partition_no_index_scan= 6,
226 partition_read_multi_range = 7,
227 partition_ft_read= 8
228 };
229 /* Data for the partition handler */
230 int m_mode; // Open mode
231 uint m_open_test_lock; // Open test_if_locked
232 uchar *m_file_buffer; // Content of the .par file
233 char *m_name_buffer_ptr; // Pointer to first partition name
234 MEM_ROOT m_mem_root;
235 plugin_ref *m_engine_array; // Array of types of the handlers
236 handler **m_file; // Array of references to handler inst.
237 uint m_file_tot_parts; // Debug
238 handler **m_new_file; // Array of references to new handlers
239 handler **m_reorged_file; // Reorganised partitions
240 handler **m_added_file; // Added parts kept for errors
241 LEX_CSTRING *m_connect_string;
242 partition_info *m_part_info; // local reference to partition
243 Field **m_part_field_array; // Part field array locally to save acc
244 uchar *m_ordered_rec_buffer; // Row and key buffer for ord. idx scan
245 st_partition_ft_info *ft_first;
246 st_partition_ft_info *ft_current;
247 /*
248 Current index.
249 When used in key_rec_cmp: If clustered pk, index compare
250 must compare pk if given index is same for two rows.
251 So normally m_curr_key_info[0]= current index and m_curr_key[1]= NULL,
252 and if clustered pk, [0]= current index, [1]= pk, [2]= NULL
253 */
254 KEY *m_curr_key_info[3]; // Current index
255 uchar *m_rec0; // table->record[0]
256 const uchar *m_err_rec; // record which gave error
257 QUEUE m_queue; // Prio queue used by sorted read
258
259 /*
260 Length of an element in m_ordered_rec_buffer. The elements are composed of
261
262 [part_no] [table->record copy] [underlying_table_rowid]
263
264 underlying_table_rowid is only stored when the table has no extended keys.
265 */
266 size_t m_priority_queue_rec_len;
267
268 /*
269 If true, then sorting records by key value also sorts them by their
270 underlying_table_rowid.
271 */
272 bool m_using_extended_keys;
273
274 /*
275 Since the partition handler is a handler on top of other handlers, it
276 is necessary to keep information about what the underlying handler
277 characteristics is. It is not possible to keep any handler instances
278 for this since the MySQL Server sometimes allocating the handler object
279 without freeing them.
280 */
281 enum enum_handler_status
282 {
283 handler_not_initialized= 0,
284 handler_initialized,
285 handler_opened,
286 handler_closed
287 };
288 enum_handler_status m_handler_status;
289
290 uint m_reorged_parts; // Number of reorganised parts
291 uint m_tot_parts; // Total number of partitions;
292 uint m_num_locks; // For engines like ha_blackhole, which needs no locks
293 uint m_last_part; // Last file that we update,write,read
294 part_id_range m_part_spec; // Which parts to scan
295 uint m_scan_value; // Value passed in rnd_init
296 // call
297 uint m_ref_length; // Length of position in this
298 // handler object
299 key_range m_start_key; // index read key range
300 enum partition_index_scan_type m_index_scan_type;// What type of index
301 // scan
302 uint m_top_entry; // Which partition is to
303 // deliver next result
304 uint m_rec_length; // Local copy of record length
305
306 bool m_ordered; // Ordered/Unordered index scan
307 bool m_pkey_is_clustered; // Is primary key clustered
308 bool m_create_handler; // Handler used to create table
309 bool m_is_sub_partitioned; // Is subpartitioned
310 bool m_ordered_scan_ongoing;
311 bool m_rnd_init_and_first;
312 bool m_ft_init_and_first;
313
314 /*
315 If set, this object was created with ha_partition::clone and doesn't
316 "own" the m_part_info structure.
317 */
318 ha_partition *m_is_clone_of;
319 MEM_ROOT *m_clone_mem_root;
320
321 /*
322 We keep track if all underlying handlers are MyISAM since MyISAM has a
323 great number of extra flags not needed by other handlers.
324 */
325 bool m_myisam; // Are all underlying handlers
326 // MyISAM
327 /*
328 We keep track of InnoDB handlers below since it requires proper setting
329 of query_id in fields at index_init and index_read calls.
330 */
331 bool m_innodb; // Are all underlying handlers
332 // InnoDB
333 /*
334 When calling extra(HA_EXTRA_CACHE) we do not pass this to the underlying
335 handlers immediately. Instead we cache it and call the underlying
336 immediately before starting the scan on the partition. This is to
337 prevent allocating a READ CACHE for each partition in parallel when
338 performing a full table scan on MyISAM partitioned table.
339 This state is cleared by extra(HA_EXTRA_NO_CACHE).
340 */
341 bool m_extra_cache;
342 uint m_extra_cache_size;
343 /* The same goes for HA_EXTRA_PREPARE_FOR_UPDATE */
344 bool m_extra_prepare_for_update;
345 /* Which partition has active cache */
346 uint m_extra_cache_part_id;
347
348 void init_handler_variables();
349 /*
350 Variables for lock structures.
351 */
352 THR_LOCK_DATA lock; /* MySQL lock */
353
354 bool auto_increment_lock; /**< lock reading/updating auto_inc */
355 /**
356 Flag to keep the auto_increment lock through out the statement.
357 This to ensure it will work with statement based replication.
358 */
359 bool auto_increment_safe_stmt_log_lock;
360 /** For optimizing ha_start_bulk_insert calls */
361 MY_BITMAP m_bulk_insert_started;
362 ha_rows m_bulk_inserted_rows;
363 /** used for prediction of start_bulk_insert rows */
364 enum_monotonicity_info m_part_func_monotonicity_info;
365 part_id_range m_direct_update_part_spec;
366 bool m_pre_calling;
367 bool m_pre_call_use_parallel;
368 /* Keep track of bulk access requests */
369 bool bulk_access_executing;
370
371 /** keep track of locked partitions */
372 MY_BITMAP m_locked_partitions;
373 /** Stores shared auto_increment etc. */
374 Partition_share *part_share;
375 /** Temporary storage for new partitions Handler_shares during ALTER */
376 List<Parts_share_refs> m_new_partitions_share_refs;
377 /** Sorted array of partition ids in descending order of number of rows. */
378 uint32 *m_part_ids_sorted_by_num_of_records;
379 /* Compare function for my_qsort2, for reversed order. */
380 static int compare_number_of_records(ha_partition *me,
381 const uint32 *a,
382 const uint32 *b);
383 /** keep track of partitions to call ha_reset */
384 MY_BITMAP m_partitions_to_reset;
385 /** partitions that returned HA_ERR_KEY_NOT_FOUND. */
386 MY_BITMAP m_key_not_found_partitions;
387 bool m_key_not_found;
388 List<String> *m_partitions_to_open;
389 MY_BITMAP m_opened_partitions;
390 /** This is one of the m_file-s that it guaranteed to be opened. */
391 /** It is set in open_read_partitions() */
392 handler *m_file_sample;
393public:
394 handler **get_child_handlers()
395 {
396 return m_file;
397 }
398 virtual part_id_range *get_part_spec()
399 {
400 return &m_part_spec;
401 }
402 virtual uint get_no_current_part_id()
403 {
404 return NO_CURRENT_PART_ID;
405 }
406 Partition_share *get_part_share() { return part_share; }
407 handler *clone(const char *name, MEM_ROOT *mem_root);
408 virtual void set_part_info(partition_info *part_info)
409 {
410 m_part_info= part_info;
411 m_is_sub_partitioned= part_info->is_sub_partitioned();
412 }
413
414 virtual void return_record_by_parent();
415
416 /*
417 -------------------------------------------------------------------------
418 MODULE create/delete handler object
419 -------------------------------------------------------------------------
420 Object create/delete methode. The normal called when a table object
421 exists. There is also a method to create the handler object with only
422 partition information. This is used from mysql_create_table when the
423 table is to be created and the engine type is deduced to be the
424 partition handler.
425 -------------------------------------------------------------------------
426 */
427 ha_partition(handlerton *hton, TABLE_SHARE * table);
428 ha_partition(handlerton *hton, partition_info * part_info);
429 ha_partition(handlerton *hton, TABLE_SHARE *share,
430 partition_info *part_info_arg,
431 ha_partition *clone_arg,
432 MEM_ROOT *clone_mem_root_arg);
433 ~ha_partition();
434 void ha_partition_init();
435 /*
436 A partition handler has no characteristics in itself. It only inherits
437 those from the underlying handlers. Here we set-up those constants to
438 enable later calls of the methods to retrieve constants from the under-
439 lying handlers. Returns false if not successful.
440 */
441 bool initialize_partition(MEM_ROOT *mem_root);
442
443 /*
444 -------------------------------------------------------------------------
445 MODULE meta data changes
446 -------------------------------------------------------------------------
447 Meta data routines to CREATE, DROP, RENAME table and often used at
448 ALTER TABLE (update_create_info used from ALTER TABLE and SHOW ..).
449
450 update_table_comment is used in SHOW TABLE commands to provide a
451 chance for the handler to add any interesting comments to the table
452 comments not provided by the users comment.
453
454 create_partitioning_metadata is called before opening a new handler object
455 with openfrm to call create. It is used to create any local handler
456 object needed in opening the object in openfrm
457 -------------------------------------------------------------------------
458 */
459 virtual int delete_table(const char *from);
460 virtual int rename_table(const char *from, const char *to);
461 virtual int create(const char *name, TABLE *form,
462 HA_CREATE_INFO *create_info);
463 virtual int create_partitioning_metadata(const char *name,
464 const char *old_name, int action_flag);
465 virtual void update_create_info(HA_CREATE_INFO *create_info);
466 virtual char *update_table_comment(const char *comment);
467 virtual int change_partitions(HA_CREATE_INFO *create_info,
468 const char *path,
469 ulonglong * const copied,
470 ulonglong * const deleted,
471 const uchar *pack_frm_data,
472 size_t pack_frm_len);
473 virtual int drop_partitions(const char *path);
474 virtual int rename_partitions(const char *path);
475 bool get_no_parts(const char *name, uint *num_parts)
476 {
477 DBUG_ENTER("ha_partition::get_no_parts");
478 *num_parts= m_tot_parts;
479 DBUG_RETURN(0);
480 }
481 virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share);
482 virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
483 uint table_changes);
484 void update_part_create_info(HA_CREATE_INFO *create_info, uint part_id)
485 {
486 m_file[part_id]->update_create_info(create_info);
487 }
488private:
489 int copy_partitions(ulonglong * const copied, ulonglong * const deleted);
490 void cleanup_new_partition(uint part_count);
491 int prepare_new_partition(TABLE *table, HA_CREATE_INFO *create_info,
492 handler *file, const char *part_name,
493 partition_element *p_elem,
494 uint disable_non_uniq_indexes);
495 /*
496 delete_table and rename_table uses very similar logic which
497 is packed into this routine.
498 */
499 uint del_ren_table(const char *from, const char *to);
500 /*
501 One method to create the table_name.par file containing the names of the
502 underlying partitions, their engine and the number of partitions.
503 And one method to read it in.
504 */
505 bool create_handler_file(const char *name);
506 bool setup_engine_array(MEM_ROOT *mem_root);
507 bool read_par_file(const char *name);
508 bool get_from_handler_file(const char *name, MEM_ROOT *mem_root,
509 bool is_clone);
510 bool new_handlers_from_part_info(MEM_ROOT *mem_root);
511 bool create_handlers(MEM_ROOT *mem_root);
512 void clear_handler_file();
513 int set_up_table_before_create(TABLE *table_arg,
514 const char *partition_name_with_path,
515 HA_CREATE_INFO *info,
516 partition_element *p_elem);
517 partition_element *find_partition_element(uint part_id);
518 bool insert_partition_name_in_hash(const char *name, uint part_id,
519 bool is_subpart);
520 bool populate_partition_name_hash();
521 Partition_share *get_share();
522 bool set_ha_share_ref(Handler_share **ha_share);
523 void fix_data_dir(char* path);
524 bool init_partition_bitmaps();
525 void free_partition_bitmaps();
526
527public:
528
529 /*
530 -------------------------------------------------------------------------
531 MODULE open/close object
532 -------------------------------------------------------------------------
533 Open and close handler object to ensure all underlying files and
534 objects allocated and deallocated for query handling is handled
535 properly.
536 -------------------------------------------------------------------------
537
538 A handler object is opened as part of its initialisation and before
539 being used for normal queries (not before meta-data changes always.
540 If the object was opened it will also be closed before being deleted.
541 */
542 virtual int open(const char *name, int mode, uint test_if_locked);
543 virtual int close(void);
544
545 /*
546 -------------------------------------------------------------------------
547 MODULE start/end statement
548 -------------------------------------------------------------------------
549 This module contains methods that are used to understand start/end of
550 statements, transaction boundaries, and aid for proper concurrency
551 control.
552 The partition handler need not implement abort and commit since this
553 will be handled by any underlying handlers implementing transactions.
554 There is only one call to each handler type involved per transaction
555 and these go directly to the handlers supporting transactions
556 -------------------------------------------------------------------------
557 */
558 virtual THR_LOCK_DATA **store_lock(THD * thd, THR_LOCK_DATA ** to,
559 enum thr_lock_type lock_type);
560 virtual int external_lock(THD * thd, int lock_type);
561 LEX_CSTRING *engine_name() { return hton_name(partition_ht()); }
562 /*
563 When table is locked a statement is started by calling start_stmt
564 instead of external_lock
565 */
566 virtual int start_stmt(THD * thd, thr_lock_type lock_type);
567 /*
568 Lock count is number of locked underlying handlers (I assume)
569 */
570 virtual uint lock_count(void) const;
571 /*
572 Call to unlock rows not to be updated in transaction
573 */
574 virtual void unlock_row();
575 /*
576 Check if semi consistent read
577 */
578 virtual bool was_semi_consistent_read();
579 /*
580 Call to hint about semi consistent read
581 */
582 virtual void try_semi_consistent_read(bool);
583
584 /*
585 NOTE: due to performance and resource issues with many partitions,
586 we only use the m_psi on the ha_partition handler, excluding all
587 partitions m_psi.
588 */
589#ifdef HAVE_M_PSI_PER_PARTITION
590 /*
591 Bind the table/handler thread to track table i/o.
592 */
593 virtual void unbind_psi();
594 virtual void rebind_psi();
595#endif
596 /*
597 -------------------------------------------------------------------------
598 MODULE change record
599 -------------------------------------------------------------------------
600 This part of the handler interface is used to change the records
601 after INSERT, DELETE, UPDATE, REPLACE method calls but also other
602 special meta-data operations as ALTER TABLE, LOAD DATA, TRUNCATE.
603 -------------------------------------------------------------------------
604
605 These methods are used for insert (write_row), update (update_row)
606 and delete (delete_row). All methods to change data always work on
607 one row at a time. update_row and delete_row also contains the old
608 row.
609 delete_all_rows will delete all rows in the table in one call as a
610 special optimisation for DELETE from table;
611
612 Bulk inserts are supported if all underlying handlers support it.
613 start_bulk_insert and end_bulk_insert is called before and after a
614 number of calls to write_row.
615 */
616 virtual int write_row(uchar * buf);
617 virtual bool start_bulk_update();
618 virtual int exec_bulk_update(ha_rows *dup_key_found);
619 virtual int end_bulk_update();
620 virtual int bulk_update_row(const uchar *old_data, const uchar *new_data,
621 ha_rows *dup_key_found);
622 virtual int update_row(const uchar * old_data, const uchar * new_data);
623 virtual int direct_update_rows_init();
624 virtual int pre_direct_update_rows_init();
625 virtual int direct_update_rows(ha_rows *update_rows);
626 virtual int pre_direct_update_rows();
627 virtual bool start_bulk_delete();
628 virtual int end_bulk_delete();
629 virtual int delete_row(const uchar * buf);
630 virtual int direct_delete_rows_init();
631 virtual int pre_direct_delete_rows_init();
632 virtual int direct_delete_rows(ha_rows *delete_rows);
633 virtual int pre_direct_delete_rows();
634 virtual int delete_all_rows(void);
635 virtual int truncate();
636 virtual void start_bulk_insert(ha_rows rows, uint flags);
637 virtual int end_bulk_insert();
638private:
639 ha_rows guess_bulk_insert_rows();
640 void start_part_bulk_insert(THD *thd, uint part_id);
641 long estimate_read_buffer_size(long original_size);
642public:
643
644 /*
645 Method for truncating a specific partition.
646 (i.e. ALTER TABLE t1 TRUNCATE PARTITION p).
647
648 @remark This method is a partitioning-specific hook
649 and thus not a member of the general SE API.
650 */
651 int truncate_partition(Alter_info *, bool *binlog_stmt);
652
653 virtual bool is_fatal_error(int error, uint flags)
654 {
655 if (!handler::is_fatal_error(error, flags) ||
656 error == HA_ERR_NO_PARTITION_FOUND ||
657 error == HA_ERR_NOT_IN_LOCK_PARTITIONS)
658 return FALSE;
659 return TRUE;
660 }
661
662
663 /*
664 -------------------------------------------------------------------------
665 MODULE full table scan
666 -------------------------------------------------------------------------
667 This module is used for the most basic access method for any table
668 handler. This is to fetch all data through a full table scan. No
669 indexes are needed to implement this part.
670 It contains one method to start the scan (rnd_init) that can also be
671 called multiple times (typical in a nested loop join). Then proceeding
672 to the next record (rnd_next) and closing the scan (rnd_end).
673 To remember a record for later access there is a method (position)
674 and there is a method used to retrieve the record based on the stored
675 position.
676 The position can be a file position, a primary key, a ROWID dependent
677 on the handler below.
678 -------------------------------------------------------------------------
679 */
680 /*
681 unlike index_init(), rnd_init() can be called two times
682 without rnd_end() in between (it only makes sense if scan=1).
683 then the second call should prepare for the new table scan
684 (e.g if rnd_init allocates the cursor, second call should
685 position it to the start of the table, no need to deallocate
686 and allocate it again
687 */
688 virtual int rnd_init(bool scan);
689 virtual int rnd_end();
690 virtual int rnd_next(uchar * buf);
691 virtual int rnd_pos(uchar * buf, uchar * pos);
692 virtual int rnd_pos_by_record(uchar *record);
693 virtual void position(const uchar * record);
694
695 /*
696 -------------------------------------------------------------------------
697 MODULE index scan
698 -------------------------------------------------------------------------
699 This part of the handler interface is used to perform access through
700 indexes. The interface is defined as a scan interface but the handler
701 can also use key lookup if the index is a unique index or a primary
702 key index.
703 Index scans are mostly useful for SELECT queries but are an important
704 part also of UPDATE, DELETE, REPLACE and CREATE TABLE table AS SELECT
705 and so forth.
706 Naturally an index is needed for an index scan and indexes can either
707 be ordered, hash based. Some ordered indexes can return data in order
708 but not necessarily all of them.
709 There are many flags that define the behavior of indexes in the
710 various handlers. These methods are found in the optimizer module.
711 -------------------------------------------------------------------------
712
713 index_read is called to start a scan of an index. The find_flag defines
714 the semantics of the scan. These flags are defined in
715 include/my_base.h
716 index_read_idx is the same but also initializes index before calling doing
717 the same thing as index_read. Thus it is similar to index_init followed
718 by index_read. This is also how we implement it.
719
720 index_read/index_read_idx does also return the first row. Thus for
721 key lookups, the index_read will be the only call to the handler in
722 the index scan.
723
724 index_init initializes an index before using it and index_end does
725 any end processing needed.
726 */
727 virtual int index_read_map(uchar * buf, const uchar * key,
728 key_part_map keypart_map,
729 enum ha_rkey_function find_flag);
730 virtual int index_init(uint idx, bool sorted);
731 virtual int index_end();
732
733 /**
734 @breif
735 Positions an index cursor to the index specified in the hanlde. Fetches the
736 row if available. If the key value is null, begin at first key of the
737 index.
738 */
739 virtual int index_read_idx_map(uchar *buf, uint index, const uchar *key,
740 key_part_map keypart_map,
741 enum ha_rkey_function find_flag);
742 /*
743 These methods are used to jump to next or previous entry in the index
744 scan. There are also methods to jump to first and last entry.
745 */
746 virtual int index_next(uchar * buf);
747 virtual int index_prev(uchar * buf);
748 virtual int index_first(uchar * buf);
749 virtual int index_last(uchar * buf);
750 virtual int index_next_same(uchar * buf, const uchar * key, uint keylen);
751
752 int index_read_last_map(uchar *buf,
753 const uchar *key,
754 key_part_map keypart_map);
755
756 /*
757 read_first_row is virtual method but is only implemented by
758 handler.cc, no storage engine has implemented it so neither
759 will the partition handler.
760
761 virtual int read_first_row(uchar *buf, uint primary_key);
762 */
763
764
765 virtual int read_range_first(const key_range * start_key,
766 const key_range * end_key,
767 bool eq_range, bool sorted);
768 virtual int read_range_next();
769
770
771 HANDLER_BUFFER *m_mrr_buffer;
772 uint *m_mrr_buffer_size;
773 uchar *m_mrr_full_buffer;
774 uint m_mrr_full_buffer_size;
775 uint m_mrr_new_full_buffer_size;
776 MY_BITMAP m_mrr_used_partitions;
777 uint *m_stock_range_seq;
778 uint m_current_range_seq;
779 uint m_mrr_mode;
780 uint m_mrr_n_ranges;
781 range_id_t *m_range_info;
782 bool m_multi_range_read_first;
783 uint m_mrr_range_init_flags;
784 uint m_mrr_range_length;
785 PARTITION_KEY_MULTI_RANGE *m_mrr_range_first;
786 PARTITION_KEY_MULTI_RANGE *m_mrr_range_current;
787 uint *m_part_mrr_range_length;
788 PARTITION_PART_KEY_MULTI_RANGE **m_part_mrr_range_first;
789 PARTITION_PART_KEY_MULTI_RANGE **m_part_mrr_range_current;
790 PARTITION_PART_KEY_MULTI_RANGE_HLD *m_partition_part_key_multi_range_hld;
791 range_seq_t m_seq;
792 RANGE_SEQ_IF *m_seq_if;
793 RANGE_SEQ_IF m_part_seq_if;
794
795 virtual int multi_range_key_create_key(
796 RANGE_SEQ_IF *seq,
797 range_seq_t seq_it
798 );
799 virtual ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
800 void *seq_init_param,
801 uint n_ranges, uint *bufsz,
802 uint *mrr_mode,
803 Cost_estimate *cost);
804 virtual ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
805 uint key_parts, uint *bufsz,
806 uint *mrr_mode, Cost_estimate *cost);
807 virtual int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
808 uint n_ranges, uint mrr_mode,
809 HANDLER_BUFFER *buf);
810 virtual int multi_range_read_next(range_id_t *range_info);
811 virtual int multi_range_read_explain_info(uint mrr_mode, char *str,
812 size_t size);
813 uint last_part() { return m_last_part; }
814
815private:
816 bool init_record_priority_queue();
817 void destroy_record_priority_queue();
818 int common_index_read(uchar * buf, bool have_start_key);
819 int common_first_last(uchar * buf);
820 int partition_scan_set_up(uchar * buf, bool idx_read_flag);
821 bool check_parallel_search();
822 int handle_pre_scan(bool reverse_order, bool use_parallel);
823 int handle_unordered_next(uchar * buf, bool next_same);
824 int handle_unordered_scan_next_partition(uchar * buf);
825 int handle_ordered_index_scan(uchar * buf, bool reverse_order);
826 int handle_ordered_index_scan_key_not_found();
827 int handle_ordered_next(uchar * buf, bool next_same);
828 int handle_ordered_prev(uchar * buf);
829 void return_top_record(uchar * buf);
830public:
831 /*
832 -------------------------------------------------------------------------
833 MODULE information calls
834 -------------------------------------------------------------------------
835 This calls are used to inform the handler of specifics of the ongoing
836 scans and other actions. Most of these are used for optimisation
837 purposes.
838 -------------------------------------------------------------------------
839 */
840 virtual int info(uint);
841 void get_dynamic_partition_info(PARTITION_STATS *stat_info,
842 uint part_id);
843 void set_partitions_to_open(List<String> *partition_names);
844 int change_partitions_to_open(List<String> *partition_names);
845 int open_read_partitions(char *name_buff, size_t name_buff_size);
846 virtual int extra(enum ha_extra_function operation);
847 virtual int extra_opt(enum ha_extra_function operation, ulong cachesize);
848 virtual int reset(void);
849 virtual uint count_query_cache_dependant_tables(uint8 *tables_type);
850 virtual my_bool
851 register_query_cache_dependant_tables(THD *thd,
852 Query_cache *cache,
853 Query_cache_block_table **block,
854 uint *n);
855
856private:
857 my_bool reg_query_cache_dependant_table(THD *thd,
858 char *engine_key,
859 uint engine_key_len,
860 char *query_key, uint query_key_len,
861 uint8 type,
862 Query_cache *cache,
863 Query_cache_block_table
864 **block_table,
865 handler *file, uint *n);
866 static const uint NO_CURRENT_PART_ID= NOT_A_PARTITION_ID;
867 int loop_extra(enum ha_extra_function operation);
868 int loop_extra_alter(enum ha_extra_function operations);
869 void late_extra_cache(uint partition_id);
870 void late_extra_no_cache(uint partition_id);
871 void prepare_extra_cache(uint cachesize);
872 handler *get_open_file_sample() const { return m_file_sample; }
873public:
874
875 /*
876 -------------------------------------------------------------------------
877 MODULE optimiser support
878 -------------------------------------------------------------------------
879 -------------------------------------------------------------------------
880 */
881
882 /*
883 NOTE !!!!!!
884 -------------------------------------------------------------------------
885 -------------------------------------------------------------------------
886 One important part of the public handler interface that is not depicted in
887 the methods is the attribute records
888
889 which is defined in the base class. This is looked upon directly and is
890 set by calling info(HA_STATUS_INFO) ?
891 -------------------------------------------------------------------------
892 */
893
894private:
895 /* Helper functions for optimizer hints. */
896 ha_rows min_rows_for_estimate();
897 uint get_biggest_used_partition(uint *part_index);
898public:
899
900 /*
901 keys_to_use_for_scanning can probably be implemented as the
902 intersection of all underlying handlers if mixed handlers are used.
903 This method is used to derive whether an index can be used for
904 index-only scanning when performing an ORDER BY query.
905 Only called from one place in sql_select.cc
906 */
907 virtual const key_map *keys_to_use_for_scanning();
908
909 /*
910 Called in test_quick_select to determine if indexes should be used.
911 */
912 virtual double scan_time();
913
914 /*
915 The next method will never be called if you do not implement indexes.
916 */
917 virtual double read_time(uint index, uint ranges, ha_rows rows);
918 /*
919 For the given range how many records are estimated to be in this range.
920 Used by optimiser to calculate cost of using a particular index.
921 */
922 virtual ha_rows records_in_range(uint inx, key_range * min_key,
923 key_range * max_key);
924
925 /*
926 Upper bound of number records returned in scan is sum of all
927 underlying handlers.
928 */
929 virtual ha_rows estimate_rows_upper_bound();
930
931 /*
932 table_cache_type is implemented by the underlying handler but all
933 underlying handlers must have the same implementation for it to work.
934 */
935 virtual uint8 table_cache_type();
936 virtual ha_rows records();
937
938 /* Calculate hash value for PARTITION BY KEY tables. */
939 static uint32 calculate_key_hash_value(Field **field_array);
940
941 /*
942 -------------------------------------------------------------------------
943 MODULE print messages
944 -------------------------------------------------------------------------
945 This module contains various methods that returns text messages for
946 table types, index type and error messages.
947 -------------------------------------------------------------------------
948 */
949 /*
950 The name of the index type that will be used for display
951 Here we must ensure that all handlers use the same index type
952 for each index created.
953 */
954 virtual const char *index_type(uint inx);
955
956 /* The name of the table type that will be used for display purposes */
957 virtual const char *table_type() const;
958
959 /* The name of the row type used for the underlying tables. */
960 virtual enum row_type get_row_type() const;
961
962 /*
963 Handler specific error messages
964 */
965 virtual void print_error(int error, myf errflag);
966 virtual bool get_error_message(int error, String * buf);
967 /*
968 -------------------------------------------------------------------------
969 MODULE handler characteristics
970 -------------------------------------------------------------------------
971 This module contains a number of methods defining limitations and
972 characteristics of the handler. The partition handler will calculate
973 this characteristics based on underlying handler characteristics.
974 -------------------------------------------------------------------------
975
976 This is a list of flags that says what the storage engine
977 implements. The current table flags are documented in handler.h
978 The partition handler will support whatever the underlying handlers
979 support except when specifically mentioned below about exceptions
980 to this rule.
981 NOTE: This cannot be cached since it can depend on TRANSACTION ISOLATION
982 LEVEL which is dynamic, see bug#39084.
983
984 HA_READ_RND_SAME:
985 Not currently used. (Means that the handler supports the rnd_same() call)
986 (MyISAM, HEAP)
987
988 HA_TABLE_SCAN_ON_INDEX:
989 Used to avoid scanning full tables on an index. If this flag is set then
990 the handler always has a primary key (hidden if not defined) and this
991 index is used for scanning rather than a full table scan in all
992 situations.
993 (InnoDB, Federated)
994
995 HA_REC_NOT_IN_SEQ:
996 This flag is set for handlers that cannot guarantee that the rows are
997 returned accroding to incremental positions (0, 1, 2, 3...).
998 This also means that rnd_next() should return HA_ERR_RECORD_DELETED
999 if it finds a deleted row.
1000 (MyISAM (not fixed length row), HEAP, InnoDB)
1001
1002 HA_CAN_GEOMETRY:
1003 Can the storage engine handle spatial data.
1004 Used to check that no spatial attributes are declared unless
1005 the storage engine is capable of handling it.
1006 (MyISAM)
1007
1008 HA_FAST_KEY_READ:
1009 Setting this flag indicates that the handler is equally fast in
1010 finding a row by key as by position.
1011 This flag is used in a very special situation in conjunction with
1012 filesort's. For further explanation see intro to init_read_record.
1013 (HEAP, InnoDB)
1014
1015 HA_NULL_IN_KEY:
1016 Is NULL values allowed in indexes.
1017 If this is not allowed then it is not possible to use an index on a
1018 NULLable field.
1019 (HEAP, MyISAM, InnoDB)
1020
1021 HA_DUPLICATE_POS:
1022 Tells that we can the position for the conflicting duplicate key
1023 record is stored in table->file->dupp_ref. (insert uses rnd_pos() on
1024 this to find the duplicated row)
1025 (MyISAM)
1026
1027 HA_CAN_INDEX_BLOBS:
1028 Is the storage engine capable of defining an index of a prefix on
1029 a BLOB attribute.
1030 (Federated, MyISAM, InnoDB)
1031
1032 HA_AUTO_PART_KEY:
1033 Auto increment fields can be part of a multi-part key. For second part
1034 auto-increment keys, the auto_incrementing is done in handler.cc
1035 (Federated, MyISAM)
1036
1037 HA_REQUIRE_PRIMARY_KEY:
1038 Can't define a table without primary key (and cannot handle a table
1039 with hidden primary key)
1040 (No handler has this limitation currently)
1041
1042 HA_STATS_RECORDS_IS_EXACT:
1043 Does the counter of records after the info call specify an exact
1044 value or not. If it does this flag is set.
1045 Only MyISAM and HEAP uses exact count.
1046
1047 HA_CAN_INSERT_DELAYED:
1048 Can the storage engine support delayed inserts.
1049 To start with the partition handler will not support delayed inserts.
1050 Further investigation needed.
1051 (HEAP, MyISAM)
1052
1053 HA_PRIMARY_KEY_IN_READ_INDEX:
1054 This parameter is set when the handler will also return the primary key
1055 when doing read-only-key on another index.
1056
1057 HA_NOT_DELETE_WITH_CACHE:
1058 Seems to be an old MyISAM feature that is no longer used. No handler
1059 has it defined but it is checked in init_read_record.
1060 Further investigation needed.
1061 (No handler defines it)
1062
1063 HA_NO_PREFIX_CHAR_KEYS:
1064 Indexes on prefixes of character fields is not allowed.
1065 (Federated)
1066
1067 HA_CAN_FULLTEXT:
1068 Does the storage engine support fulltext indexes
1069 The partition handler will start by not supporting fulltext indexes.
1070 (MyISAM)
1071
1072 HA_CAN_SQL_HANDLER:
1073 Can the HANDLER interface in the MySQL API be used towards this
1074 storage engine.
1075 (MyISAM, InnoDB)
1076
1077 HA_NO_AUTO_INCREMENT:
1078 Set if the storage engine does not support auto increment fields.
1079 (Currently not set by any handler)
1080
1081 HA_HAS_CHECKSUM:
1082 Special MyISAM feature. Has special SQL support in CREATE TABLE.
1083 No special handling needed by partition handler.
1084 (MyISAM)
1085
1086 HA_FILE_BASED:
1087 Should file names always be in lower case (used by engines
1088 that map table names to file names.
1089 Since partition handler has a local file this flag is set.
1090 (Federated, MyISAM)
1091
1092 HA_CAN_BIT_FIELD:
1093 Is the storage engine capable of handling bit fields?
1094 (MyISAM)
1095
1096 HA_NEED_READ_RANGE_BUFFER:
1097 Is Read Multi-Range supported => need multi read range buffer
1098 This parameter specifies whether a buffer for read multi range
1099 is needed by the handler. Whether the handler supports this
1100 feature or not is dependent of whether the handler implements
1101 read_multi_range* calls or not. The only handler currently
1102 supporting this feature is NDB so the partition handler need
1103 not handle this call. There are methods in handler.cc that will
1104 transfer those calls into index_read and other calls in the
1105 index scan module.
1106 (No handler defines it)
1107
1108 HA_PRIMARY_KEY_REQUIRED_FOR_POSITION:
1109 Does the storage engine need a PK for position?
1110 (InnoDB)
1111
1112 HA_FILE_BASED is always set for partition handler since we use a
1113 special file for handling names of partitions, engine types.
1114 HA_REC_NOT_IN_SEQ is always set for partition handler since we cannot
1115 guarantee that the records will be returned in sequence.
1116 HA_DUPLICATE_POS,
1117 HA_CAN_INSERT_DELAYED, HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is disabled
1118 until further investigated.
1119 */
1120 virtual Table_flags table_flags() const;
1121
1122 /*
1123 This is a bitmap of flags that says how the storage engine
1124 implements indexes. The current index flags are documented in
1125 handler.h. If you do not implement indexes, just return zero
1126 here.
1127
1128 part is the key part to check. First key part is 0
1129 If all_parts it's set, MySQL want to know the flags for the combined
1130 index up to and including 'part'.
1131
1132 HA_READ_NEXT:
1133 Does the index support read next, this is assumed in the server
1134 code and never checked so all indexes must support this.
1135 Note that the handler can be used even if it doesn't have any index.
1136 (HEAP, MyISAM, Federated, InnoDB)
1137
1138 HA_READ_PREV:
1139 Can the index be used to scan backwards.
1140 (HEAP, MyISAM, InnoDB)
1141
1142 HA_READ_ORDER:
1143 Can the index deliver its record in index order. Typically true for
1144 all ordered indexes and not true for hash indexes.
1145 In first step this is not true for partition handler until a merge
1146 sort has been implemented in partition handler.
1147 Used to set keymap part_of_sortkey
1148 This keymap is only used to find indexes usable for resolving an ORDER BY
1149 in the query. Thus in most cases index_read will work just fine without
1150 order in result production. When this flag is set it is however safe to
1151 order all output started by index_read since most engines do this. With
1152 read_multi_range calls there is a specific flag setting order or not
1153 order so in those cases ordering of index output can be avoided.
1154 (InnoDB, HEAP, MyISAM)
1155
1156 HA_READ_RANGE:
1157 Specify whether index can handle ranges, typically true for all
1158 ordered indexes and not true for hash indexes.
1159 Used by optimiser to check if ranges (as key >= 5) can be optimised
1160 by index.
1161 (InnoDB, MyISAM, HEAP)
1162
1163 HA_ONLY_WHOLE_INDEX:
1164 Can't use part key searches. This is typically true for hash indexes
1165 and typically not true for ordered indexes.
1166 (Federated, HEAP)
1167
1168 HA_KEYREAD_ONLY:
1169 Does the storage engine support index-only scans on this index.
1170 Enables use of HA_EXTRA_KEYREAD and HA_EXTRA_NO_KEYREAD
1171 Used to set key_map keys_for_keyread and to check in optimiser for
1172 index-only scans. When doing a read under HA_EXTRA_KEYREAD the handler
1173 only have to fill in the columns the key covers. If
1174 HA_PRIMARY_KEY_IN_READ_INDEX is set then also the PRIMARY KEY columns
1175 must be updated in the row.
1176 (InnoDB, MyISAM)
1177 */
1178 virtual ulong index_flags(uint inx, uint part, bool all_parts) const
1179 {
1180 /*
1181 The following code is not safe if you are using different
1182 storage engines or different index types per partition.
1183 */
1184 return m_file[0]->index_flags(inx, part, all_parts);
1185 }
1186
1187 /**
1188 wrapper function for handlerton alter_table_flags, since
1189 the ha_partition_hton cannot know all its capabilities
1190 */
1191 virtual alter_table_operations alter_table_flags(alter_table_operations flags);
1192 /*
1193 unireg.cc will call the following to make sure that the storage engine
1194 can handle the data it is about to send.
1195
1196 The maximum supported values is the minimum of all handlers in the table
1197 */
1198 uint min_of_the_max_uint(uint (handler::*operator_func)(void) const) const;
1199 virtual uint max_supported_record_length() const;
1200 virtual uint max_supported_keys() const;
1201 virtual uint max_supported_key_parts() const;
1202 virtual uint max_supported_key_length() const;
1203 virtual uint max_supported_key_part_length() const;
1204 virtual uint min_record_length(uint options) const;
1205
1206 /*
1207 Primary key is clustered can only be true if all underlying handlers have
1208 this feature.
1209 */
1210 virtual bool primary_key_is_clustered()
1211 { return m_pkey_is_clustered; }
1212
1213 /*
1214 -------------------------------------------------------------------------
1215 MODULE compare records
1216 -------------------------------------------------------------------------
1217 cmp_ref checks if two references are the same. For most handlers this is
1218 a simple memcmp of the reference. However some handlers use primary key
1219 as reference and this can be the same even if memcmp says they are
1220 different. This is due to character sets and end spaces and so forth.
1221 For the partition handler the reference is first two bytes providing the
1222 partition identity of the referred record and then the reference of the
1223 underlying handler.
1224 Thus cmp_ref for the partition handler always returns FALSE for records
1225 not in the same partition and uses cmp_ref on the underlying handler
1226 to check whether the rest of the reference part is also the same.
1227 -------------------------------------------------------------------------
1228 */
1229 virtual int cmp_ref(const uchar * ref1, const uchar * ref2);
1230 /*
1231 -------------------------------------------------------------------------
1232 MODULE auto increment
1233 -------------------------------------------------------------------------
1234 This module is used to handle the support of auto increments.
1235
1236 This variable in the handler is used as part of the handler interface
1237 It is maintained by the parent handler object and should not be
1238 touched by child handler objects (see handler.cc for its use).
1239
1240 auto_increment_column_changed
1241 -------------------------------------------------------------------------
1242 */
1243 virtual bool need_info_for_auto_inc();
1244 virtual bool can_use_for_auto_inc_init();
1245 virtual void get_auto_increment(ulonglong offset, ulonglong increment,
1246 ulonglong nb_desired_values,
1247 ulonglong *first_value,
1248 ulonglong *nb_reserved_values);
1249 virtual void release_auto_increment();
1250private:
1251 virtual int reset_auto_increment(ulonglong value);
1252 void update_next_auto_inc_val();
1253 virtual void lock_auto_increment()
1254 {
1255 /* lock already taken */
1256 if (auto_increment_safe_stmt_log_lock)
1257 return;
1258 if (table_share->tmp_table == NO_TMP_TABLE)
1259 {
1260 part_share->lock_auto_inc();
1261 DBUG_ASSERT(!auto_increment_lock);
1262 auto_increment_lock= TRUE;
1263 }
1264 }
1265 virtual void unlock_auto_increment()
1266 {
1267 /*
1268 If auto_increment_safe_stmt_log_lock is true, we have to keep the lock.
1269 It will be set to false and thus unlocked at the end of the statement by
1270 ha_partition::release_auto_increment.
1271 */
1272 if (auto_increment_lock && !auto_increment_safe_stmt_log_lock)
1273 {
1274 auto_increment_lock= FALSE;
1275 part_share->unlock_auto_inc();
1276 }
1277 }
1278 virtual void set_auto_increment_if_higher(Field *field)
1279 {
1280 ulonglong nr= (((Field_num*) field)->unsigned_flag ||
1281 field->val_int() > 0) ? field->val_int() : 0;
1282 lock_auto_increment();
1283 DBUG_ASSERT(part_share->auto_inc_initialized ||
1284 !can_use_for_auto_inc_init());
1285 /* must check when the mutex is taken */
1286 if (nr >= part_share->next_auto_inc_val)
1287 part_share->next_auto_inc_val= nr + 1;
1288 unlock_auto_increment();
1289 }
1290
1291public:
1292
1293 /*
1294 -------------------------------------------------------------------------
1295 MODULE initialize handler for HANDLER call
1296 -------------------------------------------------------------------------
1297 This method is a special InnoDB method called before a HANDLER query.
1298 -------------------------------------------------------------------------
1299 */
1300 virtual void init_table_handle_for_HANDLER();
1301
1302 /*
1303 The remainder of this file defines the handler methods not implemented
1304 by the partition handler
1305 */
1306
1307 /*
1308 -------------------------------------------------------------------------
1309 MODULE foreign key support
1310 -------------------------------------------------------------------------
1311 The following methods are used to implement foreign keys as supported by
1312 InnoDB. Implement this ??
1313 get_foreign_key_create_info is used by SHOW CREATE TABLE to get a textual
1314 description of how the CREATE TABLE part to define FOREIGN KEY's is done.
1315 free_foreign_key_create_info is used to free the memory area that provided
1316 this description.
1317 can_switch_engines checks if it is ok to switch to a new engine based on
1318 the foreign key info in the table.
1319 -------------------------------------------------------------------------
1320
1321 virtual char* get_foreign_key_create_info()
1322 virtual void free_foreign_key_create_info(char* str)
1323
1324 virtual int get_foreign_key_list(THD *thd,
1325 List<FOREIGN_KEY_INFO> *f_key_list)
1326 virtual uint referenced_by_foreign_key()
1327 */
1328 virtual bool can_switch_engines();
1329 /*
1330 -------------------------------------------------------------------------
1331 MODULE fulltext index
1332 -------------------------------------------------------------------------
1333 */
1334 void ft_close_search(FT_INFO *handler);
1335 virtual int ft_init();
1336 virtual int pre_ft_init();
1337 virtual void ft_end();
1338 virtual int pre_ft_end();
1339 virtual FT_INFO *ft_init_ext(uint flags, uint inx, String *key);
1340 virtual int ft_read(uchar *buf);
1341 virtual int pre_ft_read(bool use_parallel);
1342
1343 /*
1344 -------------------------------------------------------------------------
1345 MODULE restart full table scan at position (MyISAM)
1346 -------------------------------------------------------------------------
1347 The following method is only used by MyISAM when used as
1348 temporary tables in a join.
1349 virtual int restart_rnd_next(uchar *buf, uchar *pos);
1350 */
1351
1352 /*
1353 -------------------------------------------------------------------------
1354 MODULE in-place ALTER TABLE
1355 -------------------------------------------------------------------------
1356 These methods are in the handler interface. (used by innodb-plugin)
1357 They are used for in-place alter table:
1358 -------------------------------------------------------------------------
1359 */
1360 virtual enum_alter_inplace_result
1361 check_if_supported_inplace_alter(TABLE *altered_table,
1362 Alter_inplace_info *ha_alter_info);
1363 virtual bool prepare_inplace_alter_table(TABLE *altered_table,
1364 Alter_inplace_info *ha_alter_info);
1365 virtual bool inplace_alter_table(TABLE *altered_table,
1366 Alter_inplace_info *ha_alter_info);
1367 virtual bool commit_inplace_alter_table(TABLE *altered_table,
1368 Alter_inplace_info *ha_alter_info,
1369 bool commit);
1370 virtual void notify_table_changed();
1371
1372 /*
1373 -------------------------------------------------------------------------
1374 MODULE tablespace support
1375 -------------------------------------------------------------------------
1376 Admin of table spaces is not applicable to the partition handler (InnoDB)
1377 This means that the following method is not implemented:
1378 -------------------------------------------------------------------------
1379 virtual int discard_or_import_tablespace(my_bool discard)
1380 */
1381
1382 /*
1383 -------------------------------------------------------------------------
1384 MODULE admin MyISAM
1385 -------------------------------------------------------------------------
1386
1387 -------------------------------------------------------------------------
1388 OPTIMIZE TABLE, CHECK TABLE, ANALYZE TABLE and REPAIR TABLE are
1389 mapped to a routine that handles looping over a given set of
1390 partitions and those routines send a flag indicating to execute on
1391 all partitions.
1392 -------------------------------------------------------------------------
1393 */
1394 virtual int optimize(THD* thd, HA_CHECK_OPT *check_opt);
1395 virtual int analyze(THD* thd, HA_CHECK_OPT *check_opt);
1396 virtual int check(THD* thd, HA_CHECK_OPT *check_opt);
1397 virtual int repair(THD* thd, HA_CHECK_OPT *check_opt);
1398 virtual bool check_and_repair(THD *thd);
1399 virtual bool auto_repair(int error) const;
1400 virtual bool is_crashed() const;
1401 virtual int check_for_upgrade(HA_CHECK_OPT *check_opt);
1402
1403 /*
1404 -------------------------------------------------------------------------
1405 MODULE condition pushdown
1406 -------------------------------------------------------------------------
1407 */
1408 virtual const COND *cond_push(const COND *cond);
1409 virtual void cond_pop();
1410 virtual void clear_top_table_fields();
1411 virtual int info_push(uint info_type, void *info);
1412
1413 private:
1414 int handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt, uint flags);
1415 int handle_opt_part(THD *thd, HA_CHECK_OPT *check_opt, uint part_id,
1416 uint flag);
1417 /**
1418 Check if the rows are placed in the correct partition. If the given
1419 argument is true, then move the rows to the correct partition.
1420 */
1421 int check_misplaced_rows(uint read_part_id, bool repair);
1422 void append_row_to_str(String &str);
1423 public:
1424
1425 /*
1426 -------------------------------------------------------------------------
1427 Admin commands not supported currently (almost purely MyISAM routines)
1428 This means that the following methods are not implemented:
1429 -------------------------------------------------------------------------
1430
1431 virtual int backup(TD* thd, HA_CHECK_OPT *check_opt);
1432 virtual int restore(THD* thd, HA_CHECK_OPT *check_opt);
1433 virtual int dump(THD* thd, int fd = -1);
1434 virtual int net_read_dump(NET* net);
1435 */
1436 virtual uint checksum() const;
1437 /* Enabled keycache for performance reasons, WL#4571 */
1438 virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt);
1439 virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt);
1440 virtual TABLE_LIST *get_next_global_for_child();
1441
1442 /*
1443 -------------------------------------------------------------------------
1444 MODULE enable/disable indexes
1445 -------------------------------------------------------------------------
1446 Enable/Disable Indexes are only supported by HEAP and MyISAM.
1447 -------------------------------------------------------------------------
1448 */
1449 virtual int disable_indexes(uint mode);
1450 virtual int enable_indexes(uint mode);
1451 virtual int indexes_are_disabled(void);
1452
1453 /*
1454 -------------------------------------------------------------------------
1455 MODULE append_create_info
1456 -------------------------------------------------------------------------
1457 append_create_info is only used by MyISAM MERGE tables and the partition
1458 handler will not support this handler as underlying handler.
1459 Implement this??
1460 -------------------------------------------------------------------------
1461 virtual void append_create_info(String *packet)
1462 */
1463
1464 /*
1465 the following heavily relies on the fact that all partitions
1466 are in the same storage engine.
1467
1468 When this limitation is lifted, the following hack should go away,
1469 and a proper interface for engines needs to be introduced:
1470
1471 an PARTITION_SHARE structure that has a pointer to the TABLE_SHARE.
1472 is given to engines everywhere where TABLE_SHARE is used now
1473 has members like option_struct, ha_data
1474 perhaps TABLE needs to be split the same way too...
1475
1476 this can also be done before partition will support a mix of engines,
1477 but preferably together with other incompatible API changes.
1478 */
1479 virtual handlerton *partition_ht() const
1480 {
1481 handlerton *h= m_file[0]->ht;
1482 for (uint i=1; i < m_tot_parts; i++)
1483 DBUG_ASSERT(h == m_file[i]->ht);
1484 return h;
1485 }
1486
1487 ha_rows part_records(void *_part_elem)
1488 {
1489 partition_element *part_elem= reinterpret_cast<partition_element *>(_part_elem);
1490 DBUG_ASSERT(m_part_info);
1491 uint32 sub_factor= m_part_info->num_subparts ? m_part_info->num_subparts : 1;
1492 uint32 part_id= part_elem->id * sub_factor;
1493 uint32 part_id_end= part_id + sub_factor;
1494 DBUG_ASSERT(part_id_end <= m_tot_parts);
1495 ha_rows part_recs= 0;
1496 for (; part_id < part_id_end; ++part_id)
1497 {
1498 handler *file= m_file[part_id];
1499 DBUG_ASSERT(bitmap_is_set(&(m_part_info->read_partitions), part_id));
1500 file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_OPEN);
1501 part_recs+= file->stats.records;
1502 }
1503 return part_recs;
1504 }
1505
1506 friend int cmp_key_rowid_part_id(void *ptr, uchar *ref1, uchar *ref2);
1507 friend int cmp_key_part_id(void *key_p, uchar *ref1, uchar *ref2);
1508};
1509#endif /* HA_PARTITION_INCLUDED */
1510