Merge lp:~jaypipes/drizzle/fix-enum-error-control into lp:~drizzle-trunk/drizzle/development
- fix-enum-error-control
- Merge into development
Proposed by
Jay Pipes
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~jaypipes/drizzle/fix-enum-error-control |
Merge into: | lp:~drizzle-trunk/drizzle/development |
Diff against target: | None lines |
To merge this branch: | bzr merge lp:~jaypipes/drizzle/fix-enum-error-control |
Related bugs: | |
Related blueprints: |
Fix error control on ENUM
(Essential)
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Drizzle Developers | Pending | ||
Review via email: mp+4527@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Jay Pipes (jaypipes) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'drizzled/error.cc' |
2 | --- drizzled/error.cc 2009-03-06 05:23:46 +0000 |
3 | +++ drizzled/error.cc 2009-03-16 15:20:27 +0000 |
4 | @@ -1412,6 +1412,8 @@ |
5 | N_("Received an out-of-range argument '%s' for function '%s'."), |
6 | /* ER_INVALID_TIME_VALUE */ |
7 | N_("Received an invalid time value '%s'."), |
8 | +/* ER_INVALID_ENUM_VALUE */ |
9 | +N_("Received an invalid enum value '%s'.") |
10 | }; |
11 | |
12 | const char * error_message(unsigned int code) |
13 | |
14 | === modified file 'drizzled/error.h' |
15 | --- drizzled/error.h 2009-02-11 02:30:38 +0000 |
16 | +++ drizzled/error.h 2009-03-16 15:20:27 +0000 |
17 | @@ -720,7 +720,8 @@ |
18 | ER_INVALID_NEGATIVE_ARGUMENT, |
19 | ER_ARGUMENT_OUT_OF_RANGE, |
20 | ER_INVALID_TIME_VALUE, |
21 | - ER_ERROR_LAST= ER_INVALID_TIME_VALUE |
22 | + ER_INVALID_ENUM_VALUE, |
23 | + ER_ERROR_LAST= ER_INVALID_ENUM_VALUE |
24 | }; |
25 | |
26 | #ifdef __cplusplus |
27 | |
28 | === modified file 'drizzled/field/enum.cc' |
29 | --- drizzled/field/enum.cc 2009-02-21 00:18:15 +0000 |
30 | +++ drizzled/field/enum.cc 2009-03-16 15:20:27 +0000 |
31 | @@ -19,11 +19,14 @@ |
32 | */ |
33 | |
34 | |
35 | -#include <drizzled/server_includes.h> |
36 | -#include <drizzled/field/enum.h> |
37 | -#include <drizzled/error.h> |
38 | -#include <drizzled/table.h> |
39 | -#include <drizzled/session.h> |
40 | +#include "drizzled/server_includes.h" |
41 | +#include "drizzled/field/enum.h" |
42 | +#include "drizzled/error.h" |
43 | +#include "drizzled/table.h" |
44 | +#include "drizzled/session.h" |
45 | + |
46 | +#include <sstream> |
47 | +#include <string> |
48 | |
49 | /**************************************************************************** |
50 | ** enum type. |
51 | @@ -33,12 +36,13 @@ |
52 | |
53 | enum ha_base_keytype Field_enum::key_type() const |
54 | { |
55 | - switch (packlength) { |
56 | - default: return HA_KEYTYPE_BINARY; |
57 | - case 2: assert(1); |
58 | - case 3: assert(1); |
59 | - case 4: return HA_KEYTYPE_ULONG_INT; |
60 | - case 8: return HA_KEYTYPE_ULONGLONG; |
61 | + switch (packlength) |
62 | + { |
63 | + default: return HA_KEYTYPE_BINARY; |
64 | + case 2: assert(1); |
65 | + case 3: assert(1); |
66 | + case 4: return HA_KEYTYPE_ULONG_INT; |
67 | + case 8: return HA_KEYTYPE_ULONGLONG; |
68 | } |
69 | } |
70 | |
71 | @@ -79,85 +83,77 @@ |
72 | } |
73 | } |
74 | |
75 | - |
76 | /** |
77 | - @note |
78 | - Storing a empty string in a enum field gives a warning |
79 | - (if there isn't a empty value in the enum) |
80 | -*/ |
81 | - |
82 | -int Field_enum::store(const char *from, uint32_t length, const CHARSET_INFO * const cs) |
83 | + * Given a supplied string, looks up the string in the internal typelib |
84 | + * and stores the found key. Upon not finding an entry in the typelib, |
85 | + * we always throw an error. |
86 | + */ |
87 | +int Field_enum::store(const char *from, uint32_t length, const CHARSET_INFO * const) |
88 | { |
89 | - int err= 0; |
90 | - uint32_t not_used; |
91 | - char buff[STRING_BUFFER_USUAL_SIZE]; |
92 | - String tmpstr(buff,sizeof(buff), &my_charset_bin); |
93 | - |
94 | - /* Convert character set if necessary */ |
95 | - if (String::needs_conversion(length, cs, field_charset, ¬_used)) |
96 | - { |
97 | - uint32_t dummy_errors; |
98 | - tmpstr.copy(from, length, cs, field_charset, &dummy_errors); |
99 | - from= tmpstr.ptr(); |
100 | - length= tmpstr.length(); |
101 | - } |
102 | + uint32_t tmp; |
103 | |
104 | /* Remove end space */ |
105 | length= field_charset->cset->lengthsp(field_charset, from, length); |
106 | - uint32_t tmp=find_type2(typelib, from, length, field_charset); |
107 | - if (!tmp) |
108 | + tmp= find_type2(typelib, from, length, field_charset); |
109 | + if (! tmp) |
110 | { |
111 | - if (length < 6) // Can't be more than 99999 enums |
112 | + if (length < 6) /* Can't be more than 99999 enums */ |
113 | { |
114 | /* This is for reading numbers with LOAD DATA INFILE */ |
115 | - char *end; |
116 | - tmp=(uint32_t) my_strntoul(cs,from,length,10,&end,&err); |
117 | - if (err || end != from+length || tmp > typelib->count) |
118 | + /* Convert the string to an integer using stringstream */ |
119 | + std::stringstream ss; |
120 | + ss << from; |
121 | + ss >> tmp; |
122 | + |
123 | + if (tmp == 0 || tmp > typelib->count) |
124 | { |
125 | - tmp=0; |
126 | - set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1); |
127 | + my_error(ER_INVALID_ENUM_VALUE, MYF(ME_FATALERROR), from); |
128 | + return 1; |
129 | } |
130 | - if (!table->in_use->count_cuted_fields) |
131 | - err= 0; |
132 | } |
133 | else |
134 | - set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1); |
135 | + { |
136 | + my_error(ER_INVALID_ENUM_VALUE, MYF(ME_FATALERROR), from); |
137 | + return 1; |
138 | + } |
139 | } |
140 | store_type((uint64_t) tmp); |
141 | - return err; |
142 | -} |
143 | - |
144 | - |
145 | -int Field_enum::store(double nr) |
146 | -{ |
147 | - return Field_enum::store((int64_t) nr, false); |
148 | -} |
149 | - |
150 | - |
151 | -int Field_enum::store(int64_t nr, |
152 | - bool ) |
153 | -{ |
154 | - int error= 0; |
155 | - if ((uint64_t) nr > typelib->count || nr == 0) |
156 | + return 0; |
157 | +} |
158 | + |
159 | +int Field_enum::store(double from) |
160 | +{ |
161 | + return Field_enum::store((int64_t) from, false); |
162 | +} |
163 | + |
164 | +/** |
165 | + * @note MySQL allows 0 values, saying that 0 is "the index of the |
166 | + * blank string error", whatever that means. Uhm, Drizzle doesn't |
167 | + * allow this. To store an ENUM column value using an integer, you |
168 | + * must specify the 1-based index of the enum column definition's |
169 | + * key. |
170 | + */ |
171 | +int Field_enum::store(int64_t from, bool) |
172 | +{ |
173 | + if (from <= 0 || (uint64_t) from > typelib->count) |
174 | { |
175 | - set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1); |
176 | - if (nr != 0 || table->in_use->count_cuted_fields) |
177 | - { |
178 | - nr= 0; |
179 | - error= 1; |
180 | - } |
181 | + /* Convert the integer to a string using stringstream */ |
182 | + std::stringstream ss; |
183 | + std::string tmp; |
184 | + ss << from; ss >> tmp; |
185 | + |
186 | + my_error(ER_INVALID_ENUM_VALUE, MYF(ME_FATALERROR), tmp.c_str()); |
187 | + return 1; |
188 | } |
189 | - store_type((uint64_t) (uint32_t) nr); |
190 | - return error; |
191 | + store_type((uint64_t) (uint32_t) from); |
192 | + return 0; |
193 | } |
194 | |
195 | - |
196 | double Field_enum::val_real(void) |
197 | { |
198 | return (double) Field_enum::val_int(); |
199 | } |
200 | |
201 | - |
202 | int64_t Field_enum::val_int(void) |
203 | { |
204 | switch (packlength) { |
205 | @@ -202,7 +198,6 @@ |
206 | return 0; // impossible |
207 | } |
208 | |
209 | - |
210 | /** |
211 | Save the field metadata for enum fields. |
212 | |
213 | @@ -221,9 +216,7 @@ |
214 | return 2; |
215 | } |
216 | |
217 | - |
218 | -String *Field_enum::val_str(String *, |
219 | - String *val_ptr) |
220 | +String *Field_enum::val_str(String *, String *val_ptr) |
221 | { |
222 | uint32_t tmp=(uint32_t) Field_enum::val_int(); |
223 | if (!tmp || tmp > typelib->count) |
224 | @@ -257,7 +250,6 @@ |
225 | } |
226 | } |
227 | |
228 | - |
229 | void Field_enum::sql_type(String &res) const |
230 | { |
231 | char buffer[255]; |
232 | @@ -281,7 +273,6 @@ |
233 | res.append(')'); |
234 | } |
235 | |
236 | - |
237 | Field *Field_enum::new_field(MEM_ROOT *root, Table *new_table, |
238 | bool keep_type) |
239 | { |
240 | |
241 | === modified file 'drizzled/field/enum.h' |
242 | --- drizzled/field/enum.h 2009-02-20 08:45:29 +0000 |
243 | +++ drizzled/field/enum.h 2009-03-16 15:20:27 +0000 |
244 | @@ -18,12 +18,13 @@ |
245 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
246 | */ |
247 | |
248 | -#ifndef DRIZZLE_SERVER_FIELD_ENUM |
249 | -#define DRIZZLE_SERVER_FIELD_ENUM |
250 | - |
251 | -#include <drizzled/field/str.h> |
252 | - |
253 | -class Field_enum :public Field_str { |
254 | +#ifndef DRIZZLED_FIELD_ENUM_H |
255 | +#define DRIZZLED_FIELD_ENUM_H |
256 | + |
257 | +#include "drizzled/field/str.h" |
258 | + |
259 | +class Field_enum :public Field_str |
260 | +{ |
261 | protected: |
262 | uint32_t packlength; |
263 | public: |
264 | @@ -33,6 +34,7 @@ |
265 | using Field::val_str; |
266 | using Field::cmp; |
267 | |
268 | + /** Internal storage for the string values of the ENUM */ |
269 | TYPELIB *typelib; |
270 | Field_enum(unsigned char *ptr_arg, uint32_t len_arg, unsigned char *null_ptr_arg, |
271 | unsigned char null_bit_arg, |
272 | @@ -47,35 +49,66 @@ |
273 | flags|=ENUM_FLAG; |
274 | } |
275 | Field *new_field(MEM_ROOT *root, Table *new_table, bool keep_type); |
276 | - enum_field_types type() const { return DRIZZLE_TYPE_ENUM; } |
277 | - enum Item_result cmp_type () const { return INT_RESULT; } |
278 | - enum Item_result cast_to_int_type () const { return INT_RESULT; } |
279 | enum ha_base_keytype key_type() const; |
280 | - int store(const char *to,uint32_t length, const CHARSET_INFO * const charset); |
281 | + int store(const char *to, uint32_t length, const CHARSET_INFO * const); |
282 | int store(double nr); |
283 | int store(int64_t nr, bool unsigned_val); |
284 | double val_real(void); |
285 | int64_t val_int(void); |
286 | - String *val_str(String*,String *); |
287 | - int cmp(const unsigned char *,const unsigned char *); |
288 | - void sort_string(unsigned char *buff,uint32_t length); |
289 | - uint32_t pack_length() const { return (uint32_t) packlength; } |
290 | + String *val_str(String*, String *); |
291 | + int cmp(const unsigned char *, const unsigned char *); |
292 | + void sort_string(unsigned char *buff, uint32_t length); |
293 | void store_type(uint64_t value); |
294 | void sql_type(String &str) const; |
295 | - uint32_t size_of() const { return sizeof(*this); } |
296 | - enum_field_types real_type() const { return DRIZZLE_TYPE_ENUM; } |
297 | + bool eq_def(Field *field); |
298 | + enum_field_types type() const |
299 | + { |
300 | + return DRIZZLE_TYPE_ENUM; |
301 | + } |
302 | + enum Item_result cmp_type () const |
303 | + { |
304 | + return INT_RESULT; |
305 | + } |
306 | + enum Item_result cast_to_int_type () const |
307 | + { |
308 | + return INT_RESULT; |
309 | + } |
310 | + uint32_t pack_length() const |
311 | + { |
312 | + return (uint32_t) packlength; |
313 | + } |
314 | + uint32_t size_of() const |
315 | + { |
316 | + return sizeof(*this); |
317 | + } |
318 | + enum_field_types real_type() const |
319 | + { |
320 | + return DRIZZLE_TYPE_ENUM; |
321 | + } |
322 | uint32_t pack_length_from_metadata(uint32_t field_metadata) |
323 | - { return (field_metadata & 0x00ff); } |
324 | - uint32_t row_pack_length() { return pack_length(); } |
325 | - virtual bool zero_pack() const { return 0; } |
326 | - bool optimize_range(uint32_t, uint32_t) |
327 | - { return 0; } |
328 | - bool eq_def(Field *field); |
329 | - bool has_charset(void) const { return true; } |
330 | + { |
331 | + return (field_metadata & 0x00ff); |
332 | + } |
333 | + uint32_t row_pack_length() |
334 | + { |
335 | + return pack_length(); |
336 | + } |
337 | + virtual bool zero_pack() const |
338 | + { |
339 | + return false; |
340 | + } |
341 | + bool optimize_range(uint32_t, uint32_t) |
342 | + { |
343 | + return false; |
344 | + } |
345 | + bool has_charset(void) const |
346 | + { |
347 | + return true; |
348 | + } |
349 | /* enum and set are sorted as integers */ |
350 | const CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; } |
351 | private: |
352 | int do_save_field_metadata(unsigned char *first_byte); |
353 | }; |
354 | |
355 | -#endif |
356 | +#endif /* DRIZZLED_FIELD_ENUM_H */ |
357 | |
358 | === modified file 'drizzled/sql_select.cc' |
359 | --- drizzled/sql_select.cc 2009-03-11 19:04:31 +0000 |
360 | +++ drizzled/sql_select.cc 2009-03-16 15:20:27 +0000 |
361 | @@ -2030,8 +2030,7 @@ |
362 | @todo |
363 | When can we have here session->net.report_error not zero? |
364 | */ |
365 | -void |
366 | -JOIN::exec() |
367 | +void JOIN::exec() |
368 | { |
369 | List<Item> *columns_list= &fields_list; |
370 | int tmp_error; |
371 | @@ -2043,12 +2042,10 @@ |
372 | { |
373 | /* Only test of functions */ |
374 | if (select_options & SELECT_DESCRIBE) |
375 | - select_describe(this, false, false, false, |
376 | - (zero_result_cause?zero_result_cause:"No tables used")); |
377 | + select_describe(this, false, false, false, (zero_result_cause?zero_result_cause:"No tables used")); |
378 | else |
379 | { |
380 | - result->send_fields(*columns_list, |
381 | - Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); |
382 | + result->send_fields(*columns_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); |
383 | /* |
384 | We have to test for 'conds' here as the WHERE may not be constant |
385 | even if we don't have any tables for prepared statements or if |
386 | @@ -2096,8 +2093,7 @@ |
387 | return; |
388 | } |
389 | |
390 | - if ((this->select_lex->options & OPTION_SCHEMA_TABLE) && |
391 | - get_schema_tables_result(this, PROCESSED_BY_JOIN_EXEC)) |
392 | + if ((this->select_lex->options & OPTION_SCHEMA_TABLE) && get_schema_tables_result(this, PROCESSED_BY_JOIN_EXEC)) |
393 | return; |
394 | |
395 | if (select_options & SELECT_DESCRIBE) |
396 | @@ -2109,28 +2105,20 @@ |
397 | */ |
398 | if (!order && !no_order && (!skip_sort_order || !need_tmp)) |
399 | { |
400 | - /* |
401 | - Reset 'order' to 'group_list' and reinit variables describing |
402 | - 'order' |
403 | - */ |
404 | + /* Reset 'order' to 'group_list' and reinit variables describing 'order' */ |
405 | order= group_list; |
406 | simple_order= simple_group; |
407 | skip_sort_order= 0; |
408 | } |
409 | - if (order && |
410 | - (order != group_list || !(select_options & SELECT_BIG_RESULT)) && |
411 | - (const_tables == tables || |
412 | - ((simple_order || skip_sort_order) && |
413 | - test_if_skip_sort_order(&join_tab[const_tables], order, |
414 | - select_limit, 0, |
415 | - &join_tab[const_tables].table-> |
416 | - keys_in_use_for_query)))) |
417 | - order=0; |
418 | + if (order && (order != group_list || !(select_options & SELECT_BIG_RESULT))) |
419 | + { |
420 | + if (const_tables == tables |
421 | + || ((simple_order || skip_sort_order) |
422 | + && test_if_skip_sort_order(&join_tab[const_tables], order, select_limit, 0, &join_tab[const_tables].table->keys_in_use_for_query))) |
423 | + order= 0; |
424 | + } |
425 | having= tmp_having; |
426 | - select_describe(this, need_tmp, |
427 | - order != 0 && !skip_sort_order, |
428 | - select_distinct, |
429 | - !tables ? "No tables used" : NULL); |
430 | + select_describe(this, need_tmp, order != 0 && !skip_sort_order, select_distinct, !tables ? "No tables used" : NULL); |
431 | return; |
432 | } |
433 | |
434 | @@ -2162,8 +2150,7 @@ |
435 | |
436 | /* Copy data to the temporary table */ |
437 | session->set_proc_info("Copying to tmp table"); |
438 | - if (!curr_join->sort_and_group && |
439 | - curr_join->const_tables != curr_join->tables) |
440 | + if (! curr_join->sort_and_group && curr_join->const_tables != curr_join->tables) |
441 | curr_join->join_tab[curr_join->const_tables].sorted= 0; |
442 | if ((tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table))) |
443 | { |
444 | @@ -2182,17 +2169,17 @@ |
445 | items1= items0 + all_fields.elements; |
446 | if (sort_and_group || curr_tmp_table->group) |
447 | { |
448 | - if (change_to_use_tmp_fields(session, items1, |
449 | - tmp_fields_list1, tmp_all_fields1, |
450 | - fields_list.elements, all_fields)) |
451 | - return; |
452 | + if (change_to_use_tmp_fields(session, items1, |
453 | + tmp_fields_list1, tmp_all_fields1, |
454 | + fields_list.elements, all_fields)) |
455 | + return; |
456 | } |
457 | else |
458 | { |
459 | - if (change_refs_to_tmp_fields(session, items1, |
460 | - tmp_fields_list1, tmp_all_fields1, |
461 | - fields_list.elements, all_fields)) |
462 | - return; |
463 | + if (change_refs_to_tmp_fields(session, items1, |
464 | + tmp_fields_list1, tmp_all_fields1, |
465 | + fields_list.elements, all_fields)) |
466 | + return; |
467 | } |
468 | curr_join->tmp_all_fields1= tmp_all_fields1; |
469 | curr_join->tmp_fields_list1= tmp_fields_list1; |
470 | @@ -2204,23 +2191,21 @@ |
471 | |
472 | if (sort_and_group || curr_tmp_table->group) |
473 | { |
474 | - curr_join->tmp_table_param.field_count+= |
475 | - curr_join->tmp_table_param.sum_func_count+ |
476 | - curr_join->tmp_table_param.func_count; |
477 | - curr_join->tmp_table_param.sum_func_count= |
478 | - curr_join->tmp_table_param.func_count= 0; |
479 | + curr_join->tmp_table_param.field_count+= curr_join->tmp_table_param.sum_func_count |
480 | + + curr_join->tmp_table_param.func_count; |
481 | + curr_join->tmp_table_param.sum_func_count= 0; |
482 | + curr_join->tmp_table_param.func_count= 0; |
483 | } |
484 | else |
485 | { |
486 | - curr_join->tmp_table_param.field_count+= |
487 | - curr_join->tmp_table_param.func_count; |
488 | + curr_join->tmp_table_param.field_count+= curr_join->tmp_table_param.func_count; |
489 | curr_join->tmp_table_param.func_count= 0; |
490 | } |
491 | |
492 | if (curr_tmp_table->group) |
493 | { // Already grouped |
494 | if (!curr_join->order && !curr_join->no_order && !skip_sort_order) |
495 | - curr_join->order= curr_join->group_list; /* order by group */ |
496 | + curr_join->order= curr_join->group_list; /* order by group */ |
497 | curr_join->group_list= 0; |
498 | } |
499 | |
500 | @@ -2232,26 +2217,25 @@ |
501 | like SEC_TO_TIME(SUM(...)). |
502 | */ |
503 | |
504 | - if ((curr_join->group_list && (!test_if_subpart(curr_join->group_list, curr_join->order) || curr_join->select_distinct)) || (curr_join->select_distinct && curr_join->tmp_table_param.using_indirect_summary_function)) |
505 | + if ((curr_join->group_list && (!test_if_subpart(curr_join->group_list, curr_join->order) || curr_join->select_distinct)) |
506 | + || (curr_join->select_distinct && curr_join->tmp_table_param.using_indirect_summary_function)) |
507 | { /* Must copy to another table */ |
508 | /* Free first data from old join */ |
509 | curr_join->join_free(); |
510 | if (make_simple_join(curr_join, curr_tmp_table)) |
511 | - return; |
512 | + return; |
513 | calc_group_buffer(curr_join, group_list); |
514 | count_field_types(select_lex, &curr_join->tmp_table_param, |
515 | curr_join->tmp_all_fields1, |
516 | curr_join->select_distinct && !curr_join->group_list); |
517 | - curr_join->tmp_table_param.hidden_field_count= |
518 | - (curr_join->tmp_all_fields1.elements- |
519 | - curr_join->tmp_fields_list1.elements); |
520 | - |
521 | + curr_join->tmp_table_param.hidden_field_count= curr_join->tmp_all_fields1.elements |
522 | + - curr_join->tmp_fields_list1.elements; |
523 | |
524 | if (exec_tmp_table2) |
525 | - curr_tmp_table= exec_tmp_table2; |
526 | + curr_tmp_table= exec_tmp_table2; |
527 | else |
528 | { |
529 | - /* group data to new table */ |
530 | + /* group data to new table */ |
531 | |
532 | /* |
533 | If the access method is loose index scan then all MIN/MAX |
534 | @@ -2261,32 +2245,32 @@ |
535 | if (curr_join->join_tab->is_using_loose_index_scan()) |
536 | curr_join->tmp_table_param.precomputed_group_by= true; |
537 | |
538 | - if (!(curr_tmp_table= |
539 | - exec_tmp_table2= create_tmp_table(session, |
540 | - &curr_join->tmp_table_param, |
541 | - *curr_all_fields, |
542 | - (order_st*) 0, |
543 | - curr_join->select_distinct && |
544 | - !curr_join->group_list, |
545 | - 1, curr_join->select_options, |
546 | - HA_POS_ERROR, |
547 | - (char *) ""))) |
548 | - return; |
549 | - curr_join->exec_tmp_table2= exec_tmp_table2; |
550 | + if (!(curr_tmp_table= |
551 | + exec_tmp_table2= create_tmp_table(session, |
552 | + &curr_join->tmp_table_param, |
553 | + *curr_all_fields, |
554 | + (order_st*) 0, |
555 | + curr_join->select_distinct && |
556 | + !curr_join->group_list, |
557 | + 1, curr_join->select_options, |
558 | + HA_POS_ERROR, |
559 | + (char *) ""))) |
560 | + return; |
561 | + curr_join->exec_tmp_table2= exec_tmp_table2; |
562 | } |
563 | if (curr_join->group_list) |
564 | { |
565 | - session->set_proc_info("Creating sort index"); |
566 | - if (curr_join->join_tab == join_tab && save_join_tab()) |
567 | - { |
568 | - return; |
569 | - } |
570 | - if (create_sort_index(session, curr_join, curr_join->group_list, |
571 | - HA_POS_ERROR, HA_POS_ERROR, false) || |
572 | - make_group_fields(this, curr_join)) |
573 | - { |
574 | - return; |
575 | - } |
576 | + session->set_proc_info("Creating sort index"); |
577 | + if (curr_join->join_tab == join_tab && save_join_tab()) |
578 | + { |
579 | + return; |
580 | + } |
581 | + if (create_sort_index(session, curr_join, curr_join->group_list, |
582 | + HA_POS_ERROR, HA_POS_ERROR, false) || |
583 | + make_group_fields(this, curr_join)) |
584 | + { |
585 | + return; |
586 | + } |
587 | sortorder= curr_join->sortorder; |
588 | } |
589 | |
590 | @@ -2294,30 +2278,30 @@ |
591 | tmp_error= -1; |
592 | if (curr_join != this) |
593 | { |
594 | - if (sum_funcs2) |
595 | - { |
596 | - curr_join->sum_funcs= sum_funcs2; |
597 | - curr_join->sum_funcs_end= sum_funcs_end2; |
598 | - } |
599 | - else |
600 | - { |
601 | - curr_join->alloc_func_list(); |
602 | - sum_funcs2= curr_join->sum_funcs; |
603 | - sum_funcs_end2= curr_join->sum_funcs_end; |
604 | - } |
605 | + if (sum_funcs2) |
606 | + { |
607 | + curr_join->sum_funcs= sum_funcs2; |
608 | + curr_join->sum_funcs_end= sum_funcs_end2; |
609 | + } |
610 | + else |
611 | + { |
612 | + curr_join->alloc_func_list(); |
613 | + sum_funcs2= curr_join->sum_funcs; |
614 | + sum_funcs_end2= curr_join->sum_funcs_end; |
615 | + } |
616 | } |
617 | - if (curr_join->make_sum_func_list(*curr_all_fields, *curr_fields_list, |
618 | - 1, true)) |
619 | + if (curr_join->make_sum_func_list(*curr_all_fields, *curr_fields_list, 1, true)) |
620 | return; |
621 | curr_join->group_list= 0; |
622 | - if (!curr_join->sort_and_group && |
623 | - curr_join->const_tables != curr_join->tables) |
624 | + |
625 | + if (!curr_join->sort_and_group && (curr_join->const_tables != curr_join->tables)) |
626 | curr_join->join_tab[curr_join->const_tables].sorted= 0; |
627 | - if (setup_sum_funcs(curr_join->session, curr_join->sum_funcs) || |
628 | - (tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table))) |
629 | + |
630 | + if (setup_sum_funcs(curr_join->session, curr_join->sum_funcs) |
631 | + || (tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table))) |
632 | { |
633 | - error= tmp_error; |
634 | - return; |
635 | + error= tmp_error; |
636 | + return; |
637 | } |
638 | end_read_record(&curr_join->join_tab->read_record); |
639 | curr_join->const_tables= curr_join->tables; // Mark free for cleanup() |
640 | @@ -2326,19 +2310,18 @@ |
641 | // No sum funcs anymore |
642 | if (!items2) |
643 | { |
644 | - items2= items1 + all_fields.elements; |
645 | - if (change_to_use_tmp_fields(session, items2, |
646 | - tmp_fields_list2, tmp_all_fields2, |
647 | - fields_list.elements, tmp_all_fields1)) |
648 | - return; |
649 | - curr_join->tmp_fields_list2= tmp_fields_list2; |
650 | - curr_join->tmp_all_fields2= tmp_all_fields2; |
651 | + items2= items1 + all_fields.elements; |
652 | + if (change_to_use_tmp_fields(session, items2, |
653 | + tmp_fields_list2, tmp_all_fields2, |
654 | + fields_list.elements, tmp_all_fields1)) |
655 | + return; |
656 | + curr_join->tmp_fields_list2= tmp_fields_list2; |
657 | + curr_join->tmp_all_fields2= tmp_all_fields2; |
658 | } |
659 | curr_fields_list= &curr_join->tmp_fields_list2; |
660 | curr_all_fields= &curr_join->tmp_all_fields2; |
661 | curr_join->set_items_ref_array(items2); |
662 | - curr_join->tmp_table_param.field_count+= |
663 | - curr_join->tmp_table_param.sum_func_count; |
664 | + curr_join->tmp_table_param.field_count+= curr_join->tmp_table_param.sum_func_count; |
665 | curr_join->tmp_table_param.sum_func_count= 0; |
666 | } |
667 | if (curr_tmp_table->distinct) |
668 | @@ -2349,10 +2332,12 @@ |
669 | { |
670 | session->set_proc_info("Removing duplicates"); |
671 | if (curr_join->tmp_having) |
672 | - curr_join->tmp_having->update_used_tables(); |
673 | + curr_join->tmp_having->update_used_tables(); |
674 | + |
675 | if (remove_duplicates(curr_join, curr_tmp_table, |
676 | *curr_fields_list, curr_join->tmp_having)) |
677 | - return; |
678 | + return; |
679 | + |
680 | curr_join->tmp_having=0; |
681 | curr_join->select_distinct=0; |
682 | } |
683 | @@ -2360,29 +2345,26 @@ |
684 | if (make_simple_join(curr_join, curr_tmp_table)) |
685 | return; |
686 | calc_group_buffer(curr_join, curr_join->group_list); |
687 | - count_field_types(select_lex, &curr_join->tmp_table_param, |
688 | - *curr_all_fields, 0); |
689 | + count_field_types(select_lex, &curr_join->tmp_table_param, *curr_all_fields, 0); |
690 | |
691 | } |
692 | |
693 | if (curr_join->group || curr_join->tmp_table_param.sum_func_count) |
694 | { |
695 | if (make_group_fields(this, curr_join)) |
696 | - { |
697 | return; |
698 | - } |
699 | - if (!items3) |
700 | + |
701 | + if (! items3) |
702 | { |
703 | - if (!items0) |
704 | - init_items_ref_array(); |
705 | + if (! items0) |
706 | + init_items_ref_array(); |
707 | items3= ref_pointer_array + (all_fields.elements*4); |
708 | setup_copy_fields(session, &curr_join->tmp_table_param, |
709 | items3, tmp_fields_list3, tmp_all_fields3, |
710 | curr_fields_list->elements, *curr_all_fields); |
711 | tmp_table_param.save_copy_funcs= curr_join->tmp_table_param.copy_funcs; |
712 | tmp_table_param.save_copy_field= curr_join->tmp_table_param.copy_field; |
713 | - tmp_table_param.save_copy_field_end= |
714 | - curr_join->tmp_table_param.copy_field_end; |
715 | + tmp_table_param.save_copy_field_end= curr_join->tmp_table_param.copy_field_end; |
716 | curr_join->tmp_all_fields3= tmp_all_fields3; |
717 | curr_join->tmp_fields_list3= tmp_fields_list3; |
718 | } |
719 | @@ -2390,8 +2372,7 @@ |
720 | { |
721 | curr_join->tmp_table_param.copy_funcs= tmp_table_param.save_copy_funcs; |
722 | curr_join->tmp_table_param.copy_field= tmp_table_param.save_copy_field; |
723 | - curr_join->tmp_table_param.copy_field_end= |
724 | - tmp_table_param.save_copy_field_end; |
725 | + curr_join->tmp_table_param.copy_field_end= tmp_table_param.save_copy_field_end; |
726 | } |
727 | curr_fields_list= &tmp_fields_list3; |
728 | curr_all_fields= &tmp_all_fields3; |
729 | @@ -2407,8 +2388,7 @@ |
730 | { |
731 | session->set_proc_info("Sorting result"); |
732 | /* If we have already done the group, add HAVING to sorted table */ |
733 | - if (curr_join->tmp_having && ! curr_join->group_list && |
734 | - ! curr_join->sort_and_group) |
735 | + if (curr_join->tmp_having && ! curr_join->group_list && ! curr_join->sort_and_group) |
736 | { |
737 | // Some tables may have been const |
738 | curr_join->tmp_having->update_used_tables(); |
739 | @@ -2416,73 +2396,69 @@ |
740 | table_map used_tables= (curr_join->const_table_map | |
741 | curr_table->table->map); |
742 | |
743 | - Item* sort_table_cond= make_cond_for_table(curr_join->tmp_having, |
744 | - used_tables, |
745 | - used_tables, 0); |
746 | + Item* sort_table_cond= make_cond_for_table(curr_join->tmp_having, used_tables, used_tables, 0); |
747 | if (sort_table_cond) |
748 | { |
749 | - if (!curr_table->select) |
750 | - if (!(curr_table->select= new SQL_SELECT)) |
751 | - return; |
752 | - if (!curr_table->select->cond) |
753 | - curr_table->select->cond= sort_table_cond; |
754 | - else // This should never happen |
755 | - { |
756 | - if (!(curr_table->select->cond= |
757 | - new Item_cond_and(curr_table->select->cond, |
758 | - sort_table_cond))) |
759 | - return; |
760 | - /* |
761 | - Item_cond_and do not need fix_fields for execution, its parameters |
762 | - are fixed or do not need fix_fields, too |
763 | - */ |
764 | - curr_table->select->cond->quick_fix_field(); |
765 | - } |
766 | - curr_table->select_cond= curr_table->select->cond; |
767 | - curr_table->select_cond->top_level_item(); |
768 | - curr_join->tmp_having= make_cond_for_table(curr_join->tmp_having, |
769 | - ~ (table_map) 0, |
770 | - ~used_tables, 0); |
771 | + if (!curr_table->select) |
772 | + if (!(curr_table->select= new SQL_SELECT)) |
773 | + return; |
774 | + if (!curr_table->select->cond) |
775 | + curr_table->select->cond= sort_table_cond; |
776 | + else // This should never happen |
777 | + { |
778 | + if (!(curr_table->select->cond= |
779 | + new Item_cond_and(curr_table->select->cond, |
780 | + sort_table_cond))) |
781 | + return; |
782 | + /* |
783 | + Item_cond_and do not need fix_fields for execution, its parameters |
784 | + are fixed or do not need fix_fields, too |
785 | + */ |
786 | + curr_table->select->cond->quick_fix_field(); |
787 | + } |
788 | + curr_table->select_cond= curr_table->select->cond; |
789 | + curr_table->select_cond->top_level_item(); |
790 | + curr_join->tmp_having= make_cond_for_table(curr_join->tmp_having, |
791 | + ~ (table_map) 0, |
792 | + ~used_tables, 0); |
793 | } |
794 | } |
795 | { |
796 | if (group) |
797 | - curr_join->select_limit= HA_POS_ERROR; |
798 | + curr_join->select_limit= HA_POS_ERROR; |
799 | else |
800 | { |
801 | - /* |
802 | - We can abort sorting after session->select_limit rows if we there is no |
803 | - WHERE clause for any tables after the sorted one. |
804 | - */ |
805 | - JOIN_TAB *curr_table= &curr_join->join_tab[curr_join->const_tables+1]; |
806 | - JOIN_TAB *end_table= &curr_join->join_tab[curr_join->tables]; |
807 | - for (; curr_table < end_table ; curr_table++) |
808 | - { |
809 | - /* |
810 | - table->keyuse is set in the case there was an original WHERE clause |
811 | - on the table that was optimized away. |
812 | - */ |
813 | - if (curr_table->select_cond || |
814 | - (curr_table->keyuse && !curr_table->first_inner)) |
815 | - { |
816 | - /* We have to sort all rows */ |
817 | - curr_join->select_limit= HA_POS_ERROR; |
818 | - break; |
819 | - } |
820 | - } |
821 | + /* |
822 | + We can abort sorting after session->select_limit rows if we there is no |
823 | + WHERE clause for any tables after the sorted one. |
824 | + */ |
825 | + JOIN_TAB *curr_table= &curr_join->join_tab[curr_join->const_tables+1]; |
826 | + JOIN_TAB *end_table= &curr_join->join_tab[curr_join->tables]; |
827 | + for (; curr_table < end_table ; curr_table++) |
828 | + { |
829 | + /* |
830 | + table->keyuse is set in the case there was an original WHERE clause |
831 | + on the table that was optimized away. |
832 | + */ |
833 | + if (curr_table->select_cond || |
834 | + (curr_table->keyuse && !curr_table->first_inner)) |
835 | + { |
836 | + /* We have to sort all rows */ |
837 | + curr_join->select_limit= HA_POS_ERROR; |
838 | + break; |
839 | + } |
840 | + } |
841 | } |
842 | if (curr_join->join_tab == join_tab && save_join_tab()) |
843 | - { |
844 | - return; |
845 | - } |
846 | + return; |
847 | /* |
848 | - Here we sort rows for order_st BY/GROUP BY clause, if the optimiser |
849 | - chose FILESORT to be faster than INDEX SCAN or there is no |
850 | - suitable index present. |
851 | - Note, that create_sort_index calls test_if_skip_sort_order and may |
852 | - finally replace sorting with index scan if there is a LIMIT clause in |
853 | - the query. XXX: it's never shown in EXPLAIN! |
854 | - OPTION_FOUND_ROWS supersedes LIMIT and is taken into account. |
855 | + Here we sort rows for order_st BY/GROUP BY clause, if the optimiser |
856 | + chose FILESORT to be faster than INDEX SCAN or there is no |
857 | + suitable index present. |
858 | + Note, that create_sort_index calls test_if_skip_sort_order and may |
859 | + finally replace sorting with index scan if there is a LIMIT clause in |
860 | + the query. XXX: it's never shown in EXPLAIN! |
861 | + OPTION_FOUND_ROWS supersedes LIMIT and is taken into account. |
862 | */ |
863 | if (create_sort_index(session, curr_join, |
864 | curr_join->group_list ? |
865 | @@ -2491,7 +2467,8 @@ |
866 | (select_options & OPTION_FOUND_ROWS ? |
867 | HA_POS_ERROR : unit->select_limit_cnt), |
868 | curr_join->group_list ? true : false)) |
869 | - return; |
870 | + return; |
871 | + |
872 | sortorder= curr_join->sortorder; |
873 | if (curr_join->const_tables != curr_join->tables && |
874 | !curr_join->join_tab[curr_join->const_tables].table->sort.io_cache) |
875 | @@ -2514,13 +2491,11 @@ |
876 | curr_join->having= curr_join->tmp_having; |
877 | curr_join->fields= curr_fields_list; |
878 | |
879 | - { |
880 | - session->set_proc_info("Sending data"); |
881 | - result->send_fields(*curr_fields_list, |
882 | - Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); |
883 | - error= do_select(curr_join, curr_fields_list, NULL); |
884 | - session->limit_found_rows= curr_join->send_records; |
885 | - } |
886 | + session->set_proc_info("Sending data"); |
887 | + result->send_fields(*curr_fields_list, |
888 | + Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); |
889 | + error= do_select(curr_join, curr_fields_list, NULL); |
890 | + session->limit_found_rows= curr_join->send_records; |
891 | |
892 | /* Accumulate the counts from all join iterations of all join parts. */ |
893 | session->examined_row_count+= curr_join->examined_rows; |
894 | @@ -2530,24 +2505,19 @@ |
895 | for a derived table which is always materialized. |
896 | Otherwise we would not be able to print the query correctly. |
897 | */ |
898 | - if (items0 && |
899 | - (session->lex->describe & DESCRIBE_EXTENDED) && |
900 | - select_lex->linkage == DERIVED_TABLE_TYPE) |
901 | + if (items0 && (session->lex->describe & DESCRIBE_EXTENDED) && select_lex->linkage == DERIVED_TABLE_TYPE) |
902 | set_items_ref_array(items0); |
903 | |
904 | return; |
905 | } |
906 | |
907 | - |
908 | /** |
909 | Clean up join. |
910 | |
911 | @return |
912 | Return error that hold JOIN. |
913 | */ |
914 | - |
915 | -int |
916 | -JOIN::destroy() |
917 | +int JOIN::destroy() |
918 | { |
919 | select_lex->join= 0; |
920 | |
921 | @@ -2557,7 +2527,7 @@ |
922 | { |
923 | JOIN_TAB *tab, *end; |
924 | for (tab= join_tab, end= tab+tables ; tab != end ; tab++) |
925 | - tab->cleanup(); |
926 | + tab->cleanup(); |
927 | } |
928 | tmp_join->tmp_join= 0; |
929 | tmp_table_param.copy_field=0; |
930 | @@ -2575,8 +2545,6 @@ |
931 | return(error); |
932 | } |
933 | |
934 | - |
935 | - |
936 | /** |
937 | An entry point to single-unit select (a select without UNION). |
938 | |
939 | @@ -3162,7 +3130,6 @@ |
940 | return(false); |
941 | } |
942 | |
943 | - |
944 | /** |
945 | Setup for execution all subqueries of a query, for which the optimizer |
946 | chose hash semi-join. |
947 | @@ -3185,7 +3152,6 @@ |
948 | @retval false success. |
949 | @retval true error occurred. |
950 | */ |
951 | - |
952 | bool JOIN::setup_subquery_materialization() |
953 | { |
954 | for (Select_Lex_Unit *un= select_lex->first_inner_unit(); un; |
955 | @@ -3812,28 +3778,28 @@ |
956 | select->quick=0; |
957 | if (records == 0 && s->table->reginfo.impossible_range) |
958 | { |
959 | - /* |
960 | - Impossible WHERE or ON expression |
961 | - In case of ON, we mark that the we match one empty NULL row. |
962 | - In case of WHERE, don't set found_const_table_map to get the |
963 | - caller to abort with a zero row result. |
964 | - */ |
965 | - join->const_table_map|= s->table->map; |
966 | - set_position(join,const_count++,s,(KEYUSE*) 0); |
967 | - s->type= JT_CONST; |
968 | - if (*s->on_expr_ref) |
969 | - { |
970 | - /* Generate empty row */ |
971 | - s->info= "Impossible ON condition"; |
972 | - found_const_table_map|= s->table->map; |
973 | - s->type= JT_CONST; |
974 | - mark_as_null_row(s->table); // All fields are NULL |
975 | - } |
976 | + /* |
977 | + Impossible WHERE or ON expression |
978 | + In case of ON, we mark that the we match one empty NULL row. |
979 | + In case of WHERE, don't set found_const_table_map to get the |
980 | + caller to abort with a zero row result. |
981 | + */ |
982 | + join->const_table_map|= s->table->map; |
983 | + set_position(join,const_count++,s,(KEYUSE*) 0); |
984 | + s->type= JT_CONST; |
985 | + if (*s->on_expr_ref) |
986 | + { |
987 | + /* Generate empty row */ |
988 | + s->info= "Impossible ON condition"; |
989 | + found_const_table_map|= s->table->map; |
990 | + s->type= JT_CONST; |
991 | + mark_as_null_row(s->table); // All fields are NULL |
992 | + } |
993 | } |
994 | if (records != HA_POS_ERROR) |
995 | { |
996 | - s->found_records=records; |
997 | - s->read_time= (ha_rows) (s->quick ? s->quick->read_time : 0.0); |
998 | + s->found_records=records; |
999 | + s->read_time= (ha_rows) (s->quick ? s->quick->read_time : 0.0); |
1000 | } |
1001 | delete select; |
1002 | } |
1003 | |
1004 | === modified file 'tests/r/strict.result' |
1005 | --- tests/r/strict.result 2009-02-28 18:17:29 +0000 |
1006 | +++ tests/r/strict.result 2009-03-16 15:20:27 +0000 |
1007 | @@ -239,25 +239,22 @@ |
1008 | CREATE TABLE t1 (col1 enum('red','blue','green')); |
1009 | INSERT INTO t1 VALUES ('red'),('blue'),('green'); |
1010 | INSERT INTO t1 (col1) VALUES ('yellow'); |
1011 | -ERROR 01000: Data truncated for column 'col1' at row 1 |
1012 | +ERROR HY000: Received an invalid enum value 'yellow'. |
1013 | INSERT INTO t1 (col1) VALUES ('redd'); |
1014 | -ERROR 01000: Data truncated for column 'col1' at row 1 |
1015 | +ERROR HY000: Received an invalid enum value 'redd'. |
1016 | INSERT INTO t1 VALUES (''); |
1017 | -ERROR 01000: Data truncated for column 'col1' at row 1 |
1018 | +ERROR HY000: Received an invalid enum value ''. |
1019 | UPDATE t1 SET col1 ='yellow' WHERE col1 ='green'; |
1020 | -ERROR 01000: Data truncated for column 'col1' at row 3 |
1021 | +ERROR HY000: Received an invalid enum value 'yellow'. |
1022 | INSERT IGNORE INTO t1 VALUES ('yellow'); |
1023 | -Warnings: |
1024 | -Warning 1265 Data truncated for column 'col1' at row 1 |
1025 | +ERROR HY000: Received an invalid enum value 'yellow'. |
1026 | UPDATE IGNORE t1 SET col1 ='yellow' WHERE col1 ='blue'; |
1027 | -Warnings: |
1028 | -Warning 1265 Data truncated for column 'col1' at row 2 |
1029 | +ERROR HY000: Received an invalid enum value 'yellow'. |
1030 | SELECT * FROM t1; |
1031 | col1 |
1032 | red |
1033 | - |
1034 | +blue |
1035 | green |
1036 | - |
1037 | DROP TABLE t1; |
1038 | CREATE TABLE t1 (col1 INT NOT NULL, col2 CHAR(5) NOT NULL, col3 DATE NOT NULL); |
1039 | INSERT INTO t1 VALUES (100, 'hello', '2004-08-20'); |
1040 | |
1041 | === modified file 'tests/r/type_enum.result' |
1042 | --- tests/r/type_enum.result 2009-03-03 21:05:10 +0000 |
1043 | +++ tests/r/type_enum.result 2009-03-16 15:20:27 +0000 |
1044 | @@ -1638,7 +1638,7 @@ |
1045 | drop table t1; |
1046 | create table t1 (a enum ('0','1')); |
1047 | insert into t1 set a='foobar'; |
1048 | -ERROR 01000: Data truncated for column 'a' at row 1 |
1049 | +ERROR HY000: Received an invalid enum value 'foobar'. |
1050 | select * from t1; |
1051 | a |
1052 | update t1 set a = replace(a,'x','y'); |
1053 | @@ -1723,34 +1723,34 @@ |
1054 | c1 ENUM('a', '', 'b') |
1055 | ); |
1056 | INSERT INTO t1 (c1) VALUES (0), ('a'), (''), ('b'); |
1057 | -ERROR 01000: Data truncated for column 'c1' at row 1 |
1058 | +ERROR HY000: Received an invalid enum value '0'. |
1059 | INSERT INTO t1 (c1) VALUES (0), ('a'), (''), ('b'); |
1060 | -ERROR 01000: Data truncated for column 'c1' at row 1 |
1061 | +ERROR HY000: Received an invalid enum value '0'. |
1062 | INSERT INTO t1 (c1) VALUES ('a'), ('b'); |
1063 | SELECT id, c1 + 0, c1 FROM t1; |
1064 | id c1 + 0 c1 |
1065 | 1 1 a |
1066 | 2 3 b |
1067 | ALTER TABLE t1 CHANGE c1 c1 ENUM('a', '') NOT NULL; |
1068 | -ERROR 01000: Data truncated for column 'c1' at row 2 |
1069 | +ERROR HY000: Received an invalid enum value 'b'. |
1070 | ALTER TABLE t1 CHANGE c1 c1 ENUM('a', 'b') NOT NULL; |
1071 | SELECT id, c1 + 0, c1 FROM t1; |
1072 | id c1 + 0 c1 |
1073 | 1 1 a |
1074 | -2 2 b |
1075 | +2 1 a |
1076 | DROP TABLE t1; |
1077 | End of 4.1 tests |
1078 | create table t1(f1 enum('a','b'), index(f1)); |
1079 | insert into t1 values(''),(''),('a'),('b'); |
1080 | -ERROR 01000: Data truncated for column 'f1' at row 1 |
1081 | +ERROR HY000: Received an invalid enum value ''. |
1082 | select * from t1 where f1=''; |
1083 | -f1 |
1084 | +ERROR HY000: Received an invalid enum value ''. |
1085 | drop table t1; |
1086 | CREATE TABLE t1 (c1 ENUM('a', '', 'b')); |
1087 | INSERT INTO t1 (c1) VALUES ('b'); |
1088 | INSERT INTO t1 (c1) VALUES (''); |
1089 | INSERT INTO t1 (c1) VALUES (0); |
1090 | -ERROR 01000: Data truncated for column 'c1' at row 1 |
1091 | +ERROR HY000: Received an invalid enum value '0'. |
1092 | INSERT INTO t1 (c1) VALUES ('a'); |
1093 | SELECT c1 + 0, COUNT(c1) FROM t1 GROUP BY c1; |
1094 | c1 + 0 COUNT(c1) |
1095 | @@ -1766,7 +1766,7 @@ |
1096 | DROP TABLE t1,t2; |
1097 | CREATE TABLE t1(a enum('a','b','c','d')); |
1098 | INSERT INTO t1 VALUES (4),(1),(0),(3); |
1099 | -ERROR 01000: Data truncated for column 'a' at row 3 |
1100 | +ERROR HY000: Received an invalid enum value '0'. |
1101 | INSERT INTO t1 VALUES (4),(1),(2),(3); |
1102 | SELECT a FROM t1; |
1103 | a |
1104 | @@ -1781,9 +1781,8 @@ |
1105 | a |
1106 | ALTER TABLE t1 ADD PRIMARY KEY (a); |
1107 | EXPLAIN SELECT a FROM t1 WHERE a=0; |
1108 | -id select_type table type possible_keys key key_len ref rows Extra |
1109 | -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables |
1110 | +ERROR HY000: Received an invalid enum value '0'. |
1111 | SELECT a FROM t1 WHERE a=0; |
1112 | -a |
1113 | +ERROR HY000: Received an invalid enum value '0'. |
1114 | DROP TABLE t1; |
1115 | End of 5.1 tests |
1116 | |
1117 | === modified file 'tests/r/type_ranges.result' |
1118 | --- tests/r/type_ranges.result 2009-02-28 17:48:22 +0000 |
1119 | +++ tests/r/type_ranges.result 2009-03-16 15:20:27 +0000 |
1120 | @@ -87,7 +87,7 @@ |
1121 | insert into t1 values (0,1/3,3,3,3,3,3,3,3,3,3,3,3,3,NULL,'19970303','19970303101010','','','','3',3,3); |
1122 | ERROR 22001: Data too long for column 'string' at row 1 |
1123 | insert into t1 values (0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,NULL,19970807,19970403090807,-1,-1,-1,'-1',-1,-1); |
1124 | -ERROR 01000: Data truncated for column 'options' at row 1 |
1125 | +ERROR HY000: Received an invalid enum value '-1'. |
1126 | insert into t1 values (0,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,NULL,0,0,-4294967295,-4294967295,-4294967295,'-4294967295',0,"tree"); |
1127 | ERROR 22001: Data too long for column 'string' at row 1 |
1128 | insert into t1 values (0,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,NULL,0,0,4294967295,4294967295,4294967295,'4294967295',0,0); |
1129 | |
1130 | === modified file 'tests/r/union.result' |
1131 | --- tests/r/union.result 2009-02-28 20:43:31 +0000 |
1132 | +++ tests/r/union.result 2009-03-16 15:20:27 +0000 |
1133 | @@ -979,7 +979,7 @@ |
1134 | create table t4 (a ENUM('aaa', 'bbb') NOT NULL); |
1135 | insert into t3 values (1); |
1136 | insert into t4 values (3); |
1137 | -ERROR 01000: Data truncated for column 'a' at row 1 |
1138 | +ERROR HY000: Received an invalid enum value '3'. |
1139 | select "1" as a union select a from t1; |
1140 | a |
1141 | 1 |
1142 | |
1143 | === modified file 'tests/t/strict.test' |
1144 | --- tests/t/strict.test 2009-02-21 16:00:06 +0000 |
1145 | +++ tests/t/strict.test 2009-03-16 15:20:27 +0000 |
1146 | @@ -169,15 +169,17 @@ |
1147 | |
1148 | CREATE TABLE t1 (col1 enum('red','blue','green')); |
1149 | INSERT INTO t1 VALUES ('red'),('blue'),('green'); |
1150 | ---error 1265 |
1151 | +--error 1691 # Bad enum |
1152 | INSERT INTO t1 (col1) VALUES ('yellow'); |
1153 | ---error 1265 |
1154 | +--error 1691 # Bad enum |
1155 | INSERT INTO t1 (col1) VALUES ('redd'); |
1156 | ---error 1265 |
1157 | +--error 1691 # Bad enum |
1158 | INSERT INTO t1 VALUES (''); |
1159 | ---error 1265 |
1160 | +--error 1691 # Bad enum |
1161 | UPDATE t1 SET col1 ='yellow' WHERE col1 ='green'; |
1162 | +--error 1691 # Bad enum |
1163 | INSERT IGNORE INTO t1 VALUES ('yellow'); |
1164 | +--error 1691 # Bad enum |
1165 | UPDATE IGNORE t1 SET col1 ='yellow' WHERE col1 ='blue'; |
1166 | SELECT * FROM t1; |
1167 | DROP TABLE t1; |
1168 | |
1169 | === modified file 'tests/t/type_enum.test' |
1170 | --- tests/t/type_enum.test 2009-03-03 03:03:39 +0000 |
1171 | +++ tests/t/type_enum.test 2009-03-16 15:20:27 +0000 |
1172 | @@ -30,7 +30,7 @@ |
1173 | # |
1174 | |
1175 | create table t1 (a enum ('0','1')); |
1176 | ---error 1265 Data truncated for column a |
1177 | +--error 1691 # Bad enum |
1178 | insert into t1 set a='foobar'; |
1179 | select * from t1; |
1180 | update t1 set a = replace(a,'x','y'); |
1181 | @@ -163,15 +163,16 @@ |
1182 | id INT AUTO_INCREMENT PRIMARY KEY, |
1183 | c1 ENUM('a', '', 'b') |
1184 | ); |
1185 | ---error 1265 |
1186 | +--error 1691 # 0 is not valid way to insert. Must use 1-based index of key. |
1187 | INSERT INTO t1 (c1) VALUES (0), ('a'), (''), ('b'); |
1188 | ---error 1265 |
1189 | +--error 1691 # 0 is not valid way to insert. Must use 1-based index of key. |
1190 | INSERT INTO t1 (c1) VALUES (0), ('a'), (''), ('b'); |
1191 | INSERT INTO t1 (c1) VALUES ('a'), ('b'); |
1192 | SELECT id, c1 + 0, c1 FROM t1; |
1193 | |
1194 | ---error 1265 |
1195 | +--error 1691 # Bad en |
1196 | ALTER TABLE t1 CHANGE c1 c1 ENUM('a', '') NOT NULL; |
1197 | +# Below works because '' was not inserted in any statement above... |
1198 | ALTER TABLE t1 CHANGE c1 c1 ENUM('a', 'b') NOT NULL; |
1199 | SELECT id, c1 + 0, c1 FROM t1; |
1200 | |
1201 | @@ -183,8 +184,9 @@ |
1202 | # Bug#28729: Field_enum wrongly reported an error while storing an empty string. |
1203 | # |
1204 | create table t1(f1 enum('a','b'), index(f1)); |
1205 | ---error 1265 |
1206 | +--error 1691 # Bad enum |
1207 | insert into t1 values(''),(''),('a'),('b'); |
1208 | +--error 1691 # Bad enum |
1209 | select * from t1 where f1=''; |
1210 | drop table t1; |
1211 | |
1212 | @@ -196,7 +198,7 @@ |
1213 | CREATE TABLE t1 (c1 ENUM('a', '', 'b')); |
1214 | INSERT INTO t1 (c1) VALUES ('b'); |
1215 | INSERT INTO t1 (c1) VALUES (''); |
1216 | ---error 1265 |
1217 | +--error 1691 # Bad enum 0 |
1218 | INSERT INTO t1 (c1) VALUES (0); |
1219 | INSERT INTO t1 (c1) VALUES ('a'); |
1220 | |
1221 | @@ -212,18 +214,28 @@ |
1222 | # |
1223 | |
1224 | CREATE TABLE t1(a enum('a','b','c','d')); |
1225 | ---error 1265 Data truncated for column 'a' at row 3 |
1226 | +--error 1691 # Bad enum 0 |
1227 | INSERT INTO t1 VALUES (4),(1),(0),(3); |
1228 | INSERT INTO t1 VALUES (4),(1),(2),(3); |
1229 | |
1230 | SELECT a FROM t1; |
1231 | |
1232 | +# @TODO There is currently no way to fix the below |
1233 | +# oddity. Basically, Field_enum::store() is *only* called |
1234 | +# when there is key information for the ENUM in select_describe() |
1235 | +# and therefore, when Field_enum::store() is called for 0, it |
1236 | +# throws an error, but only when there is an ENUM primary key. |
1237 | +# |
1238 | +# This should go away entirely when we get rid of the Field::store() |
1239 | +# mess in the optimizer with value objects. |
1240 | EXPLAIN SELECT a FROM t1 WHERE a=0; |
1241 | SELECT a FROM t1 WHERE a=0; |
1242 | |
1243 | ALTER TABLE t1 ADD PRIMARY KEY (a); |
1244 | |
1245 | +--error 1691 # Bad enum 0 |
1246 | EXPLAIN SELECT a FROM t1 WHERE a=0; |
1247 | +--error 1691 # Bad enum 0 |
1248 | SELECT a FROM t1 WHERE a=0; |
1249 | |
1250 | DROP TABLE t1; |
1251 | |
1252 | === modified file 'tests/t/type_ranges.test' |
1253 | --- tests/t/type_ranges.test 2009-02-21 16:00:06 +0000 |
1254 | +++ tests/t/type_ranges.test 2009-03-16 15:20:27 +0000 |
1255 | @@ -59,7 +59,7 @@ |
1256 | insert into t1 values (NULL,2,2,2,2,2,2,2,2,2,2,2,2,2,NULL,NULL,NULL,NULL,NULL,2,2,'two','one'); |
1257 | --error 1406 |
1258 | insert into t1 values (0,1/3,3,3,3,3,3,3,3,3,3,3,3,3,NULL,'19970303','19970303101010','','','','3',3,3); |
1259 | ---error 1265 |
1260 | +--error 1691 # Bad enum |
1261 | insert into t1 values (0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,NULL,19970807,19970403090807,-1,-1,-1,'-1',-1,-1); |
1262 | --error 1406 |
1263 | insert into t1 values (0,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,NULL,0,0,-4294967295,-4294967295,-4294967295,'-4294967295',0,"tree"); |
1264 | |
1265 | === modified file 'tests/t/union.test' |
1266 | --- tests/t/union.test 2009-02-28 20:43:31 +0000 |
1267 | +++ tests/t/union.test 2009-03-16 15:20:27 +0000 |
1268 | @@ -573,7 +573,7 @@ |
1269 | create table t3 (a ENUM('Yes', 'No') NOT NULL); |
1270 | create table t4 (a ENUM('aaa', 'bbb') NOT NULL); |
1271 | insert into t3 values (1); |
1272 | ---error 1265 |
1273 | +--error 1691 # Bad enum |
1274 | insert into t4 values (3); |
1275 | select "1" as a union select a from t1; |
1276 | select a as a from t1 union select "1"; |
Fixes error control on ENUM field type