mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / sql / partition_info.cc
blob6f1f7adcaf9e32ad089ffaac2f14f0bd9a2d1daa
1 /*
2 Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
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.
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.
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 St, Fifth Floor, Boston, MA 02110-1301 USA
18 /* Some general useful functions */
20 #ifdef USE_PRAGMA_IMPLEMENTATION
21 #pragma implementation
22 #endif
24 #include "mysql_priv.h"
26 #ifdef WITH_PARTITION_STORAGE_ENGINE
27 #include "ha_partition.h"
30 partition_info *partition_info::get_clone()
32 if (!this)
33 return 0;
34 List_iterator<partition_element> part_it(partitions);
35 partition_element *part;
36 partition_info *clone= new partition_info();
37 if (!clone)
39 mem_alloc_error(sizeof(partition_info));
40 return NULL;
42 memcpy(clone, this, sizeof(partition_info));
43 clone->partitions.empty();
45 while ((part= (part_it++)))
47 List_iterator<partition_element> subpart_it(part->subpartitions);
48 partition_element *subpart;
49 partition_element *part_clone= new partition_element();
50 if (!part_clone)
52 mem_alloc_error(sizeof(partition_element));
53 return NULL;
55 memcpy(part_clone, part, sizeof(partition_element));
56 part_clone->subpartitions.empty();
57 while ((subpart= (subpart_it++)))
59 partition_element *subpart_clone= new partition_element();
60 if (!subpart_clone)
62 mem_alloc_error(sizeof(partition_element));
63 return NULL;
65 memcpy(subpart_clone, subpart, sizeof(partition_element));
66 part_clone->subpartitions.push_back(subpart_clone);
68 clone->partitions.push_back(part_clone);
70 return clone;
74 Create a memory area where default partition names are stored and fill it
75 up with the names.
77 SYNOPSIS
78 create_default_partition_names()
79 part_no Partition number for subparts
80 no_parts Number of partitions
81 start_no Starting partition number
82 subpart Is it subpartitions
84 RETURN VALUE
85 A pointer to the memory area of the default partition names
87 DESCRIPTION
88 A support routine for the partition code where default values are
89 generated.
90 The external routine needing this code is check_partition_info
93 #define MAX_PART_NAME_SIZE 8
95 char *partition_info::create_default_partition_names(uint part_no,
96 uint no_parts_arg,
97 uint start_no)
99 char *ptr= (char*) sql_calloc(no_parts_arg*MAX_PART_NAME_SIZE);
100 char *move_ptr= ptr;
101 uint i= 0;
102 DBUG_ENTER("create_default_partition_names");
104 if (likely(ptr != 0))
108 sprintf(move_ptr, "p%u", (start_no + i));
109 move_ptr+= MAX_PART_NAME_SIZE;
110 } while (++i < no_parts_arg);
112 else
114 mem_alloc_error(no_parts_arg*MAX_PART_NAME_SIZE);
116 DBUG_RETURN(ptr);
121 Create a unique name for the subpartition as part_name'sp''subpart_no'
122 SYNOPSIS
123 create_subpartition_name()
124 subpart_no Number of subpartition
125 part_name Name of partition
126 RETURN VALUES
127 >0 A reference to the created name string
128 0 Memory allocation error
131 char *partition_info::create_subpartition_name(uint subpart_no,
132 const char *part_name)
134 uint size_alloc= strlen(part_name) + MAX_PART_NAME_SIZE;
135 char *ptr= (char*) sql_calloc(size_alloc);
136 DBUG_ENTER("create_subpartition_name");
138 if (likely(ptr != NULL))
140 my_snprintf(ptr, size_alloc, "%ssp%u", part_name, subpart_no);
142 else
144 mem_alloc_error(size_alloc);
146 DBUG_RETURN(ptr);
151 Set up all the default partitions not set-up by the user in the SQL
152 statement. Also perform a number of checks that the user hasn't tried
153 to use default values where no defaults exists.
155 SYNOPSIS
156 set_up_default_partitions()
157 file A reference to a handler of the table
158 info Create info
159 start_no Starting partition number
161 RETURN VALUE
162 TRUE Error, attempted default values not possible
163 FALSE Ok, default partitions set-up
165 DESCRIPTION
166 The routine uses the underlying handler of the partitioning to define
167 the default number of partitions. For some handlers this requires
168 knowledge of the maximum number of rows to be stored in the table.
169 This routine only accepts HASH and KEY partitioning and thus there is
170 no subpartitioning if this routine is successful.
171 The external routine needing this code is check_partition_info
174 bool partition_info::set_up_default_partitions(handler *file,
175 HA_CREATE_INFO *info,
176 uint start_no)
178 uint i;
179 char *default_name;
180 bool result= TRUE;
181 DBUG_ENTER("partition_info::set_up_default_partitions");
183 if (part_type != HASH_PARTITION)
185 const char *error_string;
186 if (part_type == RANGE_PARTITION)
187 error_string= partition_keywords[PKW_RANGE].str;
188 else
189 error_string= partition_keywords[PKW_LIST].str;
190 my_error(ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0), error_string);
191 goto end;
194 if ((no_parts == 0) &&
195 ((no_parts= file->get_default_no_partitions(info)) == 0))
197 my_error(ER_PARTITION_NOT_DEFINED_ERROR, MYF(0), "partitions");
198 goto end;
201 if (unlikely(no_parts > MAX_PARTITIONS))
203 my_error(ER_TOO_MANY_PARTITIONS_ERROR, MYF(0));
204 goto end;
206 if (unlikely((!(default_name= create_default_partition_names(0, no_parts,
207 start_no)))))
208 goto end;
209 i= 0;
212 partition_element *part_elem= new partition_element();
213 if (likely(part_elem != 0 &&
214 (!partitions.push_back(part_elem))))
216 part_elem->engine_type= default_engine_type;
217 part_elem->partition_name= default_name;
218 default_name+=MAX_PART_NAME_SIZE;
220 else
222 mem_alloc_error(sizeof(partition_element));
223 goto end;
225 } while (++i < no_parts);
226 result= FALSE;
227 end:
228 DBUG_RETURN(result);
233 Set up all the default subpartitions not set-up by the user in the SQL
234 statement. Also perform a number of checks that the default partitioning
235 becomes an allowed partitioning scheme.
237 SYNOPSIS
238 set_up_default_subpartitions()
239 file A reference to a handler of the table
240 info Create info
242 RETURN VALUE
243 TRUE Error, attempted default values not possible
244 FALSE Ok, default partitions set-up
246 DESCRIPTION
247 The routine uses the underlying handler of the partitioning to define
248 the default number of partitions. For some handlers this requires
249 knowledge of the maximum number of rows to be stored in the table.
250 This routine is only called for RANGE or LIST partitioning and those
251 need to be specified so only subpartitions are specified.
252 The external routine needing this code is check_partition_info
255 bool partition_info::set_up_default_subpartitions(handler *file,
256 HA_CREATE_INFO *info)
258 uint i, j;
259 bool result= TRUE;
260 partition_element *part_elem;
261 List_iterator<partition_element> part_it(partitions);
262 DBUG_ENTER("partition_info::set_up_default_subpartitions");
264 if (no_subparts == 0)
265 no_subparts= file->get_default_no_partitions(info);
266 if (unlikely((no_parts * no_subparts) > MAX_PARTITIONS))
268 my_error(ER_TOO_MANY_PARTITIONS_ERROR, MYF(0));
269 goto end;
271 i= 0;
274 part_elem= part_it++;
275 j= 0;
278 partition_element *subpart_elem= new partition_element(part_elem);
279 if (likely(subpart_elem != 0 &&
280 (!part_elem->subpartitions.push_back(subpart_elem))))
282 char *ptr= create_subpartition_name(j, part_elem->partition_name);
283 if (!ptr)
284 goto end;
285 subpart_elem->engine_type= default_engine_type;
286 subpart_elem->partition_name= ptr;
288 else
290 mem_alloc_error(sizeof(partition_element));
291 goto end;
293 } while (++j < no_subparts);
294 } while (++i < no_parts);
295 result= FALSE;
296 end:
297 DBUG_RETURN(result);
302 Support routine for check_partition_info
304 SYNOPSIS
305 set_up_defaults_for_partitioning()
306 file A reference to a handler of the table
307 info Create info
308 start_no Starting partition number
310 RETURN VALUE
311 TRUE Error, attempted default values not possible
312 FALSE Ok, default partitions set-up
314 DESCRIPTION
315 Set up defaults for partition or subpartition (cannot set-up for both,
316 this will return an error.
319 bool partition_info::set_up_defaults_for_partitioning(handler *file,
320 HA_CREATE_INFO *info,
321 uint start_no)
323 DBUG_ENTER("partition_info::set_up_defaults_for_partitioning");
325 if (!default_partitions_setup)
327 default_partitions_setup= TRUE;
328 if (use_default_partitions)
329 DBUG_RETURN(set_up_default_partitions(file, info, start_no));
330 if (is_sub_partitioned() &&
331 use_default_subpartitions)
332 DBUG_RETURN(set_up_default_subpartitions(file, info));
334 DBUG_RETURN(FALSE);
339 A support function to check if a partition element's name is unique
341 SYNOPSIS
342 has_unique_name()
343 partition_element element to check
345 RETURN VALUES
346 TRUE Has unique name
347 FALSE Doesn't
350 bool partition_info::has_unique_name(partition_element *element)
352 DBUG_ENTER("partition_info::has_unique_name");
354 const char *name_to_check= element->partition_name;
355 List_iterator<partition_element> parts_it(partitions);
357 partition_element *el;
358 while ((el= (parts_it++)))
360 if (!(my_strcasecmp(system_charset_info, el->partition_name,
361 name_to_check)) && el != element)
362 DBUG_RETURN(FALSE);
364 if (!el->subpartitions.is_empty())
366 partition_element *sub_el;
367 List_iterator<partition_element> subparts_it(el->subpartitions);
368 while ((sub_el= (subparts_it++)))
370 if (!(my_strcasecmp(system_charset_info, sub_el->partition_name,
371 name_to_check)) && sub_el != element)
372 DBUG_RETURN(FALSE);
376 DBUG_RETURN(TRUE);
381 A support function to check partition names for duplication in a
382 partitioned table
384 SYNOPSIS
385 has_unique_names()
387 RETURN VALUES
388 TRUE Has unique part and subpart names
389 FALSE Doesn't
391 DESCRIPTION
392 Checks that the list of names in the partitions doesn't contain any
393 duplicated names.
396 char *partition_info::has_unique_names()
398 DBUG_ENTER("partition_info::has_unique_names");
400 List_iterator<partition_element> parts_it(partitions);
402 partition_element *el;
403 while ((el= (parts_it++)))
405 if (! has_unique_name(el))
406 DBUG_RETURN(el->partition_name);
408 if (!el->subpartitions.is_empty())
410 List_iterator<partition_element> subparts_it(el->subpartitions);
411 partition_element *subel;
412 while ((subel= (subparts_it++)))
414 if (! has_unique_name(subel))
415 DBUG_RETURN(subel->partition_name);
419 DBUG_RETURN(NULL);
424 Check that the partition/subpartition is setup to use the correct
425 storage engine
426 SYNOPSIS
427 check_engine_condition()
428 p_elem Partition element
429 table_engine_set Have user specified engine on table level
430 inout::engine_type Current engine used
431 inout::first Is it first partition
432 RETURN VALUE
433 TRUE Failed check
434 FALSE Ok
435 DESCRIPTION
436 Specified engine for table and partitions p0 and pn
437 Must be correct both on CREATE and ALTER commands
438 table p0 pn res (0 - OK, 1 - FAIL)
439 - - - 0
440 - - x 1
441 - x - 1
442 - x x 0
443 x - - 0
444 x - x 0
445 x x - 0
446 x x x 0
447 i.e:
448 - All subpartitions must use the same engine
449 AND it must be the same as the partition.
450 - All partitions must use the same engine
451 AND it must be the same as the table.
452 - if one does NOT specify an engine on the table level
453 then one must either NOT specify any engine on any
454 partition/subpartition OR for ALL partitions/subpartitions
455 Note:
456 When ALTER a table, the engines are already set for all levels
457 (table, all partitions and subpartitions). So if one want to
458 change the storage engine, one must specify it on the table level
462 static bool check_engine_condition(partition_element *p_elem,
463 bool table_engine_set,
464 handlerton **engine_type,
465 bool *first)
467 DBUG_ENTER("check_engine_condition");
469 DBUG_PRINT("enter", ("p_eng %s t_eng %s t_eng_set %u first %u state %u",
470 ha_resolve_storage_engine_name(p_elem->engine_type),
471 ha_resolve_storage_engine_name(*engine_type),
472 table_engine_set, *first, p_elem->part_state));
473 if (*first && !table_engine_set)
475 *engine_type= p_elem->engine_type;
476 DBUG_PRINT("info", ("setting table_engine = %s",
477 ha_resolve_storage_engine_name(*engine_type)));
479 *first= FALSE;
480 if ((table_engine_set &&
481 (p_elem->engine_type != (*engine_type) &&
482 p_elem->engine_type)) ||
483 (!table_engine_set &&
484 p_elem->engine_type != (*engine_type)))
486 DBUG_RETURN(TRUE);
489 DBUG_RETURN(FALSE);
494 Check engine mix that it is correct
495 Current limitation is that all partitions and subpartitions
496 must use the same storage engine.
497 SYNOPSIS
498 check_engine_mix()
499 inout::engine_type Current engine used
500 table_engine_set Have user specified engine on table level
501 RETURN VALUE
502 TRUE Error, mixed engines
503 FALSE Ok, no mixed engines
504 DESCRIPTION
505 Current check verifies only that all handlers are the same.
506 Later this check will be more sophisticated.
507 (specified partition handler ) specified table handler
508 (NDB, NDB) NDB OK
509 (MYISAM, MYISAM) - OK
510 (MYISAM, -) - NOT OK
511 (MYISAM, -) MYISAM OK
512 (- , MYISAM) - NOT OK
513 (- , -) MYISAM OK
514 (-,-) - OK
515 (NDB, MYISAM) * NOT OK
518 bool partition_info::check_engine_mix(handlerton *engine_type,
519 bool table_engine_set)
521 handlerton *old_engine_type= engine_type;
522 bool first= TRUE;
523 uint no_parts= partitions.elements;
524 DBUG_ENTER("partition_info::check_engine_mix");
525 DBUG_PRINT("info", ("in: engine_type = %s, table_engine_set = %u",
526 ha_resolve_storage_engine_name(engine_type),
527 table_engine_set));
528 if (no_parts)
530 List_iterator<partition_element> part_it(partitions);
531 uint i= 0;
534 partition_element *part_elem= part_it++;
535 DBUG_PRINT("info", ("part = %d engine = %s table_engine_set %u",
536 i, ha_resolve_storage_engine_name(part_elem->engine_type),
537 table_engine_set));
538 if (is_sub_partitioned() &&
539 part_elem->subpartitions.elements)
541 uint no_subparts= part_elem->subpartitions.elements;
542 uint j= 0;
543 List_iterator<partition_element> sub_it(part_elem->subpartitions);
546 partition_element *sub_elem= sub_it++;
547 DBUG_PRINT("info", ("sub = %d engine = %s table_engie_set %u",
548 j, ha_resolve_storage_engine_name(sub_elem->engine_type),
549 table_engine_set));
550 if (check_engine_condition(sub_elem, table_engine_set,
551 &engine_type, &first))
552 goto error;
553 } while (++j < no_subparts);
554 /* ensure that the partition also has correct engine */
555 if (check_engine_condition(part_elem, table_engine_set,
556 &engine_type, &first))
557 goto error;
559 else if (check_engine_condition(part_elem, table_engine_set,
560 &engine_type, &first))
561 goto error;
562 } while (++i < no_parts);
564 DBUG_PRINT("info", ("engine_type = %s",
565 ha_resolve_storage_engine_name(engine_type)));
566 if (!engine_type)
567 engine_type= old_engine_type;
568 if (engine_type->flags & HTON_NO_PARTITION)
570 my_error(ER_PARTITION_MERGE_ERROR, MYF(0));
571 DBUG_RETURN(TRUE);
573 DBUG_PRINT("info", ("out: engine_type = %s",
574 ha_resolve_storage_engine_name(engine_type)));
575 DBUG_ASSERT(engine_type != partition_hton);
576 DBUG_RETURN(FALSE);
577 error:
579 Mixed engines not yet supported but when supported it will need
580 the partition handler
582 DBUG_RETURN(TRUE);
587 This routine allocates an array for all range constants to achieve a fast
588 check what partition a certain value belongs to. At the same time it does
589 also check that the range constants are defined in increasing order and
590 that the expressions are constant integer expressions.
592 SYNOPSIS
593 check_range_constants()
595 RETURN VALUE
596 TRUE An error occurred during creation of range constants
597 FALSE Successful creation of range constant mapping
599 DESCRIPTION
600 This routine is called from check_partition_info to get a quick error
601 before we came too far into the CREATE TABLE process. It is also called
602 from fix_partition_func every time we open the .frm file. It is only
603 called for RANGE PARTITIONed tables.
606 bool partition_info::check_range_constants()
608 partition_element* part_def;
609 longlong current_largest;
610 longlong part_range_value;
611 bool first= TRUE;
612 uint i;
613 List_iterator<partition_element> it(partitions);
614 bool result= TRUE;
615 bool signed_flag= !part_expr->unsigned_flag;
616 DBUG_ENTER("partition_info::check_range_constants");
617 DBUG_PRINT("enter", ("INT_RESULT with %d parts", no_parts));
619 LINT_INIT(current_largest);
621 part_result_type= INT_RESULT;
622 range_int_array= (longlong*)sql_alloc(no_parts * sizeof(longlong));
623 if (unlikely(range_int_array == NULL))
625 mem_alloc_error(no_parts * sizeof(longlong));
626 goto end;
628 i= 0;
631 part_def= it++;
632 if ((i != (no_parts - 1)) || !defined_max_value)
634 part_range_value= part_def->range_value;
635 if (!signed_flag)
636 part_range_value-= 0x8000000000000000ULL;
638 else
639 part_range_value= LONGLONG_MAX;
640 if (first)
642 current_largest= part_range_value;
643 range_int_array[0]= part_range_value;
644 first= FALSE;
646 else
648 if (likely(current_largest < part_range_value))
650 current_largest= part_range_value;
651 range_int_array[i]= part_range_value;
653 else if (defined_max_value &&
654 current_largest == part_range_value &&
655 part_range_value == LONGLONG_MAX &&
656 i == (no_parts - 1))
658 range_int_array[i]= part_range_value;
660 else
662 my_error(ER_RANGE_NOT_INCREASING_ERROR, MYF(0));
663 goto end;
666 } while (++i < no_parts);
667 result= FALSE;
668 end:
669 DBUG_RETURN(result);
674 Support routines for check_list_constants used by qsort to sort the
675 constant list expressions. One routine for unsigned and one for signed.
677 SYNOPSIS
678 list_part_cmp()
679 a First list constant to compare with
680 b Second list constant to compare with
682 RETURN VALUE
683 +1 a > b
684 0 a == b
685 -1 a < b
688 int partition_info::list_part_cmp(const void* a, const void* b)
690 longlong a1= ((LIST_PART_ENTRY*)a)->list_value;
691 longlong b1= ((LIST_PART_ENTRY*)b)->list_value;
692 if (a1 < b1)
693 return -1;
694 else if (a1 > b1)
695 return +1;
696 else
697 return 0;
702 This routine allocates an array for all list constants to achieve a fast
703 check what partition a certain value belongs to. At the same time it does
704 also check that there are no duplicates among the list constants and that
705 that the list expressions are constant integer expressions.
707 SYNOPSIS
708 check_list_constants()
710 RETURN VALUE
711 TRUE An error occurred during creation of list constants
712 FALSE Successful creation of list constant mapping
714 DESCRIPTION
715 This routine is called from check_partition_info to get a quick error
716 before we came too far into the CREATE TABLE process. It is also called
717 from fix_partition_func every time we open the .frm file. It is only
718 called for LIST PARTITIONed tables.
721 bool partition_info::check_list_constants()
723 uint i;
724 uint list_index= 0;
725 part_elem_value *list_value;
726 bool result= TRUE;
727 longlong curr_value, prev_value, type_add, calc_value;
728 partition_element* part_def;
729 bool found_null= FALSE;
730 List_iterator<partition_element> list_func_it(partitions);
731 DBUG_ENTER("partition_info::check_list_constants");
733 part_result_type= INT_RESULT;
734 no_list_values= 0;
736 We begin by calculating the number of list values that have been
737 defined in the first step.
739 We use this number to allocate a properly sized array of structs
740 to keep the partition id and the value to use in that partition.
741 In the second traversal we assign them values in the struct array.
743 Finally we sort the array of structs in order of values to enable
744 a quick binary search for the proper value to discover the
745 partition id.
746 After sorting the array we check that there are no duplicates in the
747 list.
750 i= 0;
753 part_def= list_func_it++;
754 if (part_def->has_null_value)
756 if (found_null)
758 my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0));
759 goto end;
761 has_null_value= TRUE;
762 has_null_part_id= i;
763 found_null= TRUE;
765 List_iterator<part_elem_value> list_val_it1(part_def->list_val_list);
766 while (list_val_it1++)
767 no_list_values++;
768 } while (++i < no_parts);
769 list_func_it.rewind();
770 list_array= (LIST_PART_ENTRY*)sql_alloc((no_list_values+1) *
771 sizeof(LIST_PART_ENTRY));
772 if (unlikely(list_array == NULL))
774 mem_alloc_error(no_list_values * sizeof(LIST_PART_ENTRY));
775 goto end;
778 i= 0;
780 Fix to be able to reuse signed sort functions also for unsigned
781 partition functions.
783 type_add= (longlong)(part_expr->unsigned_flag ?
784 0x8000000000000000ULL :
785 0ULL);
789 part_def= list_func_it++;
790 List_iterator<part_elem_value> list_val_it2(part_def->list_val_list);
791 while ((list_value= list_val_it2++))
793 calc_value= list_value->value - type_add;
794 list_array[list_index].list_value= calc_value;
795 list_array[list_index++].partition_id= i;
797 } while (++i < no_parts);
799 if (fixed && no_list_values)
801 bool first= TRUE;
802 my_qsort((void*)list_array, no_list_values, sizeof(LIST_PART_ENTRY),
803 &list_part_cmp);
805 i= 0;
806 LINT_INIT(prev_value);
809 DBUG_ASSERT(i < no_list_values);
810 curr_value= list_array[i].list_value;
811 if (likely(first || prev_value != curr_value))
813 prev_value= curr_value;
814 first= FALSE;
816 else
818 my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0));
819 goto end;
821 } while (++i < no_list_values);
823 result= FALSE;
824 end:
825 DBUG_RETURN(result);
830 This code is used early in the CREATE TABLE and ALTER TABLE process.
832 SYNOPSIS
833 check_partition_info()
834 file A reference to a handler of the table
835 info Create info
836 engine_type Return value for used engine in partitions
837 check_partition_function Should we check the partition function
839 RETURN VALUE
840 TRUE Error, something went wrong
841 FALSE Ok, full partition data structures are now generated
843 DESCRIPTION
844 We will check that the partition info requested is possible to set-up in
845 this version. This routine is an extension of the parser one could say.
846 If defaults were used we will generate default data structures for all
847 partitions.
851 bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
852 handler *file, HA_CREATE_INFO *info,
853 bool check_partition_function)
855 handlerton *table_engine= default_engine_type;
856 uint i, tot_partitions;
857 bool result= TRUE, table_engine_set;
858 char *same_name;
859 DBUG_ENTER("partition_info::check_partition_info");
860 DBUG_ASSERT(default_engine_type != partition_hton);
862 DBUG_PRINT("info", ("default table_engine = %s",
863 ha_resolve_storage_engine_name(table_engine)));
864 if (check_partition_function)
866 int err= 0;
868 if (part_type != HASH_PARTITION || !list_of_part_fields)
870 DBUG_ASSERT(part_expr);
871 err= part_expr->walk(&Item::check_partition_func_processor, 0,
872 NULL);
873 if (!err && is_sub_partitioned() && !list_of_subpart_fields)
874 err= subpart_expr->walk(&Item::check_partition_func_processor, 0,
875 NULL);
877 if (err)
879 my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
880 goto end;
883 if (unlikely(!is_sub_partitioned() &&
884 !(use_default_subpartitions && use_default_no_subpartitions)))
886 my_error(ER_SUBPARTITION_ERROR, MYF(0));
887 goto end;
889 if (unlikely(is_sub_partitioned() &&
890 (!(part_type == RANGE_PARTITION ||
891 part_type == LIST_PARTITION))))
893 /* Only RANGE and LIST partitioning can be subpartitioned */
894 my_error(ER_SUBPARTITION_ERROR, MYF(0));
895 goto end;
897 if (unlikely(set_up_defaults_for_partitioning(file, info, (uint)0)))
898 goto end;
899 if (!(tot_partitions= get_tot_partitions()))
901 my_error(ER_PARTITION_NOT_DEFINED_ERROR, MYF(0), "partitions");
902 goto end;
904 if (unlikely(tot_partitions > MAX_PARTITIONS))
906 my_error(ER_TOO_MANY_PARTITIONS_ERROR, MYF(0));
907 goto end;
910 if NOT specified ENGINE = <engine>:
911 If Create, always use create_info->db_type
912 else, use previous tables db_type
913 either ALL or NONE partition should be set to
914 default_engine_type when not table_engine_set
915 Note: after a table is created its storage engines for
916 the table and all partitions/subpartitions are set.
917 So when ALTER it is already set on table level
919 if (info && info->used_fields & HA_CREATE_USED_ENGINE)
921 table_engine_set= TRUE;
922 table_engine= info->db_type;
923 /* if partition_hton, use thd->lex->create_info */
924 if (table_engine == partition_hton)
925 table_engine= thd->lex->create_info.db_type;
926 DBUG_ASSERT(table_engine != partition_hton);
927 DBUG_PRINT("info", ("Using table_engine = %s",
928 ha_resolve_storage_engine_name(table_engine)));
930 else
932 table_engine_set= FALSE;
933 if (thd->lex->sql_command != SQLCOM_CREATE_TABLE)
935 table_engine_set= TRUE;
936 DBUG_PRINT("info", ("No create, table_engine = %s",
937 ha_resolve_storage_engine_name(table_engine)));
938 DBUG_ASSERT(table_engine && table_engine != partition_hton);
942 if ((same_name= has_unique_names()))
944 my_error(ER_SAME_NAME_PARTITION, MYF(0), same_name);
945 goto end;
947 i= 0;
949 List_iterator<partition_element> part_it(partitions);
950 uint no_parts_not_set= 0;
951 uint prev_no_subparts_not_set= no_subparts + 1;
954 partition_element *part_elem= part_it++;
955 #ifdef HAVE_READLINK
956 if (!my_use_symdir || (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE))
957 #endif
959 if (part_elem->data_file_name)
960 push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
961 WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED),
962 "DATA DIRECTORY");
963 if (part_elem->index_file_name)
964 push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
965 WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED),
966 "INDEX DIRECTORY");
967 part_elem->data_file_name= part_elem->index_file_name= NULL;
969 if (!is_sub_partitioned())
971 if (part_elem->engine_type == NULL)
973 no_parts_not_set++;
974 part_elem->engine_type= default_engine_type;
976 if (check_table_name(part_elem->partition_name,
977 strlen(part_elem->partition_name), FALSE))
979 my_error(ER_WRONG_PARTITION_NAME, MYF(0));
980 goto end;
982 DBUG_PRINT("info", ("part = %d engine = %s",
983 i, ha_resolve_storage_engine_name(part_elem->engine_type)));
985 else
987 uint j= 0;
988 uint no_subparts_not_set= 0;
989 List_iterator<partition_element> sub_it(part_elem->subpartitions);
990 partition_element *sub_elem;
993 sub_elem= sub_it++;
994 if (check_table_name(sub_elem->partition_name,
995 strlen(sub_elem->partition_name), FALSE))
997 my_error(ER_WRONG_PARTITION_NAME, MYF(0));
998 goto end;
1000 if (sub_elem->engine_type == NULL)
1002 if (part_elem->engine_type != NULL)
1003 sub_elem->engine_type= part_elem->engine_type;
1004 else
1006 sub_elem->engine_type= default_engine_type;
1007 no_subparts_not_set++;
1010 DBUG_PRINT("info", ("part = %d sub = %d engine = %s", i, j,
1011 ha_resolve_storage_engine_name(sub_elem->engine_type)));
1012 } while (++j < no_subparts);
1014 if (prev_no_subparts_not_set == (no_subparts + 1) &&
1015 (no_subparts_not_set == 0 || no_subparts_not_set == no_subparts))
1016 prev_no_subparts_not_set= no_subparts_not_set;
1018 if (!table_engine_set &&
1019 prev_no_subparts_not_set != no_subparts_not_set)
1021 DBUG_PRINT("info", ("no_subparts_not_set = %u no_subparts = %u",
1022 no_subparts_not_set, no_subparts));
1023 my_error(ER_MIX_HANDLER_ERROR, MYF(0));
1024 goto end;
1027 if (part_elem->engine_type == NULL)
1029 if (no_subparts_not_set == 0)
1030 part_elem->engine_type= sub_elem->engine_type;
1031 else
1033 no_parts_not_set++;
1034 part_elem->engine_type= default_engine_type;
1038 } while (++i < no_parts);
1039 if (!table_engine_set &&
1040 no_parts_not_set != 0 &&
1041 no_parts_not_set != no_parts)
1043 DBUG_PRINT("info", ("no_parts_not_set = %u no_parts = %u",
1044 no_parts_not_set, no_subparts));
1045 my_error(ER_MIX_HANDLER_ERROR, MYF(0));
1046 goto end;
1049 if (unlikely(check_engine_mix(table_engine, table_engine_set)))
1051 my_error(ER_MIX_HANDLER_ERROR, MYF(0));
1052 goto end;
1055 DBUG_ASSERT(table_engine != partition_hton &&
1056 default_engine_type == table_engine);
1057 if (eng_type)
1058 *eng_type= table_engine;
1062 We need to check all constant expressions that they are of the correct
1063 type and that they are increasing for ranges and not overlapping for
1064 list constants.
1067 if (fixed)
1069 if (unlikely((part_type == RANGE_PARTITION && check_range_constants()) ||
1070 (part_type == LIST_PARTITION && check_list_constants())))
1071 goto end;
1073 result= FALSE;
1074 end:
1075 DBUG_RETURN(result);
1080 Print error for no partition found
1082 SYNOPSIS
1083 print_no_partition_found()
1084 table Table object
1086 RETURN VALUES
1089 void partition_info::print_no_partition_found(TABLE *table)
1091 char buf[100];
1092 char *buf_ptr= (char*)&buf;
1093 TABLE_LIST table_list;
1095 bzero(&table_list, sizeof(table_list));
1096 table_list.db= table->s->db.str;
1097 table_list.table_name= table->s->table_name.str;
1099 if (check_single_table_access(current_thd,
1100 SELECT_ACL, &table_list, TRUE))
1101 my_message(ER_NO_PARTITION_FOR_GIVEN_VALUE,
1102 ER(ER_NO_PARTITION_FOR_GIVEN_VALUE_SILENT), MYF(0));
1103 else
1105 my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
1106 if (part_expr->null_value)
1107 buf_ptr= (char*)"NULL";
1108 else
1109 longlong2str(err_value, buf,
1110 part_expr->unsigned_flag ? 10 : -10);
1111 my_error(ER_NO_PARTITION_FOR_GIVEN_VALUE, MYF(0), buf_ptr);
1112 dbug_tmp_restore_column_map(table->read_set, old_map);
1116 Set up buffers and arrays for fields requiring preparation
1117 SYNOPSIS
1118 set_up_charset_field_preps()
1120 RETURN VALUES
1121 TRUE Memory Allocation error
1122 FALSE Success
1124 DESCRIPTION
1125 Set up arrays and buffers for fields that require special care for
1126 calculation of partition id. This is used for string fields with
1127 variable length or string fields with fixed length that isn't using
1128 the binary collation.
1131 bool partition_info::set_up_charset_field_preps()
1133 Field *field, **ptr;
1134 uchar **char_ptrs;
1135 unsigned i;
1136 size_t size;
1137 uint tot_fields= 0;
1138 uint tot_part_fields= 0;
1139 uint tot_subpart_fields= 0;
1140 DBUG_ENTER("set_up_charset_field_preps");
1142 if (!(part_type == HASH_PARTITION &&
1143 list_of_part_fields) &&
1144 check_part_func_fields(part_field_array, FALSE))
1146 ptr= part_field_array;
1147 /* Set up arrays and buffers for those fields */
1148 while ((field= *(ptr++)))
1150 if (field_is_partition_charset(field))
1152 tot_part_fields++;
1153 tot_fields++;
1156 size= tot_part_fields * sizeof(char*);
1157 if (!(char_ptrs= (uchar**)sql_calloc(size)))
1158 goto error;
1159 part_field_buffers= char_ptrs;
1160 if (!(char_ptrs= (uchar**)sql_calloc(size)))
1161 goto error;
1162 restore_part_field_ptrs= char_ptrs;
1163 size= (tot_part_fields + 1) * sizeof(Field*);
1164 if (!(char_ptrs= (uchar**)sql_alloc(size)))
1165 goto error;
1166 part_charset_field_array= (Field**)char_ptrs;
1167 ptr= part_field_array;
1168 i= 0;
1169 while ((field= *(ptr++)))
1171 if (field_is_partition_charset(field))
1173 uchar *field_buf;
1174 size= field->pack_length();
1175 if (!(field_buf= (uchar*) sql_calloc(size)))
1176 goto error;
1177 part_charset_field_array[i]= field;
1178 part_field_buffers[i++]= field_buf;
1181 part_charset_field_array[i]= NULL;
1183 if (is_sub_partitioned() && !list_of_subpart_fields &&
1184 check_part_func_fields(subpart_field_array, FALSE))
1186 /* Set up arrays and buffers for those fields */
1187 ptr= subpart_field_array;
1188 while ((field= *(ptr++)))
1190 if (field_is_partition_charset(field))
1192 tot_subpart_fields++;
1193 tot_fields++;
1196 size= tot_subpart_fields * sizeof(char*);
1197 if (!(char_ptrs= (uchar**) sql_calloc(size)))
1198 goto error;
1199 subpart_field_buffers= char_ptrs;
1200 if (!(char_ptrs= (uchar**) sql_calloc(size)))
1201 goto error;
1202 restore_subpart_field_ptrs= char_ptrs;
1203 size= (tot_subpart_fields + 1) * sizeof(Field*);
1204 if (!(char_ptrs= (uchar**) sql_alloc(size)))
1205 goto error;
1206 subpart_charset_field_array= (Field**)char_ptrs;
1207 ptr= subpart_field_array;
1208 i= 0;
1209 while ((field= *(ptr++)))
1211 uchar *field_buf;
1212 LINT_INIT(field_buf);
1214 if (!field_is_partition_charset(field))
1215 continue;
1216 size= field->pack_length();
1217 if (!(field_buf= (uchar*) sql_calloc(size)))
1218 goto error;
1219 subpart_charset_field_array[i]= field;
1220 subpart_field_buffers[i++]= field_buf;
1222 subpart_charset_field_array[i]= NULL;
1224 if (tot_fields)
1226 uint k;
1227 size= tot_fields*sizeof(char**);
1228 if (!(char_ptrs= (uchar**)sql_calloc(size)))
1229 goto error;
1230 full_part_field_buffers= char_ptrs;
1231 if (!(char_ptrs= (uchar**)sql_calloc(size)))
1232 goto error;
1233 restore_full_part_field_ptrs= char_ptrs;
1234 size= (tot_fields + 1) * sizeof(char**);
1235 if (!(char_ptrs= (uchar**)sql_calloc(size)))
1236 goto error;
1237 full_part_charset_field_array= (Field**)char_ptrs;
1238 for (i= 0; i < tot_part_fields; i++)
1240 full_part_charset_field_array[i]= part_charset_field_array[i];
1241 full_part_field_buffers[i]= part_field_buffers[i];
1243 k= tot_part_fields;
1244 for (i= 0; i < tot_subpart_fields; i++)
1246 uint j;
1247 bool found= FALSE;
1248 field= subpart_charset_field_array[i];
1250 for (j= 0; j < tot_part_fields; j++)
1252 if (field == part_charset_field_array[i])
1253 found= TRUE;
1255 if (!found)
1257 full_part_charset_field_array[k]= subpart_charset_field_array[i];
1258 full_part_field_buffers[k]= subpart_field_buffers[i];
1259 k++;
1262 full_part_charset_field_array[k]= NULL;
1264 DBUG_RETURN(FALSE);
1265 error:
1266 mem_alloc_error(size);
1267 DBUG_RETURN(TRUE);
1272 Check if path does not contain mysql data home directory
1273 for partition elements with data directory and index directory
1275 SYNOPSIS
1276 check_partition_dirs()
1277 part_info partition_info struct
1279 RETURN VALUES
1280 0 ok
1281 1 error
1284 bool check_partition_dirs(partition_info *part_info)
1286 if (!part_info)
1287 return 0;
1289 partition_element *part_elem;
1290 List_iterator<partition_element> part_it(part_info->partitions);
1291 while ((part_elem= part_it++))
1293 if (part_elem->subpartitions.elements)
1295 List_iterator<partition_element> sub_it(part_elem->subpartitions);
1296 partition_element *subpart_elem;
1297 while ((subpart_elem= sub_it++))
1299 if (test_if_data_home_dir(subpart_elem->data_file_name))
1300 goto dd_err;
1301 if (test_if_data_home_dir(subpart_elem->index_file_name))
1302 goto id_err;
1305 else
1307 if (test_if_data_home_dir(part_elem->data_file_name))
1308 goto dd_err;
1309 if (test_if_data_home_dir(part_elem->index_file_name))
1310 goto id_err;
1313 return 0;
1315 dd_err:
1316 my_error(ER_WRONG_ARGUMENTS,MYF(0),"DATA DIRECTORY");
1317 return 1;
1319 id_err:
1320 my_error(ER_WRONG_ARGUMENTS,MYF(0),"INDEX DIRECTORY");
1321 return 1;
1325 #endif /* WITH_PARTITION_STORAGE_ENGINE */