| 1 | /* Copyright (c) 2011, Oracle and/or its affiliates. |
| 2 | Copyright (c) Monty Program Ab; 1991-2011 |
| 3 | |
| 4 | This program is free software; you can redistribute it and/or modify |
| 5 | it under the terms of the GNU General Public License as published by |
| 6 | the Free Software Foundation; version 2 of the License. |
| 7 | |
| 8 | This program is distributed in the hope that it will be useful, |
| 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 11 | GNU General Public License for more details. |
| 12 | |
| 13 | You should have received a copy of the GNU General Public License |
| 14 | along with this program; if not, write to the Free Software |
| 15 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ |
| 16 | |
| 17 | #ifndef _my_compare_h |
| 18 | #define _my_compare_h |
| 19 | |
| 20 | #include "myisampack.h" |
| 21 | #ifdef __cplusplus |
| 22 | extern "C" { |
| 23 | #endif |
| 24 | |
| 25 | #include "m_ctype.h" /* CHARSET_INFO */ |
| 26 | |
| 27 | /* |
| 28 | There is a hard limit for the maximum number of keys as there are only |
| 29 | 8 bits in the index file header for the number of keys in a table. |
| 30 | This means that 0..255 keys can exist for a table. The idea of |
| 31 | HA_MAX_POSSIBLE_KEY is to ensure that one can use myisamchk & tools on |
| 32 | a MyISAM table for which one has more keys than MyISAM is normally |
| 33 | compiled for. If you don't have this, you will get a core dump when |
| 34 | running myisamchk compiled for 128 keys on a table with 255 keys. |
| 35 | */ |
| 36 | |
| 37 | #define HA_MAX_POSSIBLE_KEY 255 /* For myisamchk */ |
| 38 | /* |
| 39 | The following defines can be increased if necessary. |
| 40 | But beware the dependency of MI_MAX_POSSIBLE_KEY_BUFF and HA_MAX_KEY_LENGTH. |
| 41 | */ |
| 42 | |
| 43 | #define HA_MAX_KEY_LENGTH 1000 /* Max length in bytes */ |
| 44 | #define HA_MAX_KEY_SEG 32 /* Max segments for key */ |
| 45 | |
| 46 | #define HA_MAX_POSSIBLE_KEY_BUFF (HA_MAX_KEY_LENGTH + 24+ 6+6) |
| 47 | #define HA_MAX_KEY_BUFF (HA_MAX_KEY_LENGTH+HA_MAX_KEY_SEG*6+8+8) |
| 48 | |
| 49 | typedef struct st_HA_KEYSEG /* Key-portion */ |
| 50 | { |
| 51 | CHARSET_INFO *charset; |
| 52 | uint32 start; /* Start of key in record */ |
| 53 | uint32 null_pos; /* position to NULL indicator */ |
| 54 | uint16 bit_pos; /* Position to bit part */ |
| 55 | uint16 flag; |
| 56 | uint16 length; /* Keylength */ |
| 57 | uint16 language; |
| 58 | uint8 type; /* Type of key (for sort) */ |
| 59 | uint8 null_bit; /* bitmask to test for NULL */ |
| 60 | uint8 bit_start; |
| 61 | uint8 bit_length; /* Length of bit part */ |
| 62 | } HA_KEYSEG; |
| 63 | |
| 64 | #define get_key_length(length,key) \ |
| 65 | { if (*(const uchar*) (key) != 255) \ |
| 66 | length= (uint) *(const uchar*) ((key)++); \ |
| 67 | else \ |
| 68 | { length= mi_uint2korr((key)+1); (key)+=3; } \ |
| 69 | } |
| 70 | |
| 71 | #define get_key_length_rdonly(length,key) \ |
| 72 | { if (*(const uchar*) (key) != 255) \ |
| 73 | length= ((uint) *(const uchar*) ((key))); \ |
| 74 | else \ |
| 75 | { length= mi_uint2korr((key)+1); } \ |
| 76 | } |
| 77 | |
| 78 | #define get_key_pack_length(length,length_pack,key) \ |
| 79 | { if (*(const uchar*) (key) != 255) \ |
| 80 | { length= (uint) *(const uchar*) ((key)++); length_pack= 1; }\ |
| 81 | else \ |
| 82 | { length=mi_uint2korr((key)+1); (key)+= 3; length_pack= 3; } \ |
| 83 | } |
| 84 | |
| 85 | #define store_key_length_inc(key,length) \ |
| 86 | { if ((length) < 255) \ |
| 87 | { *(key)++= (uchar)(length); } \ |
| 88 | else \ |
| 89 | { *(key)=255; mi_int2store((key)+1,(length)); (key)+=3; } \ |
| 90 | } |
| 91 | |
| 92 | #define size_to_store_key_length(length) ((length) < 255 ? 1 : 3) |
| 93 | |
| 94 | static inline uchar get_rec_bits(const uchar *ptr, uchar ofs, uint len) |
| 95 | { |
| 96 | uint16 val= ptr[0]; |
| 97 | if (ofs + len > 8) |
| 98 | val|= (uint16)(ptr[1]) << 8; |
| 99 | return (val >> ofs) & ((1 << len) - 1); |
| 100 | } |
| 101 | |
| 102 | static inline void set_rec_bits(uint16 bits, uchar *ptr, uchar ofs, uint len) |
| 103 | { |
| 104 | ptr[0]= (ptr[0] & ~(((1 << len) - 1) << ofs)) | (bits << ofs); |
| 105 | if (ofs + len > 8) |
| 106 | ptr[1]= (ptr[1] & ~((1 << (len - 8 + ofs)) - 1)) | (bits >> (8 - ofs)); |
| 107 | } |
| 108 | |
| 109 | #define clr_rec_bits(bit_ptr, bit_ofs, bit_len) \ |
| 110 | set_rec_bits(0, bit_ptr, bit_ofs, bit_len) |
| 111 | |
| 112 | extern int ha_compare_text(CHARSET_INFO *, const uchar *, size_t, |
| 113 | const uchar *, size_t , my_bool); |
| 114 | extern int ha_key_cmp(HA_KEYSEG *keyseg, const uchar *a, |
| 115 | const uchar *b, uint key_length, uint nextflag, |
| 116 | uint *diff_pos); |
| 117 | extern HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, const uchar *a); |
| 118 | |
| 119 | /* |
| 120 | Inside an in-memory data record, memory pointers to pieces of the |
| 121 | record (like BLOBs) are stored in their native byte order and in |
| 122 | this amount of bytes. |
| 123 | */ |
| 124 | #define portable_sizeof_char_ptr 8 |
| 125 | #ifdef __cplusplus |
| 126 | } |
| 127 | #endif |
| 128 | |
| 129 | /** |
| 130 | Return values of index_cond_func_xxx functions. |
| 131 | |
| 132 | 0=ICP_NO_MATCH - index tuple doesn't satisfy the pushed index condition (the |
| 133 | engine should discard the tuple and go to the next one) |
| 134 | 1=ICP_MATCH - index tuple satisfies the pushed index condition (the |
| 135 | engine should fetch and return the record) |
| 136 | 2=ICP_OUT_OF_RANGE - index tuple is out range that we're scanning, e.g. this |
| 137 | if we're scanning "t.key BETWEEN 10 AND 20" and got a |
| 138 | "t.key=21" tuple (the engine should stop scanning and |
| 139 | return HA_ERR_END_OF_FILE right away). |
| 140 | 3=ICP_ABORTED_BY_USER - engine must stop scanning and should return |
| 141 | HA_ERR_ABORTED_BY_USER right away |
| 142 | -1= ICP_ERROR - Reserved for internal errors in engines. Should not be |
| 143 | returned by index_cond_func_xxx |
| 144 | */ |
| 145 | |
| 146 | typedef enum icp_result { |
| 147 | ICP_ERROR=-1, |
| 148 | ICP_NO_MATCH=0, |
| 149 | ICP_MATCH=1, |
| 150 | ICP_OUT_OF_RANGE=2, |
| 151 | ICP_ABORTED_BY_USER=3 |
| 152 | } ICP_RESULT; |
| 153 | |
| 154 | typedef ICP_RESULT (*index_cond_func_t)(void *param); |
| 155 | |
| 156 | #endif /* _my_compare_h */ |
| 157 | |