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 | |