1 #ifndef SQL_JOIN_CACHE_INCLUDED
2 #define SQL_JOIN_CACHE_INCLUDED
4 #include "sql_executor.h"
29 #define CACHE_STRIPPED 2
30 #define CACHE_VARSTR1 3
31 #define CACHE_VARSTR2 4
53 uint referenced_field_no;
60 void bind_buffer(uchar *buffer)
66 bool buffer_is_bound()
const {
return str != NULL; }
106 uint offset_size(uint len)
107 {
return (len < 256 ? 1 : len < 256*256 ? 2 : 4); }
110 ulong get_offset(uint ofs_sz, uchar *ptr)
113 case 1:
return uint(*ptr);
114 case 2:
return uint2korr(ptr);
115 case 4:
return uint4korr(ptr);
121 void store_offset(uint ofs_sz, uchar *ptr, ulong ofs)
124 case 1: *ptr= (uchar) ofs;
return;
125 case 2: int2store(ptr, (uint16) ofs);
return;
126 case 4: int4store(ptr, (uint32) ofs);
return;
172 uint referenced_fields;
178 uint data_field_count;
185 uint data_field_ptr_count;
201 bool with_match_flag;
219 uint pack_length_with_blob_ptrs;
262 bool last_rec_blob_data_is_in_rec_buff;
273 uchar *curr_rec_link;
278 void calc_record_fields();
279 int alloc_fields(uint external_fields);
280 void create_flag_fields();
281 void create_remaining_fields(
bool all_read_fields);
282 void set_constants();
285 uint get_size_of_rec_offset() {
return size_of_rec_ofs; }
286 uint get_size_of_rec_length() {
return size_of_rec_len; }
287 uint get_size_of_fld_offset() {
return size_of_fld_ofs; }
289 uchar *get_rec_ref(uchar *ptr)
291 return buff+get_offset(size_of_rec_ofs, ptr-size_of_rec_ofs);
293 ulong get_rec_length(uchar *ptr)
295 return (ulong) get_offset(size_of_rec_len, ptr);
297 ulong get_fld_offset(uchar *ptr)
299 return (ulong) get_offset(size_of_fld_ofs, ptr);
302 void store_rec_ref(uchar *ptr, uchar* ref)
304 store_offset(size_of_rec_ofs, ptr-size_of_rec_ofs, (ulong) (ref-buff));
307 void store_rec_length(uchar *ptr, ulong len)
309 store_offset(size_of_rec_len, ptr, len);
311 void store_fld_offset(uchar *ptr, ulong ofs)
313 store_offset(size_of_fld_ofs, ptr, ofs);
317 uint write_record_data(uchar *
link,
bool *is_full);
324 virtual uint aux_buffer_incr() {
return 0; }
333 virtual ulong rem_space()
335 return std::max<ulong>(buff_size-(end_pos-buff)-aux_buff_size, 0UL);
339 virtual bool skip_record_if_match();
351 uint read_record_field(
CACHE_FIELD *copy,
bool last_record);
354 bool read_referenced_field(
CACHE_FIELD *copy, uchar *rec_ptr, uint *len);
360 bool blob_data_is_in_rec_buff(uchar *rec_ptr)
362 return rec_ptr == last_rec_pos && last_rec_blob_data_is_in_rec_buff;
366 virtual enum_nested_loop_state join_matching_records(
bool skip_last)=0;
369 virtual enum_nested_loop_state join_null_complements(
bool skip_last);
372 virtual void restore_last_record();
375 bool set_match_flag_if_none(
JOIN_TAB *first_inner, uchar *rec_ptr);
377 enum_nested_loop_state generate_full_extensions(uchar *rec_ptr);
380 virtual bool check_match(uchar *rec_ptr);
385 return (t->last_sj_inner_tab == t &&
388 t->table->reginfo.not_exists_optimize);
395 virtual bool put_record_in_cache();
404 virtual int init()=0;
407 virtual bool is_key_access() {
return FALSE; }
415 if (put_record_in_cache())
416 return join_records(
false);
417 return NESTED_LOOP_OK;
423 virtual bool get_record();
429 virtual void get_record_by_pos(uchar *rec_ptr);
432 virtual bool get_match_flag_by_pos(uchar *rec_ptr);
435 virtual uchar *get_curr_rec() {
return curr_rec_pos; }
438 virtual void set_curr_rec_link(uchar *
link) { curr_rec_link= link; }
441 virtual uchar *get_curr_rec_link()
443 return (curr_rec_link ? curr_rec_link : get_curr_rec());
447 enum_nested_loop_state
end_send() {
return join_records(
false); };
448 enum_nested_loop_state join_records(
bool skip_last);
450 enum_op_type type() {
return OT_CACHE; }
464 prev_cache->next_cache= NULL;
466 next_cache->prev_cache= NULL;
473 enum {ALG_NONE= 0, ALG_BNL= 1, ALG_BKA= 2, ALG_BKA_UNIQUE= 4};
486 enum_nested_loop_state join_matching_records(
bool skip_last);
499 prev_cache= next_cache= 0;
515 prev->next_cache=
this;
534 virtual void init_mrr_buff()
536 mrr_buff.buffer= end_pos;
537 mrr_buff.buffer_end= buff+buff_size;
544 uint local_key_arg_fields;
549 uint external_key_arg_fields;
560 bool check_emb_key_usage();
569 enum_nested_loop_state join_matching_records(
bool skip_last);
572 bool init_join_matching_records(
RANGE_SEQ_IF *seq_funcs, uint ranges);
586 prev_cache= next_cache= 0;
604 prev->next_cache=
this;
611 bool is_key_access() {
return TRUE; }
614 virtual uint get_next_key(uchar **key);
617 bool skip_index_tuple(range_seq_t rseq,
char *range_info);
705 uint size_of_key_ofs;
717 uint key_entry_length;
728 uchar *last_key_entry;
731 uchar *curr_key_entry;
740 uint rec_fields_offset;
742 uint data_fields_offset;
744 uint get_hash_idx(uchar* key, uint key_len);
746 void cleanup_hash_table();
750 uint get_size_of_key_offset() {
return size_of_key_ofs; }
758 uchar *get_next_key_ref(uchar *key_ref_ptr)
760 return hash_table-get_offset(size_of_key_ofs, key_ref_ptr);
769 void store_next_key_ref(uchar *key_ref_ptr, uchar *ref)
771 store_offset(size_of_key_ofs, key_ref_ptr, (ulong) (hash_table-ref));
778 bool is_null_key_ref(uchar *key_ref_ptr)
781 return memcmp(key_ref_ptr, &nil, size_of_key_ofs ) == 0;
788 void store_null_key_ref(uchar *key_ref_ptr)
791 store_offset(size_of_key_ofs, key_ref_ptr, nil);
794 uchar *get_next_rec_ref(uchar *ref_ptr)
796 return buff+get_offset(get_size_of_rec_offset(), ref_ptr);
799 void store_next_rec_ref(uchar *ref_ptr, uchar *ref)
801 store_offset(get_size_of_rec_offset(), ref_ptr, (ulong) (ref-buff));
808 uchar *get_curr_emb_key()
810 return get_curr_rec()+data_fields_offset;
818 uchar *get_emb_key(uchar *ref_ptr)
820 return buff+get_offset(get_size_of_rec_offset(), ref_ptr);
828 void store_emb_key_ref(uchar *ref_ptr, uchar *ref)
830 store_offset(get_size_of_rec_offset(), ref_ptr, (ulong) (ref-buff));
839 return std::max<ulong>(last_key_entry-end_pos-aux_buff_size, 0UL);
849 mrr_buff.buffer= end_pos;
850 mrr_buff.buffer_end= last_key_entry;
854 bool skip_record_if_match();
857 enum_nested_loop_state join_matching_records(
bool skip_last);
860 bool key_search(uchar *key, uint key_len, uchar **key_ref_ptr);
865 bool put_record_in_cache();
901 virtual bool check_all_match_flags_for_key(uchar *key_chain_ptr);
903 uint get_next_key(uchar **key);
906 uchar *get_curr_key_chain()
908 return get_next_rec_ref(curr_key_entry+key_entry_length-
909 get_size_of_rec_offset());