MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
partition_info.cc
1 /* Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
16 /* Some general useful functions */
17 
18 #include "sql_priv.h"
19 // Required to get server definitions for mysql/plugin.h right
20 #include "sql_plugin.h"
21 #include "sql_partition.h" // partition_info.h: LIST_PART_ENTRY
22  // NOT_A_PARTITION_ID
23 #include "partition_info.h"
24 #include "sql_parse.h" // test_if_data_home_dir
25 #include "sql_acl.h" // *_ACL
26 #include "table.h" // TABLE_LIST
27 #include "my_bitmap.h" // bitmap*
28 #include "sql_base.h" // fill_record
29 
30 #ifdef WITH_PARTITION_STORAGE_ENGINE
31 #include "ha_partition.h"
32 
33 
34 partition_info *partition_info::get_clone()
35 {
36  DBUG_ENTER("partition_info::get_clone");
37  if (!this)
38  DBUG_RETURN(NULL);
39  List_iterator<partition_element> part_it(partitions);
40  partition_element *part;
41  partition_info *clone= new partition_info();
42  if (!clone)
43  {
44  mem_alloc_error(sizeof(partition_info));
45  DBUG_RETURN(NULL);
46  }
47  memcpy(clone, this, sizeof(partition_info));
48  memset(&(clone->read_partitions), 0, sizeof(clone->read_partitions));
49  memset(&(clone->lock_partitions), 0, sizeof(clone->lock_partitions));
50  clone->bitmaps_are_initialized= FALSE;
51  clone->partitions.empty();
52 
53  while ((part= (part_it++)))
54  {
55  List_iterator<partition_element> subpart_it(part->subpartitions);
56  partition_element *subpart;
57  partition_element *part_clone= new partition_element();
58  if (!part_clone)
59  {
60  mem_alloc_error(sizeof(partition_element));
61  DBUG_RETURN(NULL);
62  }
63  memcpy(part_clone, part, sizeof(partition_element));
64  part_clone->subpartitions.empty();
65  while ((subpart= (subpart_it++)))
66  {
67  partition_element *subpart_clone= new partition_element();
68  if (!subpart_clone)
69  {
70  mem_alloc_error(sizeof(partition_element));
71  DBUG_RETURN(NULL);
72  }
73  memcpy(subpart_clone, subpart, sizeof(partition_element));
74  part_clone->subpartitions.push_back(subpart_clone);
75  }
76  clone->partitions.push_back(part_clone);
77  }
78  DBUG_RETURN(clone);
79 }
80 
81 
93 bool partition_info::add_named_partition(const char *part_name,
94  uint length)
95 {
96  HASH *part_name_hash;
97  PART_NAME_DEF *part_def;
98  Partition_share *part_share;
99  DBUG_ENTER("partition_info::add_named_partition");
100  DBUG_ASSERT(table && table->s && table->s->ha_share);
101  part_share= static_cast<Partition_share*>((table->s->ha_share));
102  DBUG_ASSERT(part_share->partition_name_hash_initialized);
103  part_name_hash= &part_share->partition_name_hash;
104  DBUG_ASSERT(part_name_hash->records);
105 
106  part_def= (PART_NAME_DEF*) my_hash_search(part_name_hash,
107  (const uchar*) part_name,
108  length);
109  if (!part_def)
110  {
111  my_error(ER_UNKNOWN_PARTITION, MYF(0), part_name, table->alias);
112  DBUG_RETURN(true);
113  }
114 
115  if (part_def->is_subpart)
116  {
117  bitmap_set_bit(&read_partitions, part_def->part_id);
118  }
119  else
120  {
121  if (is_sub_partitioned())
122  {
123  /* Mark all subpartitions in the partition */
124  uint j, start= part_def->part_id;
125  uint end= start + num_subparts;
126  for (j= start; j < end; j++)
127  bitmap_set_bit(&read_partitions, j);
128  }
129  else
130  bitmap_set_bit(&read_partitions, part_def->part_id);
131  }
132  DBUG_PRINT("info", ("Found partition %u is_subpart %d for name %s",
133  part_def->part_id, part_def->is_subpart,
134  part_name));
135  DBUG_RETURN(false);
136 }
137 
138 
145 bool partition_info::set_named_partition_bitmap(const char *part_name,
146  uint length)
147 {
148  DBUG_ENTER("partition_info::set_named_partition_bitmap");
149  bitmap_clear_all(&read_partitions);
150  if (add_named_partition(part_name, length))
151  DBUG_RETURN(true);
152  bitmap_copy(&lock_partitions, &read_partitions);
153  DBUG_RETURN(false);
154 }
155 
156 
157 
168 bool partition_info::prune_partition_bitmaps(TABLE_LIST *table_list)
169 {
170  List_iterator<String> partition_names_it(*(table_list->partition_names));
171  uint num_names= table_list->partition_names->elements;
172  uint i= 0;
173  DBUG_ENTER("partition_info::prune_partition_bitmaps");
174 
175  if (num_names < 1)
176  DBUG_RETURN(true);
177 
178  /*
179  TODO: When adding support for FK in partitioned tables, the referenced
180  table must probably lock all partitions for read, and also write depending
181  of ON DELETE/UPDATE.
182  */
183  bitmap_clear_all(&read_partitions);
184 
185  /* No check for duplicate names or overlapping partitions/subpartitions. */
186 
187  DBUG_PRINT("info", ("Searching through partition_name_hash"));
188  do
189  {
190  String *part_name_str= partition_names_it++;
191  if (add_named_partition(part_name_str->c_ptr(), part_name_str->length()))
192  DBUG_RETURN(true);
193  } while (++i < num_names);
194  DBUG_RETURN(false);
195 }
196 
197 
212 bool partition_info::set_partition_bitmaps(TABLE_LIST *table_list)
213 {
214  DBUG_ENTER("partition_info::set_partition_bitmaps");
215 
216  DBUG_ASSERT(bitmaps_are_initialized);
217  DBUG_ASSERT(table);
218  is_pruning_completed= false;
219  if (!bitmaps_are_initialized)
220  DBUG_RETURN(TRUE);
221 
222  if (table_list &&
223  table_list->partition_names &&
224  table_list->partition_names->elements)
225  {
226  if (table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION)
227  {
228  /*
229  Don't allow PARTITION () clause on a NDB tables yet.
230  TODO: Add partition name handling to NDB/partition_info.
231  which is currently ha_partition specific.
232  */
233  my_error(ER_PARTITION_CLAUSE_ON_NONPARTITIONED, MYF(0));
234  DBUG_RETURN(true);
235  }
236  if (prune_partition_bitmaps(table_list))
237  DBUG_RETURN(TRUE);
238  }
239  else
240  {
241  bitmap_set_all(&read_partitions);
242  DBUG_PRINT("info", ("Set all partitions"));
243  }
244  bitmap_copy(&lock_partitions, &read_partitions);
245  DBUG_ASSERT(bitmap_get_first_set(&lock_partitions) != MY_BIT_NONE);
246  DBUG_RETURN(FALSE);
247 }
248 
249 
270 bool partition_info::can_prune_insert(THD* thd,
271  enum_duplicates duplic,
272  COPY_INFO &update,
273  List<Item> &update_fields,
274  List<Item> &fields,
275  bool empty_values,
276  enum_can_prune *can_prune_partitions,
277  bool *prune_needs_default_values,
278  MY_BITMAP *used_partitions)
279 {
280  uint32 *bitmap_buf;
281  uint bitmap_bytes;
282  uint num_partitions= 0;
283  *can_prune_partitions= PRUNE_NO;
284  DBUG_ASSERT(bitmaps_are_initialized);
285  DBUG_ENTER("partition_info::can_prune_insert");
286 
287  if (table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION)
288  DBUG_RETURN(false); /* Should not insert prune NDB tables */
289 
290  /*
291  If under LOCK TABLES pruning will skip start_stmt instead of external_lock
292  for unused partitions.
293 
294  Cannot prune if there are BEFORE INSERT triggers that changes any
295  partitioning column, since they may change the row to be in another
296  partition.
297  */
298  if (table->triggers &&
299  table->triggers->has_triggers(TRG_EVENT_INSERT, TRG_ACTION_BEFORE) &&
300  table->triggers->is_fields_updated_in_trigger(&full_part_field_set,
301  TRG_EVENT_INSERT,
302  TRG_ACTION_BEFORE))
303  DBUG_RETURN(false);
304 
305  if (table->found_next_number_field)
306  {
307  /*
308  If the field is used in the partitioning expression, we cannot prune.
309  TODO: If all rows have not null values and
310  is not 0 (with NO_AUTO_VALUE_ON_ZERO sql_mode), then pruning is possible!
311  */
312  if (bitmap_is_set(&full_part_field_set,
313  table->found_next_number_field->field_index))
314  DBUG_RETURN(false);
315  }
316 
317  /*
318  If updating a field in the partitioning expression, we cannot prune.
319 
320  Note: TIMESTAMP_AUTO_SET_ON_INSERT is handled by converting Item_null
321  to the start time of the statement. Which will be the same as in
322  write_row(). So pruning of TIMESTAMP DEFAULT CURRENT_TIME will work.
323  But TIMESTAMP_AUTO_SET_ON_UPDATE cannot be pruned if the timestamp
324  column is a part of any part/subpart expression.
325  */
326  if (duplic == DUP_UPDATE)
327  {
328  /*
329  Cannot prune if any field in the partitioning expression can
330  be updated by ON DUPLICATE UPDATE.
331  */
332  if (update.function_defaults_apply_on_columns(&full_part_field_set))
333  DBUG_RETURN(false);
334 
335  /*
336  TODO: add check for static update values, which can be pruned.
337  */
338  if (is_field_in_part_expr(update_fields))
339  DBUG_RETURN(false);
340 
341  /*
342  Cannot prune if there are BEFORE UPDATE triggers that changes any
343  partitioning column, since they may change the row to be in another
344  partition.
345  */
346  if (table->triggers &&
347  table->triggers->has_triggers(TRG_EVENT_UPDATE,
348  TRG_ACTION_BEFORE) &&
349  table->triggers->is_fields_updated_in_trigger(&full_part_field_set,
350  TRG_EVENT_UPDATE,
351  TRG_ACTION_BEFORE))
352  {
353  DBUG_RETURN(false);
354  }
355  }
356 
357  /*
358  If not all partitioning fields are given,
359  we also must set all non given partitioning fields
360  to get correct defaults.
361  TODO: If any gain, we could enhance this by only copy the needed default
362  fields by
363  1) check which fields needs to be set.
364  2) only copy those fields from the default record.
365  */
366  *prune_needs_default_values= false;
367  if (fields.elements)
368  {
369  if (!is_full_part_expr_in_fields(fields))
370  *prune_needs_default_values= true;
371  }
372  else if (empty_values)
373  {
374  *prune_needs_default_values= true; // like 'INSERT INTO t () VALUES ()'
375  }
376  else
377  {
378  /*
379  In case of INSERT INTO t VALUES (...) we must get values for
380  all fields in table from VALUES (...) part, so no defaults
381  are needed.
382  */
383  }
384 
385  /* Pruning possible, have to initialize the used_partitions bitmap. */
386  num_partitions= lock_partitions.n_bits;
387  bitmap_bytes= bitmap_buffer_size(num_partitions);
388  if (!(bitmap_buf= (uint32*) thd->alloc(bitmap_bytes)))
389  {
390  mem_alloc_error(bitmap_bytes);
391  DBUG_RETURN(true);
392  }
393  /* Also clears all bits. */
394  if (bitmap_init(used_partitions, bitmap_buf, num_partitions, false))
395  {
396  /* purecov: begin deadcode */
397  /* Cannot happen, due to pre-alloc. */
398  mem_alloc_error(bitmap_bytes);
399  DBUG_RETURN(true);
400  /* purecov: end */
401  }
402  /*
403  If no partitioning field in set (e.g. defaults) check pruning only once.
404  */
405  if (fields.elements &&
406  !is_field_in_part_expr(fields))
407  *can_prune_partitions= PRUNE_DEFAULTS;
408  else
409  *can_prune_partitions= PRUNE_YES;
410 
411  DBUG_RETURN(false);
412 }
413 
414 
429 bool partition_info::set_used_partition(List<Item> &fields,
430  List<Item> &values,
431  COPY_INFO &info,
432  bool copy_default_values,
433  MY_BITMAP *used_partitions)
434 {
435  THD *thd= table->in_use;
436  uint32 part_id;
437  longlong func_value;
438  Dummy_error_handler error_handler;
439  bool ret= true;
440  DBUG_ENTER("set_partition");
441  DBUG_ASSERT(thd);
442 
443  /* Only allow checking of constant values */
444  List_iterator_fast<Item> v(values);
445  Item *item;
446  thd->push_internal_handler(&error_handler);
447  while ((item= v++))
448  {
449  if (!item->const_item())
450  goto err;
451  }
452 
453  if (copy_default_values)
454  restore_record(table,s->default_values);
455 
456  if (fields.elements || !values.elements)
457  {
458  if (fill_record(thd, fields, values, false, &full_part_field_set))
459  goto err;
460  }
461  else
462  {
463  if (fill_record(thd, table->field, values, false, &full_part_field_set))
464  goto err;
465  }
466  DBUG_ASSERT(!table->auto_increment_field_not_null);
467 
468  /*
469  Evaluate DEFAULT functions like CURRENT_TIMESTAMP.
470  TODO: avoid setting non partitioning fields default value, to avoid
471  overhead. Not yet done, since mostly only one DEFAULT function per
472  table, or at least very few such columns.
473  */
474  if (info.function_defaults_apply_on_columns(&full_part_field_set))
476 
477  {
478  /*
479  This function is used in INSERT; 'values' are supplied by user,
480  or are default values, not values read from a table, so read_set is
481  irrelevant.
482  */
483  my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
484  const int rc= get_partition_id(this, &part_id, &func_value);
485  dbug_tmp_restore_column_map(table->read_set, old_map);
486  if (rc)
487  goto err;
488  }
489 
490  DBUG_PRINT("info", ("Insert into partition %u", part_id));
491  bitmap_set_bit(used_partitions, part_id);
492  ret= false;
493 
494 err:
495  thd->pop_internal_handler();
496  DBUG_RETURN(ret);
497 }
498 
499 
500 /*
501  Create a memory area where default partition names are stored and fill it
502  up with the names.
503 
504  SYNOPSIS
505  create_default_partition_names()
506  part_no Partition number for subparts
507  num_parts Number of partitions
508  start_no Starting partition number
509  subpart Is it subpartitions
510 
511  RETURN VALUE
512  A pointer to the memory area of the default partition names
513 
514  DESCRIPTION
515  A support routine for the partition code where default values are
516  generated.
517  The external routine needing this code is check_partition_info
518 */
519 
520 #define MAX_PART_NAME_SIZE 8
521 
522 char *partition_info::create_default_partition_names(uint part_no,
523  uint num_parts_arg,
524  uint start_no)
525 {
526  char *ptr= (char*) sql_calloc(num_parts_arg*MAX_PART_NAME_SIZE);
527  char *move_ptr= ptr;
528  uint i= 0;
529  DBUG_ENTER("create_default_partition_names");
530 
531  if (likely(ptr != 0))
532  {
533  do
534  {
535  sprintf(move_ptr, "p%u", (start_no + i));
536  move_ptr+= MAX_PART_NAME_SIZE;
537  } while (++i < num_parts_arg);
538  }
539  else
540  {
541  mem_alloc_error(num_parts_arg*MAX_PART_NAME_SIZE);
542  }
543  DBUG_RETURN(ptr);
544 }
545 
546 
547 /*
548  Generate a version string for partition expression
549  This function must be updated every time there is a possibility for
550  a new function of a higher version number than 5.5.0.
551 
552  SYNOPSIS
553  set_show_version_string()
554  RETURN VALUES
555  None
556 */
557 void partition_info::set_show_version_string(String *packet)
558 {
559  int version= 0;
560  if (column_list)
561  packet->append(STRING_WITH_LEN("\n/*!50500"));
562  else
563  {
564  if (part_expr)
565  part_expr->walk(&Item::intro_version, 0, (uchar*)&version);
566  if (subpart_expr)
567  subpart_expr->walk(&Item::intro_version, 0, (uchar*)&version);
568  if (version == 0)
569  {
570  /* No new functions in partition function */
571  packet->append(STRING_WITH_LEN("\n/*!50100"));
572  }
573  else
574  {
575  char buf[65];
576  char *buf_ptr= longlong10_to_str((longlong)version, buf, 10);
577  packet->append(STRING_WITH_LEN("\n/*!"));
578  packet->append(buf, (size_t)(buf_ptr - buf));
579  }
580  }
581 }
582 
583 /*
584  Create a unique name for the subpartition as part_name'sp''subpart_no'
585  SYNOPSIS
586  create_default_subpartition_name()
587  subpart_no Number of subpartition
588  part_name Name of partition
589  RETURN VALUES
590  >0 A reference to the created name string
591  0 Memory allocation error
592 */
593 
594 char *partition_info::create_default_subpartition_name(uint subpart_no,
595  const char *part_name)
596 {
597  uint size_alloc= strlen(part_name) + MAX_PART_NAME_SIZE;
598  char *ptr= (char*) sql_calloc(size_alloc);
599  DBUG_ENTER("create_default_subpartition_name");
600 
601  if (likely(ptr != NULL))
602  {
603  my_snprintf(ptr, size_alloc, "%ssp%u", part_name, subpart_no);
604  }
605  else
606  {
607  mem_alloc_error(size_alloc);
608  }
609  DBUG_RETURN(ptr);
610 }
611 
612 
613 /*
614  Set up all the default partitions not set-up by the user in the SQL
615  statement. Also perform a number of checks that the user hasn't tried
616  to use default values where no defaults exists.
617 
618  SYNOPSIS
619  set_up_default_partitions()
620  file A reference to a handler of the table
621  info Create info
622  start_no Starting partition number
623 
624  RETURN VALUE
625  TRUE Error, attempted default values not possible
626  FALSE Ok, default partitions set-up
627 
628  DESCRIPTION
629  The routine uses the underlying handler of the partitioning to define
630  the default number of partitions. For some handlers this requires
631  knowledge of the maximum number of rows to be stored in the table.
632  This routine only accepts HASH and KEY partitioning and thus there is
633  no subpartitioning if this routine is successful.
634  The external routine needing this code is check_partition_info
635 */
636 
637 bool partition_info::set_up_default_partitions(handler *file,
638  HA_CREATE_INFO *info,
639  uint start_no)
640 {
641  uint i;
642  char *default_name;
643  bool result= TRUE;
644  DBUG_ENTER("partition_info::set_up_default_partitions");
645 
646  if (part_type != HASH_PARTITION)
647  {
648  const char *error_string;
649  if (part_type == RANGE_PARTITION)
650  error_string= partition_keywords[PKW_RANGE].str;
651  else
652  error_string= partition_keywords[PKW_LIST].str;
653  my_error(ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0), error_string);
654  goto end;
655  }
656 
657  if ((num_parts == 0) &&
658  ((num_parts= file->get_default_no_partitions(info)) == 0))
659  {
660  my_error(ER_PARTITION_NOT_DEFINED_ERROR, MYF(0), "partitions");
661  goto end;
662  }
663 
664  if (unlikely(num_parts > MAX_PARTITIONS))
665  {
666  my_error(ER_TOO_MANY_PARTITIONS_ERROR, MYF(0));
667  goto end;
668  }
669  if (unlikely((!(default_name= create_default_partition_names(0, num_parts,
670  start_no)))))
671  goto end;
672  i= 0;
673  do
674  {
675  partition_element *part_elem= new partition_element();
676  if (likely(part_elem != 0 &&
677  (!partitions.push_back(part_elem))))
678  {
679  part_elem->engine_type= default_engine_type;
680  part_elem->partition_name= default_name;
681  default_name+=MAX_PART_NAME_SIZE;
682  }
683  else
684  {
685  mem_alloc_error(sizeof(partition_element));
686  goto end;
687  }
688  } while (++i < num_parts);
689  result= FALSE;
690 end:
691  DBUG_RETURN(result);
692 }
693 
694 
695 /*
696  Set up all the default subpartitions not set-up by the user in the SQL
697  statement. Also perform a number of checks that the default partitioning
698  becomes an allowed partitioning scheme.
699 
700  SYNOPSIS
701  set_up_default_subpartitions()
702  file A reference to a handler of the table
703  info Create info
704 
705  RETURN VALUE
706  TRUE Error, attempted default values not possible
707  FALSE Ok, default partitions set-up
708 
709  DESCRIPTION
710  The routine uses the underlying handler of the partitioning to define
711  the default number of partitions. For some handlers this requires
712  knowledge of the maximum number of rows to be stored in the table.
713  This routine is only called for RANGE or LIST partitioning and those
714  need to be specified so only subpartitions are specified.
715  The external routine needing this code is check_partition_info
716 */
717 
718 bool partition_info::set_up_default_subpartitions(handler *file,
719  HA_CREATE_INFO *info)
720 {
721  uint i, j;
722  bool result= TRUE;
723  partition_element *part_elem;
724  List_iterator<partition_element> part_it(partitions);
725  DBUG_ENTER("partition_info::set_up_default_subpartitions");
726 
727  if (num_subparts == 0)
728  num_subparts= file->get_default_no_partitions(info);
729  if (unlikely((num_parts * num_subparts) > MAX_PARTITIONS))
730  {
731  my_error(ER_TOO_MANY_PARTITIONS_ERROR, MYF(0));
732  goto end;
733  }
734  i= 0;
735  do
736  {
737  part_elem= part_it++;
738  j= 0;
739  do
740  {
741  partition_element *subpart_elem= new partition_element(part_elem);
742  if (likely(subpart_elem != 0 &&
743  (!part_elem->subpartitions.push_back(subpart_elem))))
744  {
745  char *ptr= create_default_subpartition_name(j,
746  part_elem->partition_name);
747  if (!ptr)
748  goto end;
749  subpart_elem->engine_type= default_engine_type;
750  subpart_elem->partition_name= ptr;
751  }
752  else
753  {
754  mem_alloc_error(sizeof(partition_element));
755  goto end;
756  }
757  } while (++j < num_subparts);
758  } while (++i < num_parts);
759  result= FALSE;
760 end:
761  DBUG_RETURN(result);
762 }
763 
764 
765 /*
766  Support routine for check_partition_info
767 
768  SYNOPSIS
769  set_up_defaults_for_partitioning()
770  file A reference to a handler of the table
771  info Create info
772  start_no Starting partition number
773 
774  RETURN VALUE
775  TRUE Error, attempted default values not possible
776  FALSE Ok, default partitions set-up
777 
778  DESCRIPTION
779  Set up defaults for partition or subpartition (cannot set-up for both,
780  this will return an error.
781 */
782 
783 bool partition_info::set_up_defaults_for_partitioning(handler *file,
784  HA_CREATE_INFO *info,
785  uint start_no)
786 {
787  DBUG_ENTER("partition_info::set_up_defaults_for_partitioning");
788 
789  if (!default_partitions_setup)
790  {
791  default_partitions_setup= TRUE;
792  if (use_default_partitions)
793  DBUG_RETURN(set_up_default_partitions(file, info, start_no));
794  if (is_sub_partitioned() &&
795  use_default_subpartitions)
796  DBUG_RETURN(set_up_default_subpartitions(file, info));
797  }
798  DBUG_RETURN(FALSE);
799 }
800 
801 
802 /*
803  Support routine for check_partition_info
804 
805  SYNOPSIS
806  find_duplicate_field
807  no parameters
808 
809  RETURN VALUE
810  Erroneus field name Error, there are two fields with same name
811  NULL Ok, no field defined twice
812 
813  DESCRIPTION
814  Check that the user haven't defined the same field twice in
815  key or column list partitioning.
816 */
817 char* partition_info::find_duplicate_field()
818 {
819  char *field_name_outer, *field_name_inner;
820  List_iterator<char> it_outer(part_field_list);
821  uint num_fields= part_field_list.elements;
822  uint i,j;
823  DBUG_ENTER("partition_info::find_duplicate_field");
824 
825  for (i= 0; i < num_fields; i++)
826  {
827  field_name_outer= it_outer++;
828  List_iterator<char> it_inner(part_field_list);
829  for (j= 0; j < num_fields; j++)
830  {
831  field_name_inner= it_inner++;
832  if (i >= j)
833  continue;
834  if (!(my_strcasecmp(system_charset_info,
835  field_name_outer,
836  field_name_inner)))
837  {
838  DBUG_RETURN(field_name_outer);
839  }
840  }
841  }
842  DBUG_RETURN(NULL);
843 }
844 
845 
861 partition_element *partition_info::get_part_elem(const char *partition_name,
862  char *file_name,
863  uint32 *part_id)
864 {
865  List_iterator<partition_element> part_it(partitions);
866  uint i= 0;
867  DBUG_ENTER("partition_info::get_part_elem");
868  DBUG_ASSERT(part_id);
869  *part_id= NOT_A_PARTITION_ID;
870  do
871  {
872  partition_element *part_elem= part_it++;
873  if (is_sub_partitioned())
874  {
875  List_iterator<partition_element> sub_part_it(part_elem->subpartitions);
876  uint j= 0;
877  do
878  {
879  partition_element *sub_part_elem= sub_part_it++;
880  if (!my_strcasecmp(system_charset_info,
881  sub_part_elem->partition_name, partition_name))
882  {
883  if (file_name)
884  create_subpartition_name(file_name, "",
885  part_elem->partition_name,
886  partition_name,
887  NORMAL_PART_NAME);
888  *part_id= j + (i * num_subparts);
889  DBUG_RETURN(sub_part_elem);
890  }
891  } while (++j < num_subparts);
892 
893  /* Naming a partition (first level) on a subpartitioned table. */
894  if (!my_strcasecmp(system_charset_info,
895  part_elem->partition_name, partition_name))
896  DBUG_RETURN(part_elem);
897  }
898  else if (!my_strcasecmp(system_charset_info,
899  part_elem->partition_name, partition_name))
900  {
901  if (file_name)
902  create_partition_name(file_name, "", partition_name,
903  NORMAL_PART_NAME, TRUE);
904  *part_id= i;
905  DBUG_RETURN(part_elem);
906  }
907  } while (++i < num_parts);
908  DBUG_RETURN(NULL);
909 }
910 
911 
916 static const char *get_part_name_from_elem(const char *name, size_t *length,
917  my_bool not_used __attribute__((unused)))
918 {
919  *length= strlen(name);
920  return name;
921 }
922 
923 /*
924  A support function to check partition names for duplication in a
925  partitioned table
926 
927  SYNOPSIS
928  find_duplicate_name()
929 
930  RETURN VALUES
931  NULL Has unique part and subpart names
932  !NULL Pointer to duplicated name
933 
934  DESCRIPTION
935  Checks that the list of names in the partitions doesn't contain any
936  duplicated names.
937 */
938 
939 char *partition_info::find_duplicate_name()
940 {
941  HASH partition_names;
942  uint max_names;
943  const uchar *curr_name= NULL;
944  List_iterator<partition_element> parts_it(partitions);
945  partition_element *p_elem;
946 
947  DBUG_ENTER("partition_info::find_duplicate_name");
948 
949  /*
950  TODO: If table->s->ha_part_data->partition_name_hash.elements is > 0,
951  then we could just return NULL, but that has not been verified.
952  And this only happens when in ALTER TABLE with full table copy.
953  */
954 
955  max_names= num_parts;
956  if (is_sub_partitioned())
957  max_names+= num_parts * num_subparts;
958  if (my_hash_init(&partition_names, system_charset_info, max_names, 0, 0,
959  (my_hash_get_key) get_part_name_from_elem, 0, HASH_UNIQUE))
960  {
961  DBUG_ASSERT(0);
962  curr_name= (const uchar*) "Internal failure";
963  goto error;
964  }
965  while ((p_elem= (parts_it++)))
966  {
967  curr_name= (const uchar*) p_elem->partition_name;
968  if (my_hash_insert(&partition_names, curr_name))
969  goto error;
970 
971  if (!p_elem->subpartitions.is_empty())
972  {
973  List_iterator<partition_element> subparts_it(p_elem->subpartitions);
974  partition_element *subp_elem;
975  while ((subp_elem= (subparts_it++)))
976  {
977  curr_name= (const uchar*) subp_elem->partition_name;
978  if (my_hash_insert(&partition_names, curr_name))
979  goto error;
980  }
981  }
982  }
983  my_hash_free(&partition_names);
984  DBUG_RETURN(NULL);
985 error:
986  my_hash_free(&partition_names);
987  DBUG_RETURN((char*) curr_name);
988 }
989 
990 
991 /*
992  Check that the partition/subpartition is setup to use the correct
993  storage engine
994  SYNOPSIS
995  check_engine_condition()
996  p_elem Partition element
997  table_engine_set Have user specified engine on table level
998  inout::engine_type Current engine used
999  inout::first Is it first partition
1000  RETURN VALUE
1001  TRUE Failed check
1002  FALSE Ok
1003  DESCRIPTION
1004  Specified engine for table and partitions p0 and pn
1005  Must be correct both on CREATE and ALTER commands
1006  table p0 pn res (0 - OK, 1 - FAIL)
1007  - - - 0
1008  - - x 1
1009  - x - 1
1010  - x x 0
1011  x - - 0
1012  x - x 0
1013  x x - 0
1014  x x x 0
1015  i.e:
1016  - All subpartitions must use the same engine
1017  AND it must be the same as the partition.
1018  - All partitions must use the same engine
1019  AND it must be the same as the table.
1020  - if one does NOT specify an engine on the table level
1021  then one must either NOT specify any engine on any
1022  partition/subpartition OR for ALL partitions/subpartitions
1023  Note:
1024  When ALTER a table, the engines are already set for all levels
1025  (table, all partitions and subpartitions). So if one want to
1026  change the storage engine, one must specify it on the table level
1027 
1028 */
1029 
1030 static bool check_engine_condition(partition_element *p_elem,
1031  bool table_engine_set,
1032  handlerton **engine_type,
1033  bool *first)
1034 {
1035  DBUG_ENTER("check_engine_condition");
1036 
1037  DBUG_PRINT("enter", ("p_eng %s t_eng %s t_eng_set %u first %u state %u",
1038  ha_resolve_storage_engine_name(p_elem->engine_type),
1039  ha_resolve_storage_engine_name(*engine_type),
1040  table_engine_set, *first, p_elem->part_state));
1041  if (*first && !table_engine_set)
1042  {
1043  *engine_type= p_elem->engine_type;
1044  DBUG_PRINT("info", ("setting table_engine = %s",
1045  ha_resolve_storage_engine_name(*engine_type)));
1046  }
1047  *first= FALSE;
1048  if ((table_engine_set &&
1049  (p_elem->engine_type != (*engine_type) &&
1050  p_elem->engine_type)) ||
1051  (!table_engine_set &&
1052  p_elem->engine_type != (*engine_type)))
1053  {
1054  DBUG_RETURN(TRUE);
1055  }
1056 
1057  DBUG_RETURN(FALSE);
1058 }
1059 
1060 
1061 /*
1062  Check engine mix that it is correct
1063  Current limitation is that all partitions and subpartitions
1064  must use the same storage engine.
1065  SYNOPSIS
1066  check_engine_mix()
1067  inout::engine_type Current engine used
1068  table_engine_set Have user specified engine on table level
1069  RETURN VALUE
1070  TRUE Error, mixed engines
1071  FALSE Ok, no mixed engines
1072  DESCRIPTION
1073  Current check verifies only that all handlers are the same.
1074  Later this check will be more sophisticated.
1075  (specified partition handler ) specified table handler
1076  (NDB, NDB) NDB OK
1077  (MYISAM, MYISAM) - OK
1078  (MYISAM, -) - NOT OK
1079  (MYISAM, -) MYISAM OK
1080  (- , MYISAM) - NOT OK
1081  (- , -) MYISAM OK
1082  (-,-) - OK
1083  (NDB, MYISAM) * NOT OK
1084 */
1085 
1086 bool partition_info::check_engine_mix(handlerton *engine_type,
1087  bool table_engine_set)
1088 {
1089  handlerton *old_engine_type= engine_type;
1090  bool first= TRUE;
1091  uint n_parts= partitions.elements;
1092  DBUG_ENTER("partition_info::check_engine_mix");
1093  DBUG_PRINT("info", ("in: engine_type = %s, table_engine_set = %u",
1094  ha_resolve_storage_engine_name(engine_type),
1095  table_engine_set));
1096  if (n_parts)
1097  {
1098  List_iterator<partition_element> part_it(partitions);
1099  uint i= 0;
1100  do
1101  {
1102  partition_element *part_elem= part_it++;
1103  DBUG_PRINT("info", ("part = %d engine = %s table_engine_set %u",
1104  i, ha_resolve_storage_engine_name(part_elem->engine_type),
1105  table_engine_set));
1106  if (is_sub_partitioned() &&
1107  part_elem->subpartitions.elements)
1108  {
1109  uint n_subparts= part_elem->subpartitions.elements;
1110  uint j= 0;
1111  List_iterator<partition_element> sub_it(part_elem->subpartitions);
1112  do
1113  {
1114  partition_element *sub_elem= sub_it++;
1115  DBUG_PRINT("info", ("sub = %d engine = %s table_engie_set %u",
1116  j, ha_resolve_storage_engine_name(sub_elem->engine_type),
1117  table_engine_set));
1118  if (check_engine_condition(sub_elem, table_engine_set,
1119  &engine_type, &first))
1120  goto error;
1121  } while (++j < n_subparts);
1122  /* ensure that the partition also has correct engine */
1123  if (check_engine_condition(part_elem, table_engine_set,
1124  &engine_type, &first))
1125  goto error;
1126  }
1127  else if (check_engine_condition(part_elem, table_engine_set,
1128  &engine_type, &first))
1129  goto error;
1130  } while (++i < n_parts);
1131  }
1132  DBUG_PRINT("info", ("engine_type = %s",
1133  ha_resolve_storage_engine_name(engine_type)));
1134  if (!engine_type)
1135  engine_type= old_engine_type;
1136  if (engine_type->flags & HTON_NO_PARTITION)
1137  {
1138  my_error(ER_PARTITION_MERGE_ERROR, MYF(0));
1139  DBUG_RETURN(TRUE);
1140  }
1141  DBUG_PRINT("info", ("out: engine_type = %s",
1142  ha_resolve_storage_engine_name(engine_type)));
1143  DBUG_ASSERT(engine_type != partition_hton);
1144  DBUG_RETURN(FALSE);
1145 error:
1146  /*
1147  Mixed engines not yet supported but when supported it will need
1148  the partition handler
1149  */
1150  DBUG_RETURN(TRUE);
1151 }
1152 
1153 
1154 /*
1155  This routine allocates an array for all range constants to achieve a fast
1156  check what partition a certain value belongs to. At the same time it does
1157  also check that the range constants are defined in increasing order and
1158  that the expressions are constant integer expressions.
1159 
1160  SYNOPSIS
1161  check_range_constants()
1162  thd Thread object
1163 
1164  RETURN VALUE
1165  TRUE An error occurred during creation of range constants
1166  FALSE Successful creation of range constant mapping
1167 
1168  DESCRIPTION
1169  This routine is called from check_partition_info to get a quick error
1170  before we came too far into the CREATE TABLE process. It is also called
1171  from fix_partition_func every time we open the .frm file. It is only
1172  called for RANGE PARTITIONed tables.
1173 */
1174 
1175 bool partition_info::check_range_constants(THD *thd)
1176 {
1177  partition_element* part_def;
1178  bool first= TRUE;
1179  uint i;
1180  List_iterator<partition_element> it(partitions);
1181  int result= TRUE;
1182  DBUG_ENTER("partition_info::check_range_constants");
1183  DBUG_PRINT("enter", ("RANGE with %d parts, column_list = %u", num_parts,
1184  column_list));
1185 
1186  if (column_list)
1187  {
1188  part_column_list_val *loc_range_col_array;
1189  part_column_list_val *UNINIT_VAR(current_largest_col_val);
1190  uint num_column_values= part_field_list.elements;
1191  uint size_entries= sizeof(part_column_list_val) * num_column_values;
1192  range_col_array= (part_column_list_val*)sql_calloc(num_parts *
1193  size_entries);
1194  if (unlikely(range_col_array == NULL))
1195  {
1196  mem_alloc_error(num_parts * size_entries);
1197  goto end;
1198  }
1199  loc_range_col_array= range_col_array;
1200  i= 0;
1201  do
1202  {
1203  part_def= it++;
1204  {
1205  List_iterator<part_elem_value> list_val_it(part_def->list_val_list);
1206  part_elem_value *range_val= list_val_it++;
1207  part_column_list_val *col_val= range_val->col_val_array;
1208  DBUG_ASSERT(part_def->list_val_list.elements == 1);
1209 
1210  if (fix_column_value_functions(thd, range_val, i))
1211  goto end;
1212  memcpy(loc_range_col_array, (const void*)col_val, size_entries);
1213  loc_range_col_array+= num_column_values;
1214  if (!first)
1215  {
1216  if (compare_column_values((const void*)current_largest_col_val,
1217  (const void*)col_val) >= 0)
1218  goto range_not_increasing_error;
1219  }
1220  current_largest_col_val= col_val;
1221  }
1222  first= FALSE;
1223  } while (++i < num_parts);
1224  }
1225  else
1226  {
1227  longlong UNINIT_VAR(current_largest);
1228  longlong part_range_value;
1229  bool signed_flag= !part_expr->unsigned_flag;
1230 
1231  range_int_array= (longlong*)sql_alloc(num_parts * sizeof(longlong));
1232  if (unlikely(range_int_array == NULL))
1233  {
1234  mem_alloc_error(num_parts * sizeof(longlong));
1235  goto end;
1236  }
1237  i= 0;
1238  do
1239  {
1240  part_def= it++;
1241  if ((i != (num_parts - 1)) || !defined_max_value)
1242  {
1243  part_range_value= part_def->range_value;
1244  if (!signed_flag)
1245  part_range_value-= 0x8000000000000000ULL;
1246  }
1247  else
1248  part_range_value= LONGLONG_MAX;
1249 
1250  if (!first)
1251  {
1252  if (unlikely(current_largest > part_range_value) ||
1253  (unlikely(current_largest == part_range_value) &&
1254  (part_range_value < LONGLONG_MAX ||
1255  i != (num_parts - 1) ||
1256  !defined_max_value)))
1257  goto range_not_increasing_error;
1258  }
1259  range_int_array[i]= part_range_value;
1260  current_largest= part_range_value;
1261  first= FALSE;
1262  } while (++i < num_parts);
1263  }
1264  result= FALSE;
1265 end:
1266  DBUG_RETURN(result);
1267 
1268 range_not_increasing_error:
1269  my_error(ER_RANGE_NOT_INCREASING_ERROR, MYF(0));
1270  goto end;
1271 }
1272 
1273 
1274 /*
1275  Support routines for check_list_constants used by qsort to sort the
1276  constant list expressions. One routine for integers and one for
1277  column lists.
1278 
1279  SYNOPSIS
1280  list_part_cmp()
1281  a First list constant to compare with
1282  b Second list constant to compare with
1283 
1284  RETURN VALUE
1285  +1 a > b
1286  0 a == b
1287  -1 a < b
1288 */
1289 
1290 extern "C"
1291 int partition_info_list_part_cmp(const void* a, const void* b)
1292 {
1293  longlong a1= ((LIST_PART_ENTRY*)a)->list_value;
1294  longlong b1= ((LIST_PART_ENTRY*)b)->list_value;
1295  if (a1 < b1)
1296  return -1;
1297  else if (a1 > b1)
1298  return +1;
1299  else
1300  return 0;
1301 }
1302 
1303 
1304 int partition_info::list_part_cmp(const void* a, const void* b)
1305 {
1306  return partition_info_list_part_cmp(a, b);
1307 }
1308 
1309 
1310 /*
1311  Compare two lists of column values in RANGE/LIST partitioning
1312  SYNOPSIS
1313  compare_column_values()
1314  first First column list argument
1315  second Second column list argument
1316  RETURN VALUES
1317  0 Equal
1318  -1 First argument is smaller
1319  +1 First argument is larger
1320 */
1321 
1322 extern "C"
1323 int partition_info_compare_column_values(const void *first_arg,
1324  const void *second_arg)
1325 {
1326  const part_column_list_val *first= (part_column_list_val*)first_arg;
1327  const part_column_list_val *second= (part_column_list_val*)second_arg;
1328  partition_info *part_info= first->part_info;
1329  Field **field;
1330 
1331  for (field= part_info->part_field_array; *field;
1332  field++, first++, second++)
1333  {
1334  if (first->max_value || second->max_value)
1335  {
1336  if (first->max_value && second->max_value)
1337  return 0;
1338  if (second->max_value)
1339  return -1;
1340  else
1341  return +1;
1342  }
1343  if (first->null_value || second->null_value)
1344  {
1345  if (first->null_value && second->null_value)
1346  continue;
1347  if (second->null_value)
1348  return +1;
1349  else
1350  return -1;
1351  }
1352  int res= (*field)->cmp((const uchar*)first->column_value,
1353  (const uchar*)second->column_value);
1354  if (res)
1355  return res;
1356  }
1357  return 0;
1358 }
1359 
1360 
1361 int partition_info::compare_column_values(const void *first_arg,
1362  const void *second_arg)
1363 {
1364  return partition_info_compare_column_values(first_arg, second_arg);
1365 }
1366 
1367 
1368 /*
1369  This routine allocates an array for all list constants to achieve a fast
1370  check what partition a certain value belongs to. At the same time it does
1371  also check that there are no duplicates among the list constants and that
1372  that the list expressions are constant integer expressions.
1373 
1374  SYNOPSIS
1375  check_list_constants()
1376  thd Thread object
1377 
1378  RETURN VALUE
1379  TRUE An error occurred during creation of list constants
1380  FALSE Successful creation of list constant mapping
1381 
1382  DESCRIPTION
1383  This routine is called from check_partition_info to get a quick error
1384  before we came too far into the CREATE TABLE process. It is also called
1385  from fix_partition_func every time we open the .frm file. It is only
1386  called for LIST PARTITIONed tables.
1387 */
1388 
1389 bool partition_info::check_list_constants(THD *thd)
1390 {
1391  uint i, size_entries, num_column_values;
1392  uint list_index= 0;
1393  part_elem_value *list_value;
1394  bool result= TRUE;
1395  longlong type_add, calc_value;
1396  void *curr_value;
1397  void *UNINIT_VAR(prev_value);
1398  partition_element* part_def;
1399  bool found_null= FALSE;
1400  qsort_cmp compare_func;
1401  void *ptr;
1402  List_iterator<partition_element> list_func_it(partitions);
1403  DBUG_ENTER("partition_info::check_list_constants");
1404 
1405  num_list_values= 0;
1406  /*
1407  We begin by calculating the number of list values that have been
1408  defined in the first step.
1409 
1410  We use this number to allocate a properly sized array of structs
1411  to keep the partition id and the value to use in that partition.
1412  In the second traversal we assign them values in the struct array.
1413 
1414  Finally we sort the array of structs in order of values to enable
1415  a quick binary search for the proper value to discover the
1416  partition id.
1417  After sorting the array we check that there are no duplicates in the
1418  list.
1419  */
1420 
1421  i= 0;
1422  do
1423  {
1424  part_def= list_func_it++;
1425  if (part_def->has_null_value)
1426  {
1427  if (found_null)
1428  {
1429  my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0));
1430  goto end;
1431  }
1432  has_null_value= TRUE;
1433  has_null_part_id= i;
1434  found_null= TRUE;
1435  }
1436  List_iterator<part_elem_value> list_val_it1(part_def->list_val_list);
1437  while (list_val_it1++)
1438  num_list_values++;
1439  } while (++i < num_parts);
1440  list_func_it.rewind();
1441  num_column_values= part_field_list.elements;
1442  size_entries= column_list ?
1443  (num_column_values * sizeof(part_column_list_val)) :
1444  sizeof(LIST_PART_ENTRY);
1445  ptr= sql_calloc((num_list_values+1) * size_entries);
1446  if (unlikely(ptr == NULL))
1447  {
1448  mem_alloc_error(num_list_values * size_entries);
1449  goto end;
1450  }
1451  if (column_list)
1452  {
1453  part_column_list_val *loc_list_col_array;
1454  loc_list_col_array= (part_column_list_val*)ptr;
1455  list_col_array= (part_column_list_val*)ptr;
1456  compare_func= partition_info_compare_column_values;
1457  i= 0;
1458  do
1459  {
1460  part_def= list_func_it++;
1461  List_iterator<part_elem_value> list_val_it2(part_def->list_val_list);
1462  while ((list_value= list_val_it2++))
1463  {
1464  part_column_list_val *col_val= list_value->col_val_array;
1465  if (unlikely(fix_column_value_functions(thd, list_value, i)))
1466  {
1467  DBUG_RETURN(TRUE);
1468  }
1469  memcpy(loc_list_col_array, (const void*)col_val, size_entries);
1470  loc_list_col_array+= num_column_values;
1471  }
1472  } while (++i < num_parts);
1473  }
1474  else
1475  {
1476  compare_func= partition_info_list_part_cmp;
1477  list_array= (LIST_PART_ENTRY*)ptr;
1478  i= 0;
1479  /*
1480  Fix to be able to reuse signed sort functions also for unsigned
1481  partition functions.
1482  */
1483  type_add= (longlong)(part_expr->unsigned_flag ?
1484  0x8000000000000000ULL :
1485  0ULL);
1486 
1487  do
1488  {
1489  part_def= list_func_it++;
1490  List_iterator<part_elem_value> list_val_it2(part_def->list_val_list);
1491  while ((list_value= list_val_it2++))
1492  {
1493  calc_value= list_value->value - type_add;
1494  list_array[list_index].list_value= calc_value;
1495  list_array[list_index++].partition_id= i;
1496  }
1497  } while (++i < num_parts);
1498  }
1499  DBUG_ASSERT(fixed);
1500  if (num_list_values)
1501  {
1502  bool first= TRUE;
1503  /*
1504  list_array and list_col_array are unions, so this works for both
1505  variants of LIST partitioning.
1506  */
1507  my_qsort((void*)list_array, num_list_values, size_entries,
1508  compare_func);
1509 
1510  i= 0;
1511  do
1512  {
1513  DBUG_ASSERT(i < num_list_values);
1514  curr_value= column_list ? (void*)&list_col_array[num_column_values * i] :
1515  (void*)&list_array[i];
1516  if (likely(first || compare_func(curr_value, prev_value)))
1517  {
1518  prev_value= curr_value;
1519  first= FALSE;
1520  }
1521  else
1522  {
1523  my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0));
1524  goto end;
1525  }
1526  } while (++i < num_list_values);
1527  }
1528  result= FALSE;
1529 end:
1530  DBUG_RETURN(result);
1531 }
1532 
1539 static void warn_if_dir_in_part_elem(THD *thd, partition_element *part_elem)
1540 {
1541  if (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE)
1542  {
1543  if (part_elem->data_file_name)
1544  push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
1545  WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED),
1546  "DATA DIRECTORY");
1547  if (part_elem->index_file_name)
1548  push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
1549  WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED),
1550  "INDEX DIRECTORY");
1551  part_elem->data_file_name= part_elem->index_file_name= NULL;
1552  }
1553 }
1554 
1555 
1556 /*
1557  This code is used early in the CREATE TABLE and ALTER TABLE process.
1558 
1559  SYNOPSIS
1560  check_partition_info()
1561  thd Thread object
1562  eng_type Return value for used engine in partitions
1563  file A reference to a handler of the table
1564  info Create info
1565  add_or_reorg_part Is it ALTER TABLE ADD/REORGANIZE command
1566 
1567  RETURN VALUE
1568  TRUE Error, something went wrong
1569  FALSE Ok, full partition data structures are now generated
1570 
1571  DESCRIPTION
1572  We will check that the partition info requested is possible to set-up in
1573  this version. This routine is an extension of the parser one could say.
1574  If defaults were used we will generate default data structures for all
1575  partitions.
1576 
1577 */
1578 
1579 bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
1580  handler *file, HA_CREATE_INFO *info,
1581  bool add_or_reorg_part)
1582 {
1583  handlerton *table_engine= default_engine_type;
1584  uint i, tot_partitions;
1585  bool result= TRUE, table_engine_set;
1586  char *same_name;
1587  DBUG_ENTER("partition_info::check_partition_info");
1588  DBUG_ASSERT(default_engine_type != partition_hton);
1589 
1590  DBUG_PRINT("info", ("default table_engine = %s",
1591  ha_resolve_storage_engine_name(table_engine)));
1592  if (!add_or_reorg_part)
1593  {
1594  int err= 0;
1595 
1596  if (!list_of_part_fields)
1597  {
1598  DBUG_ASSERT(part_expr);
1599  err= part_expr->walk(&Item::check_partition_func_processor, 0,
1600  NULL);
1601  if (!err && is_sub_partitioned() && !list_of_subpart_fields)
1602  err= subpart_expr->walk(&Item::check_partition_func_processor, 0,
1603  NULL);
1604  }
1605  if (err)
1606  {
1607  my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
1608  goto end;
1609  }
1610  if (thd->lex->sql_command == SQLCOM_CREATE_TABLE &&
1611  fix_parser_data(thd))
1612  goto end;
1613  }
1614  if (unlikely(!is_sub_partitioned() &&
1615  !(use_default_subpartitions && use_default_num_subpartitions)))
1616  {
1617  my_error(ER_SUBPARTITION_ERROR, MYF(0));
1618  goto end;
1619  }
1620  if (unlikely(is_sub_partitioned() &&
1621  (!(part_type == RANGE_PARTITION ||
1622  part_type == LIST_PARTITION))))
1623  {
1624  /* Only RANGE and LIST partitioning can be subpartitioned */
1625  my_error(ER_SUBPARTITION_ERROR, MYF(0));
1626  goto end;
1627  }
1628  if (unlikely(set_up_defaults_for_partitioning(file, info, (uint)0)))
1629  goto end;
1630  if (!(tot_partitions= get_tot_partitions()))
1631  {
1632  my_error(ER_PARTITION_NOT_DEFINED_ERROR, MYF(0), "partitions");
1633  goto end;
1634  }
1635  if (unlikely(tot_partitions > MAX_PARTITIONS))
1636  {
1637  my_error(ER_TOO_MANY_PARTITIONS_ERROR, MYF(0));
1638  goto end;
1639  }
1640  /*
1641  if NOT specified ENGINE = <engine>:
1642  If Create, always use create_info->db_type
1643  else, use previous tables db_type
1644  either ALL or NONE partition should be set to
1645  default_engine_type when not table_engine_set
1646  Note: after a table is created its storage engines for
1647  the table and all partitions/subpartitions are set.
1648  So when ALTER it is already set on table level
1649  */
1650  if (info && info->used_fields & HA_CREATE_USED_ENGINE)
1651  {
1652  table_engine_set= TRUE;
1653  table_engine= info->db_type;
1654  /* if partition_hton, use thd->lex->create_info */
1655  if (table_engine == partition_hton)
1656  table_engine= thd->lex->create_info.db_type;
1657  DBUG_ASSERT(table_engine != partition_hton);
1658  DBUG_PRINT("info", ("Using table_engine = %s",
1659  ha_resolve_storage_engine_name(table_engine)));
1660  }
1661  else
1662  {
1663  table_engine_set= FALSE;
1664  if (thd->lex->sql_command != SQLCOM_CREATE_TABLE)
1665  {
1666  table_engine_set= TRUE;
1667  DBUG_PRINT("info", ("No create, table_engine = %s",
1668  ha_resolve_storage_engine_name(table_engine)));
1669  DBUG_ASSERT(table_engine && table_engine != partition_hton);
1670  }
1671  }
1672 
1673  if (part_field_list.elements > 0 &&
1674  (same_name= find_duplicate_field()))
1675  {
1676  my_error(ER_SAME_NAME_PARTITION_FIELD, MYF(0), same_name);
1677  goto end;
1678  }
1679  if ((same_name= find_duplicate_name()))
1680  {
1681  my_error(ER_SAME_NAME_PARTITION, MYF(0), same_name);
1682  goto end;
1683  }
1684  i= 0;
1685  {
1686  List_iterator<partition_element> part_it(partitions);
1687  uint num_parts_not_set= 0;
1688  uint prev_num_subparts_not_set= num_subparts + 1;
1689  do
1690  {
1691  partition_element *part_elem= part_it++;
1692  warn_if_dir_in_part_elem(thd, part_elem);
1693  if (!is_sub_partitioned())
1694  {
1695  if (part_elem->engine_type == NULL)
1696  {
1697  num_parts_not_set++;
1698  part_elem->engine_type= default_engine_type;
1699  }
1700  enum_ident_name_check ident_check_status=
1701  check_table_name(part_elem->partition_name,
1702  strlen(part_elem->partition_name), FALSE);
1703  if (ident_check_status == IDENT_NAME_WRONG)
1704  {
1705  my_error(ER_WRONG_PARTITION_NAME, MYF(0));
1706  goto end;
1707  }
1708  else if (ident_check_status == IDENT_NAME_TOO_LONG)
1709  {
1710  my_error(ER_TOO_LONG_IDENT, MYF(0));
1711  goto end;
1712  }
1713  DBUG_PRINT("info", ("part = %d engine = %s",
1714  i, ha_resolve_storage_engine_name(part_elem->engine_type)));
1715  }
1716  else
1717  {
1718  uint j= 0;
1719  uint num_subparts_not_set= 0;
1720  List_iterator<partition_element> sub_it(part_elem->subpartitions);
1721  partition_element *sub_elem;
1722  do
1723  {
1724  sub_elem= sub_it++;
1725  warn_if_dir_in_part_elem(thd, sub_elem);
1726  enum_ident_name_check ident_check_status=
1727  check_table_name(sub_elem->partition_name,
1728  strlen(sub_elem->partition_name), FALSE);
1729  if (ident_check_status == IDENT_NAME_WRONG)
1730  {
1731  my_error(ER_WRONG_PARTITION_NAME, MYF(0));
1732  goto end;
1733  }
1734  else if (ident_check_status == IDENT_NAME_TOO_LONG)
1735  {
1736  my_error(ER_TOO_LONG_IDENT, MYF(0));
1737  goto end;
1738  }
1739  if (sub_elem->engine_type == NULL)
1740  {
1741  if (part_elem->engine_type != NULL)
1742  sub_elem->engine_type= part_elem->engine_type;
1743  else
1744  {
1745  sub_elem->engine_type= default_engine_type;
1746  num_subparts_not_set++;
1747  }
1748  }
1749  DBUG_PRINT("info", ("part = %d sub = %d engine = %s", i, j,
1750  ha_resolve_storage_engine_name(sub_elem->engine_type)));
1751  } while (++j < num_subparts);
1752 
1753  if (prev_num_subparts_not_set == (num_subparts + 1) &&
1754  (num_subparts_not_set == 0 ||
1755  num_subparts_not_set == num_subparts))
1756  prev_num_subparts_not_set= num_subparts_not_set;
1757 
1758  if (!table_engine_set &&
1759  prev_num_subparts_not_set != num_subparts_not_set)
1760  {
1761  DBUG_PRINT("info", ("num_subparts_not_set = %u num_subparts = %u",
1762  num_subparts_not_set, num_subparts));
1763  my_error(ER_MIX_HANDLER_ERROR, MYF(0));
1764  goto end;
1765  }
1766 
1767  if (part_elem->engine_type == NULL)
1768  {
1769  if (num_subparts_not_set == 0)
1770  part_elem->engine_type= sub_elem->engine_type;
1771  else
1772  {
1773  num_parts_not_set++;
1774  part_elem->engine_type= default_engine_type;
1775  }
1776  }
1777  }
1778  } while (++i < num_parts);
1779  if (!table_engine_set &&
1780  num_parts_not_set != 0 &&
1781  num_parts_not_set != num_parts)
1782  {
1783  DBUG_PRINT("info", ("num_parts_not_set = %u num_parts = %u",
1784  num_parts_not_set, num_subparts));
1785  my_error(ER_MIX_HANDLER_ERROR, MYF(0));
1786  goto end;
1787  }
1788  }
1789  if (unlikely(check_engine_mix(table_engine, table_engine_set)))
1790  {
1791  my_error(ER_MIX_HANDLER_ERROR, MYF(0));
1792  goto end;
1793  }
1794 
1795  DBUG_ASSERT(table_engine != partition_hton &&
1796  default_engine_type == table_engine);
1797  if (eng_type)
1798  *eng_type= table_engine;
1799 
1800 
1801  /*
1802  We need to check all constant expressions that they are of the correct
1803  type and that they are increasing for ranges and not overlapping for
1804  list constants.
1805  */
1806 
1807  if (add_or_reorg_part)
1808  {
1809  if (unlikely((part_type == RANGE_PARTITION &&
1810  check_range_constants(thd)) ||
1811  (part_type == LIST_PARTITION &&
1812  check_list_constants(thd))))
1813  goto end;
1814  }
1815  result= FALSE;
1816 end:
1817  DBUG_RETURN(result);
1818 }
1819 
1820 
1821 /*
1822  Print error for no partition found
1823 
1824  SYNOPSIS
1825  print_no_partition_found()
1826  table Table object
1827 
1828  RETURN VALUES
1829 */
1830 
1831 void partition_info::print_no_partition_found(TABLE *table_arg)
1832 {
1833  char buf[100];
1834  char *buf_ptr= (char*)&buf;
1835  TABLE_LIST table_list;
1836 
1837  memset(&table_list, 0, sizeof(table_list));
1838  table_list.db= table_arg->s->db.str;
1839  table_list.table_name= table_arg->s->table_name.str;
1840 
1841  if (check_single_table_access(current_thd,
1842  SELECT_ACL, &table_list, TRUE))
1843  {
1844  my_message(ER_NO_PARTITION_FOR_GIVEN_VALUE,
1845  ER(ER_NO_PARTITION_FOR_GIVEN_VALUE_SILENT), MYF(0));
1846  }
1847  else
1848  {
1849  if (column_list)
1850  buf_ptr= (char*)"from column_list";
1851  else
1852  {
1853  my_bitmap_map *old_map= dbug_tmp_use_all_columns(table_arg, table_arg->read_set);
1854  if (part_expr->null_value)
1855  buf_ptr= (char*)"NULL";
1856  else
1857  longlong2str(err_value, buf,
1858  part_expr->unsigned_flag ? 10 : -10);
1859  dbug_tmp_restore_column_map(table_arg->read_set, old_map);
1860  }
1861  my_error(ER_NO_PARTITION_FOR_GIVEN_VALUE, MYF(0), buf_ptr);
1862  }
1863 }
1864 
1865 
1866 /*
1867  Set fields related to partition expression
1868  SYNOPSIS
1869  set_part_expr()
1870  start_token Start of partition function string
1871  item_ptr Pointer to item tree
1872  end_token End of partition function string
1873  is_subpart Subpartition indicator
1874  RETURN VALUES
1875  TRUE Memory allocation error
1876  FALSE Success
1877 */
1878 
1879 bool partition_info::set_part_expr(char *start_token, Item *item_ptr,
1880  char *end_token, bool is_subpart)
1881 {
1882  uint expr_len= end_token - start_token;
1883  char *func_string= (char*) sql_memdup(start_token, expr_len);
1884 
1885  if (!func_string)
1886  {
1887  mem_alloc_error(expr_len);
1888  return TRUE;
1889  }
1890  if (is_subpart)
1891  {
1892  list_of_subpart_fields= FALSE;
1893  subpart_expr= item_ptr;
1894  subpart_func_string= func_string;
1895  subpart_func_len= expr_len;
1896  }
1897  else
1898  {
1899  list_of_part_fields= FALSE;
1900  part_expr= item_ptr;
1901  part_func_string= func_string;
1902  part_func_len= expr_len;
1903  }
1904  return FALSE;
1905 }
1906 
1907 
1908 /*
1909  Check that partition fields and subpartition fields are not too long
1910 
1911  SYNOPSIS
1912  check_partition_field_length()
1913 
1914  RETURN VALUES
1915  TRUE Total length was too big
1916  FALSE Length is ok
1917 */
1918 
1919 bool partition_info::check_partition_field_length()
1920 {
1921  uint store_length= 0;
1922  uint i;
1923  DBUG_ENTER("partition_info::check_partition_field_length");
1924 
1925  for (i= 0; i < num_part_fields; i++)
1926  store_length+= get_partition_field_store_length(part_field_array[i]);
1927  if (store_length > MAX_KEY_LENGTH)
1928  DBUG_RETURN(TRUE);
1929  store_length= 0;
1930  for (i= 0; i < num_subpart_fields; i++)
1931  store_length+= get_partition_field_store_length(subpart_field_array[i]);
1932  if (store_length > MAX_KEY_LENGTH)
1933  DBUG_RETURN(TRUE);
1934  DBUG_RETURN(FALSE);
1935 }
1936 
1937 
1938 /*
1939  Set up buffers and arrays for fields requiring preparation
1940  SYNOPSIS
1941  set_up_charset_field_preps()
1942 
1943  RETURN VALUES
1944  TRUE Memory Allocation error
1945  FALSE Success
1946 
1947  DESCRIPTION
1948  Set up arrays and buffers for fields that require special care for
1949  calculation of partition id. This is used for string fields with
1950  variable length or string fields with fixed length that isn't using
1951  the binary collation.
1952 */
1953 
1954 bool partition_info::set_up_charset_field_preps()
1955 {
1956  Field *field, **ptr;
1957  uchar **char_ptrs;
1958  unsigned i;
1959  size_t size;
1960  uint tot_fields= 0;
1961  uint tot_part_fields= 0;
1962  uint tot_subpart_fields= 0;
1963  DBUG_ENTER("set_up_charset_field_preps");
1964 
1965  if (!(part_type == HASH_PARTITION &&
1966  list_of_part_fields) &&
1967  check_part_func_fields(part_field_array, FALSE))
1968  {
1969  ptr= part_field_array;
1970  /* Set up arrays and buffers for those fields */
1971  while ((field= *(ptr++)))
1972  {
1973  if (field_is_partition_charset(field))
1974  {
1975  tot_part_fields++;
1976  tot_fields++;
1977  }
1978  }
1979  size= tot_part_fields * sizeof(char*);
1980  if (!(char_ptrs= (uchar**)sql_calloc(size)))
1981  goto error;
1982  part_field_buffers= char_ptrs;
1983  if (!(char_ptrs= (uchar**)sql_calloc(size)))
1984  goto error;
1985  restore_part_field_ptrs= char_ptrs;
1986  size= (tot_part_fields + 1) * sizeof(Field*);
1987  if (!(char_ptrs= (uchar**)sql_alloc(size)))
1988  goto error;
1989  part_charset_field_array= (Field**)char_ptrs;
1990  ptr= part_field_array;
1991  i= 0;
1992  while ((field= *(ptr++)))
1993  {
1994  if (field_is_partition_charset(field))
1995  {
1996  uchar *field_buf;
1997  size= field->pack_length();
1998  if (!(field_buf= (uchar*) sql_calloc(size)))
1999  goto error;
2000  part_charset_field_array[i]= field;
2001  part_field_buffers[i++]= field_buf;
2002  }
2003  }
2004  part_charset_field_array[i]= NULL;
2005  }
2006  if (is_sub_partitioned() && !list_of_subpart_fields &&
2007  check_part_func_fields(subpart_field_array, FALSE))
2008  {
2009  /* Set up arrays and buffers for those fields */
2010  ptr= subpart_field_array;
2011  while ((field= *(ptr++)))
2012  {
2013  if (field_is_partition_charset(field))
2014  {
2015  tot_subpart_fields++;
2016  tot_fields++;
2017  }
2018  }
2019  size= tot_subpart_fields * sizeof(char*);
2020  if (!(char_ptrs= (uchar**) sql_calloc(size)))
2021  goto error;
2022  subpart_field_buffers= char_ptrs;
2023  if (!(char_ptrs= (uchar**) sql_calloc(size)))
2024  goto error;
2025  restore_subpart_field_ptrs= char_ptrs;
2026  size= (tot_subpart_fields + 1) * sizeof(Field*);
2027  if (!(char_ptrs= (uchar**) sql_alloc(size)))
2028  goto error;
2029  subpart_charset_field_array= (Field**)char_ptrs;
2030  ptr= subpart_field_array;
2031  i= 0;
2032  while ((field= *(ptr++)))
2033  {
2034  uchar *field_buf;
2035  LINT_INIT(field_buf);
2036 
2037  if (!field_is_partition_charset(field))
2038  continue;
2039  size= field->pack_length();
2040  if (!(field_buf= (uchar*) sql_calloc(size)))
2041  goto error;
2042  subpart_charset_field_array[i]= field;
2043  subpart_field_buffers[i++]= field_buf;
2044  }
2045  subpart_charset_field_array[i]= NULL;
2046  }
2047  DBUG_RETURN(FALSE);
2048 error:
2049  mem_alloc_error(size);
2050  DBUG_RETURN(TRUE);
2051 }
2052 
2053 
2054 /*
2055  Check if path does not contain mysql data home directory
2056  for partition elements with data directory and index directory
2057 
2058  SYNOPSIS
2059  check_partition_dirs()
2060  part_info partition_info struct
2061 
2062  RETURN VALUES
2063  0 ok
2064  1 error
2065 */
2066 
2067 bool check_partition_dirs(partition_info *part_info)
2068 {
2069  if (!part_info)
2070  return 0;
2071 
2072  partition_element *part_elem;
2073  List_iterator<partition_element> part_it(part_info->partitions);
2074  while ((part_elem= part_it++))
2075  {
2076  if (part_elem->subpartitions.elements)
2077  {
2078  List_iterator<partition_element> sub_it(part_elem->subpartitions);
2079  partition_element *subpart_elem;
2080  while ((subpart_elem= sub_it++))
2081  {
2082  if (test_if_data_home_dir(subpart_elem->data_file_name))
2083  goto dd_err;
2084  if (test_if_data_home_dir(subpart_elem->index_file_name))
2085  goto id_err;
2086  }
2087  }
2088  else
2089  {
2090  if (test_if_data_home_dir(part_elem->data_file_name))
2091  goto dd_err;
2092  if (test_if_data_home_dir(part_elem->index_file_name))
2093  goto id_err;
2094  }
2095  }
2096  return 0;
2097 
2098 dd_err:
2099  my_error(ER_WRONG_ARGUMENTS,MYF(0),"DATA DIRECTORY");
2100  return 1;
2101 
2102 id_err:
2103  my_error(ER_WRONG_ARGUMENTS,MYF(0),"INDEX DIRECTORY");
2104  return 1;
2105 }
2106 
2107 
2114 void partition_info::report_part_expr_error(bool use_subpart_expr)
2115 {
2116  Item *expr= part_expr;
2117  DBUG_ENTER("partition_info::report_part_expr_error");
2118  if (use_subpart_expr)
2119  expr= subpart_expr;
2120 
2121  if (expr->type() == Item::FIELD_ITEM)
2122  {
2123  partition_type type= part_type;
2124  bool list_of_fields= list_of_part_fields;
2125  Item_field *item_field= (Item_field*) expr;
2126  /*
2127  The expression consists of a single field.
2128  It must be of integer type unless KEY or COLUMNS partitioning.
2129  */
2130  if (use_subpart_expr)
2131  {
2132  type= subpart_type;
2133  list_of_fields= list_of_subpart_fields;
2134  }
2135  if (!column_list &&
2136  item_field->field &&
2137  item_field->field->result_type() != INT_RESULT &&
2138  !(type == HASH_PARTITION && list_of_fields))
2139  {
2140  my_error(ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD, MYF(0),
2141  item_field->item_name.ptr());
2142  DBUG_VOID_RETURN;
2143  }
2144  }
2145  if (use_subpart_expr)
2146  my_error(ER_PARTITION_FUNC_NOT_ALLOWED_ERROR, MYF(0), "SUBPARTITION");
2147  else
2148  my_error(ER_PARTITION_FUNC_NOT_ALLOWED_ERROR, MYF(0), "PARTITION");
2149  DBUG_VOID_RETURN;
2150 }
2151 
2152 
2163 bool partition_info::is_field_in_part_expr(List<Item> &fields)
2164 {
2165  List_iterator<Item> it(fields);
2166  Item *item;
2167  Item_field *field;
2168  DBUG_ENTER("is_fields_in_part_expr");
2169  while ((item= it++))
2170  {
2171  field= item->field_for_view_update();
2172  DBUG_ASSERT(field->field->table == table);
2173  if (bitmap_is_set(&full_part_field_set, field->field->field_index))
2174  DBUG_RETURN(true);
2175  }
2176  DBUG_RETURN(false);
2177 }
2178 
2179 
2184 bool partition_info::is_full_part_expr_in_fields(List<Item> &fields)
2185 {
2186  Field **part_field= full_part_field_array;
2187  DBUG_ASSERT(*part_field);
2188  DBUG_ENTER("is_full_part_expr_in_fields");
2189  /*
2190  It is very seldom many fields in full_part_field_array, so it is OK
2191  to loop over all of them instead of creating a bitmap fields argument
2192  to compare with.
2193  */
2194  do
2195  {
2196  List_iterator<Item> it(fields);
2197  Item *item;
2198  Item_field *field;
2199  bool found= false;
2200 
2201  while ((item= it++))
2202  {
2203  field= item->field_for_view_update();
2204  DBUG_ASSERT(field->field->table == table);
2205  if (*part_field == field->field)
2206  {
2207  found= true;
2208  break;
2209  }
2210  }
2211  if (!found)
2212  DBUG_RETURN(false);
2213  } while (*(++part_field));
2214  DBUG_RETURN(true);
2215 }
2216 
2217 
2228 bool partition_info::add_max_value()
2229 {
2230  DBUG_ENTER("partition_info::add_max_value");
2231 
2232  part_column_list_val *col_val;
2233  if (!(col_val= add_column_value()))
2234  {
2235  DBUG_RETURN(TRUE);
2236  }
2237  col_val->max_value= TRUE;
2238  DBUG_RETURN(FALSE);
2239 }
2240 
2241 
2253 part_column_list_val *partition_info::add_column_value()
2254 {
2255  uint max_val= num_columns ? num_columns : MAX_REF_PARTS;
2256  DBUG_ENTER("add_column_value");
2257  DBUG_PRINT("enter", ("num_columns = %u, curr_list_object %u, max_val = %u",
2258  num_columns, curr_list_object, max_val));
2259  if (curr_list_object < max_val)
2260  {
2261  curr_list_val->added_items++;
2262  DBUG_RETURN(&curr_list_val->col_val_array[curr_list_object++]);
2263  }
2264  if (!num_columns && part_type == LIST_PARTITION)
2265  {
2266  /*
2267  We're trying to add more than MAX_REF_PARTS, this can happen
2268  in ALTER TABLE using List partitions where the first partition
2269  uses VALUES IN (1,2,3...,17) where the number of fields in
2270  the list is more than MAX_REF_PARTS, in this case we know
2271  that the number of columns must be 1 and we thus reorganize
2272  into the structure used for 1 column. After this we call
2273  ourselves recursively which should always succeed.
2274  */
2275  if (!reorganize_into_single_field_col_val() && !init_column_part())
2276  {
2277  DBUG_RETURN(add_column_value());
2278  }
2279  DBUG_RETURN(NULL);
2280  }
2281  if (column_list)
2282  {
2283  my_error(ER_PARTITION_COLUMN_LIST_ERROR, MYF(0));
2284  }
2285  else
2286  {
2287  if (part_type == RANGE_PARTITION)
2288  my_error(ER_TOO_MANY_VALUES_ERROR, MYF(0), "RANGE");
2289  else
2290  my_error(ER_TOO_MANY_VALUES_ERROR, MYF(0), "LIST");
2291  }
2292  DBUG_RETURN(NULL);
2293 }
2294 
2295 
2309 void partition_info::init_col_val(part_column_list_val *col_val, Item *item)
2310 {
2311  DBUG_ENTER("partition_info::init_col_val");
2312 
2313  col_val->item_expression= item;
2314  col_val->null_value= item->null_value;
2315  if (item->result_type() == INT_RESULT)
2316  {
2317  /*
2318  This could be both column_list partitioning and function
2319  partitioning, but it doesn't hurt to set the function
2320  partitioning flags about unsignedness.
2321  */
2322  curr_list_val->value= item->val_int();
2323  curr_list_val->unsigned_flag= TRUE;
2324  if (!item->unsigned_flag &&
2325  curr_list_val->value < 0)
2326  curr_list_val->unsigned_flag= FALSE;
2327  if (!curr_list_val->unsigned_flag)
2328  curr_part_elem->signed_flag= TRUE;
2329  }
2330  col_val->part_info= NULL;
2331  DBUG_VOID_RETURN;
2332 }
2333 
2334 
2348 bool partition_info::add_column_list_value(THD *thd, Item *item)
2349 {
2350  part_column_list_val *col_val;
2351  Name_resolution_context *context= &thd->lex->current_select->context;
2352  TABLE_LIST *save_list= context->table_list;
2353  const char *save_where= thd->where;
2354  DBUG_ENTER("partition_info::add_column_list_value");
2355 
2356  if (part_type == LIST_PARTITION &&
2357  num_columns == 1U)
2358  {
2359  if (init_column_part())
2360  {
2361  DBUG_RETURN(TRUE);
2362  }
2363  }
2364 
2365  context->table_list= 0;
2366  if (column_list)
2367  thd->where= "field list";
2368  else
2369  thd->where= "partition function";
2370 
2371  if (item->walk(&Item::check_partition_func_processor, 0,
2372  NULL))
2373  {
2374  my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
2375  DBUG_RETURN(TRUE);
2376  }
2377  if (item->fix_fields(thd, (Item**)0) ||
2378  ((context->table_list= save_list), FALSE) ||
2379  (!item->const_item()))
2380  {
2381  context->table_list= save_list;
2382  thd->where= save_where;
2383  my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
2384  DBUG_RETURN(TRUE);
2385  }
2386  thd->where= save_where;
2387 
2388  if (!(col_val= add_column_value()))
2389  {
2390  DBUG_RETURN(TRUE);
2391  }
2392  init_col_val(col_val, item);
2393  DBUG_RETURN(FALSE);
2394 }
2395 
2396 
2409 bool partition_info::init_column_part()
2410 {
2411  partition_element *p_elem= curr_part_elem;
2412  part_column_list_val *col_val_array;
2413  part_elem_value *list_val;
2414  uint loc_num_columns;
2415  DBUG_ENTER("partition_info::init_column_part");
2416 
2417  if (!(list_val=
2418  (part_elem_value*)sql_calloc(sizeof(part_elem_value))) ||
2419  p_elem->list_val_list.push_back(list_val))
2420  {
2421  mem_alloc_error(sizeof(part_elem_value));
2422  DBUG_RETURN(TRUE);
2423  }
2424  if (num_columns)
2425  loc_num_columns= num_columns;
2426  else
2427  loc_num_columns= MAX_REF_PARTS;
2428  if (!(col_val_array=
2429  (part_column_list_val*)sql_calloc(loc_num_columns *
2430  sizeof(part_column_list_val))))
2431  {
2432  mem_alloc_error(loc_num_columns * sizeof(part_elem_value));
2433  DBUG_RETURN(TRUE);
2434  }
2435  list_val->col_val_array= col_val_array;
2436  list_val->added_items= 0;
2437  curr_list_val= list_val;
2438  curr_list_object= 0;
2439  DBUG_RETURN(FALSE);
2440 }
2441 
2442 
2464 bool partition_info::reorganize_into_single_field_col_val()
2465 {
2466  part_column_list_val *col_val, *new_col_val;
2467  part_elem_value *val= curr_list_val;
2468  uint num_values= num_columns;
2469  uint i;
2470  DBUG_ENTER("partition_info::reorganize_into_single_field_col_val");
2471  DBUG_ASSERT(part_type == LIST_PARTITION);
2472  DBUG_ASSERT(!num_columns || num_columns == val->added_items);
2473 
2474  if (!num_values)
2475  num_values= val->added_items;
2476  num_columns= 1;
2477  val->added_items= 1U;
2478  col_val= &val->col_val_array[0];
2479  init_col_val(col_val, col_val->item_expression);
2480  for (i= 1; i < num_values; i++)
2481  {
2482  col_val= &val->col_val_array[i];
2483  if (init_column_part())
2484  {
2485  DBUG_RETURN(TRUE);
2486  }
2487  if (!(new_col_val= add_column_value()))
2488  {
2489  DBUG_RETURN(TRUE);
2490  }
2491  memcpy(new_col_val, col_val, sizeof(*col_val));
2492  init_col_val(new_col_val, col_val->item_expression);
2493  }
2494  curr_list_val= val;
2495  DBUG_RETURN(FALSE);
2496 }
2497 
2498 
2516 bool partition_info::fix_partition_values(THD *thd,
2517  part_elem_value *val,
2518  partition_element *part_elem,
2519  uint part_id)
2520 {
2521  part_column_list_val *col_val= val->col_val_array;
2522  DBUG_ENTER("partition_info::fix_partition_values");
2523 
2524  if (col_val->fixed)
2525  {
2526  DBUG_RETURN(FALSE);
2527  }
2528  if (val->added_items != 1)
2529  {
2530  my_error(ER_PARTITION_COLUMN_LIST_ERROR, MYF(0));
2531  DBUG_RETURN(TRUE);
2532  }
2533  if (col_val->max_value)
2534  {
2535  /* The parser ensures we're not LIST partitioned here */
2536  DBUG_ASSERT(part_type == RANGE_PARTITION);
2537  if (defined_max_value)
2538  {
2539  my_error(ER_PARTITION_MAXVALUE_ERROR, MYF(0));
2540  DBUG_RETURN(TRUE);
2541  }
2542  if (part_id == (num_parts - 1))
2543  {
2544  defined_max_value= TRUE;
2545  part_elem->max_value= TRUE;
2546  part_elem->range_value= LONGLONG_MAX;
2547  }
2548  else
2549  {
2550  my_error(ER_PARTITION_MAXVALUE_ERROR, MYF(0));
2551  DBUG_RETURN(TRUE);
2552  }
2553  }
2554  else
2555  {
2556  Item *item_expr= col_val->item_expression;
2557  if ((val->null_value= item_expr->null_value))
2558  {
2559  if (part_elem->has_null_value)
2560  {
2561  my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0));
2562  DBUG_RETURN(TRUE);
2563  }
2564  part_elem->has_null_value= TRUE;
2565  }
2566  else if (item_expr->result_type() != INT_RESULT)
2567  {
2568  my_error(ER_VALUES_IS_NOT_INT_TYPE_ERROR, MYF(0),
2569  part_elem->partition_name);
2570  DBUG_RETURN(TRUE);
2571  }
2572  if (part_type == RANGE_PARTITION)
2573  {
2574  if (part_elem->has_null_value)
2575  {
2576  my_error(ER_NULL_IN_VALUES_LESS_THAN, MYF(0));
2577  DBUG_RETURN(TRUE);
2578  }
2579  part_elem->range_value= val->value;
2580  }
2581  }
2582  col_val->fixed= 2;
2583  DBUG_RETURN(FALSE);
2584 }
2585 
2586 
2598 Item* partition_info::get_column_item(Item *item, Field *field)
2599 {
2600  if (field->result_type() == STRING_RESULT &&
2601  item->collation.collation != field->charset())
2602  {
2603  if (!(item= convert_charset_partition_constant(item,
2604  field->charset())))
2605  {
2606  my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
2607  return NULL;
2608  }
2609  }
2610  return item;
2611 }
2612 
2613 
2628 bool partition_info::fix_column_value_functions(THD *thd,
2629  part_elem_value *val,
2630  uint part_id)
2631 {
2632  uint n_columns= part_field_list.elements;
2633  bool result= FALSE;
2634  uint i;
2635  part_column_list_val *col_val= val->col_val_array;
2636  DBUG_ENTER("partition_info::fix_column_value_functions");
2637 
2638  if (col_val->fixed > 1)
2639  {
2640  DBUG_RETURN(FALSE);
2641  }
2642  for (i= 0; i < n_columns; col_val++, i++)
2643  {
2644  Item *column_item= col_val->item_expression;
2645  Field *field= part_field_array[i];
2646  col_val->part_info= this;
2647  col_val->partition_id= part_id;
2648  if (col_val->max_value)
2649  col_val->column_value= NULL;
2650  else
2651  {
2652  col_val->column_value= NULL;
2653  if (!col_val->null_value)
2654  {
2655  uchar *val_ptr;
2656  uint len= field->pack_length();
2657  sql_mode_t save_sql_mode;
2658  bool save_got_warning;
2659 
2660  if (!(column_item= get_column_item(column_item,
2661  field)))
2662  {
2663  result= TRUE;
2664  goto end;
2665  }
2666  save_sql_mode= thd->variables.sql_mode;
2667  thd->variables.sql_mode= 0;
2668  save_got_warning= thd->got_warning;
2669  thd->got_warning= 0;
2670  if (column_item->save_in_field(field, TRUE) ||
2671  thd->got_warning)
2672  {
2673  my_error(ER_WRONG_TYPE_COLUMN_VALUE_ERROR, MYF(0));
2674  result= TRUE;
2675  goto end;
2676  }
2677  thd->got_warning= save_got_warning;
2678  thd->variables.sql_mode= save_sql_mode;
2679  if (!(val_ptr= (uchar*) sql_calloc(len)))
2680  {
2681  mem_alloc_error(len);
2682  result= TRUE;
2683  goto end;
2684  }
2685  col_val->column_value= val_ptr;
2686  memcpy(val_ptr, field->ptr, len);
2687  }
2688  }
2689  col_val->fixed= 2;
2690  }
2691 end:
2692  DBUG_RETURN(result);
2693 }
2694 
2738 bool partition_info::fix_parser_data(THD *thd)
2739 {
2740  List_iterator<partition_element> it(partitions);
2741  partition_element *part_elem;
2742  uint num_elements;
2743  uint i= 0, j, k;
2744  DBUG_ENTER("partition_info::fix_parser_data");
2745 
2746  if (!(part_type == RANGE_PARTITION ||
2747  part_type == LIST_PARTITION))
2748  {
2749  if (part_type == HASH_PARTITION && list_of_part_fields)
2750  {
2751  /* KEY partitioning, check ALGORITHM = N. Should not pass the parser! */
2752  if (key_algorithm > KEY_ALGORITHM_55)
2753  {
2754  my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
2755  DBUG_RETURN(true);
2756  }
2757  /* If not set, use DEFAULT = 2 for CREATE and ALTER! */
2758  if ((thd_sql_command(thd) == SQLCOM_CREATE_TABLE ||
2759  thd_sql_command(thd) == SQLCOM_ALTER_TABLE) &&
2760  key_algorithm == KEY_ALGORITHM_NONE)
2761  key_algorithm= KEY_ALGORITHM_55;
2762  }
2763  DBUG_RETURN(FALSE);
2764  }
2765  if (is_sub_partitioned() && list_of_subpart_fields)
2766  {
2767  /* KEY subpartitioning, check ALGORITHM = N. Should not pass the parser! */
2768  if (key_algorithm > KEY_ALGORITHM_55)
2769  {
2770  my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
2771  DBUG_RETURN(true);
2772  }
2773  /* If not set, use DEFAULT = 2 for CREATE and ALTER! */
2774  if ((thd_sql_command(thd) == SQLCOM_CREATE_TABLE ||
2775  thd_sql_command(thd) == SQLCOM_ALTER_TABLE) &&
2776  key_algorithm == KEY_ALGORITHM_NONE)
2777  key_algorithm= KEY_ALGORITHM_55;
2778  }
2779  do
2780  {
2781  part_elem= it++;
2782  List_iterator<part_elem_value> list_val_it(part_elem->list_val_list);
2783  num_elements= part_elem->list_val_list.elements;
2784  DBUG_ASSERT(part_type == RANGE_PARTITION ?
2785  num_elements == 1U : TRUE);
2786  for (j= 0; j < num_elements; j++)
2787  {
2788  part_elem_value *val= list_val_it++;
2789  if (column_list)
2790  {
2791  if (val->added_items != num_columns)
2792  {
2793  my_error(ER_PARTITION_COLUMN_LIST_ERROR, MYF(0));
2794  DBUG_RETURN(TRUE);
2795  }
2796  for (k= 0; k < num_columns; k++)
2797  {
2798  part_column_list_val *col_val= &val->col_val_array[k];
2799  if (col_val->null_value && part_type == RANGE_PARTITION)
2800  {
2801  my_error(ER_NULL_IN_VALUES_LESS_THAN, MYF(0));
2802  DBUG_RETURN(TRUE);
2803  }
2804  }
2805  }
2806  else
2807  {
2808  if (fix_partition_values(thd, val, part_elem, i))
2809  {
2810  DBUG_RETURN(TRUE);
2811  }
2812  if (val->null_value)
2813  {
2814  /*
2815  Null values aren't required in the value part, they are kept per
2816  partition instance, only LIST partitions have NULL values.
2817  */
2818  list_val_it.remove();
2819  }
2820  }
2821  }
2822  } while (++i < num_parts);
2823  DBUG_RETURN(FALSE);
2824 }
2825 
2826 
2839 static bool strcmp_null(const char *a, const char *b)
2840 {
2841  if (!a && !b)
2842  return false;
2843  if (a && b && !strcmp(a, b))
2844  return false;
2845  return true;
2846 }
2847 
2848 
2866 bool partition_info::has_same_partitioning(partition_info *new_part_info)
2867 {
2868  DBUG_ENTER("partition_info::has_same_partitioning");
2869 
2870  DBUG_ASSERT(part_field_array && part_field_array[0]);
2871 
2872  /*
2873  Only consider pre 5.5.3 .frm's to have same partitioning as
2874  a new one with KEY ALGORITHM = 1 ().
2875  */
2876 
2877  if (part_field_array[0]->table->s->mysql_version >= 50503)
2878  DBUG_RETURN(false);
2879 
2880  if (!new_part_info ||
2881  part_type != new_part_info->part_type ||
2882  num_parts != new_part_info->num_parts ||
2883  use_default_partitions != new_part_info->use_default_partitions ||
2884  new_part_info->is_sub_partitioned() != is_sub_partitioned())
2885  DBUG_RETURN(false);
2886 
2887  if (part_type != HASH_PARTITION)
2888  {
2889  /*
2890  RANGE or LIST partitioning, check if KEY subpartitioned.
2891  Also COLUMNS partitioning was added in 5.5, so treat that as different.
2892  */
2893  if (!is_sub_partitioned() ||
2894  !new_part_info->is_sub_partitioned() ||
2895  column_list ||
2896  new_part_info->column_list ||
2897  !list_of_subpart_fields ||
2898  !new_part_info->list_of_subpart_fields ||
2899  new_part_info->num_subparts != num_subparts ||
2900  new_part_info->subpart_field_list.elements !=
2901  subpart_field_list.elements ||
2902  new_part_info->use_default_subpartitions !=
2903  use_default_subpartitions)
2904  DBUG_RETURN(false);
2905  }
2906  else
2907  {
2908  /* Check if KEY partitioned. */
2909  if (!new_part_info->list_of_part_fields ||
2910  !list_of_part_fields ||
2911  new_part_info->part_field_list.elements != part_field_list.elements)
2912  DBUG_RETURN(false);
2913  }
2914 
2915  /* Check that it will use the same fields in KEY (fields) list. */
2916  List_iterator<char> old_field_name_it(part_field_list);
2917  List_iterator<char> new_field_name_it(new_part_info->part_field_list);
2918  char *old_name, *new_name;
2919  while ((old_name= old_field_name_it++))
2920  {
2921  new_name= new_field_name_it++;
2922  if (!new_name || my_strcasecmp(system_charset_info,
2923  new_name,
2924  old_name))
2925  DBUG_RETURN(false);
2926  }
2927 
2928  if (is_sub_partitioned())
2929  {
2930  /* Check that it will use the same fields in KEY subpart fields list. */
2931  List_iterator<char> old_field_name_it(subpart_field_list);
2932  List_iterator<char> new_field_name_it(new_part_info->subpart_field_list);
2933  char *old_name, *new_name;
2934  while ((old_name= old_field_name_it++))
2935  {
2936  new_name= new_field_name_it++;
2937  if (!new_name || my_strcasecmp(system_charset_info,
2938  new_name,
2939  old_name))
2940  DBUG_RETURN(false);
2941  }
2942  }
2943 
2944  if (!use_default_partitions)
2945  {
2946  /*
2947  Loop over partitions/subpartition to verify that they are
2948  the same, including state and name.
2949  */
2950  List_iterator<partition_element> part_it(partitions);
2951  List_iterator<partition_element> new_part_it(new_part_info->partitions);
2952  uint i= 0;
2953  do
2954  {
2955  partition_element *part_elem= part_it++;
2956  partition_element *new_part_elem= new_part_it++;
2957  /*
2958  The following must match:
2959  partition_name, tablespace_name, data_file_name, index_file_name,
2960  engine_type, part_max_rows, part_min_rows, nodegroup_id.
2961  (max_value, signed_flag, has_null_value only on partition level,
2962  RANGE/LIST)
2963  The following can differ:
2964  - part_comment
2965  part_state must be PART_NORMAL!
2966  */
2967  if (!part_elem || !new_part_elem ||
2968  strcmp(part_elem->partition_name,
2969  new_part_elem->partition_name) ||
2970  part_elem->part_state != PART_NORMAL ||
2971  new_part_elem->part_state != PART_NORMAL ||
2972  part_elem->max_value != new_part_elem->max_value ||
2973  part_elem->signed_flag != new_part_elem->signed_flag ||
2974  part_elem->has_null_value != new_part_elem->has_null_value)
2975  DBUG_RETURN(false);
2976 
2977  /* new_part_elem may not have engine_type set! */
2978  if (new_part_elem->engine_type &&
2979  part_elem->engine_type != new_part_elem->engine_type)
2980  DBUG_RETURN(false);
2981 
2982  if (is_sub_partitioned())
2983  {
2984  /*
2985  Check that both old and new partition has the same definition
2986  (VALUES IN/VALUES LESS THAN) (No COLUMNS partitioning, see above)
2987  */
2988  if (part_type == LIST_PARTITION)
2989  {
2990  List_iterator<part_elem_value> list_vals(part_elem->list_val_list);
2992  new_list_vals(new_part_elem->list_val_list);
2993  part_elem_value *val;
2994  part_elem_value *new_val;
2995  while ((val= list_vals++))
2996  {
2997  new_val= new_list_vals++;
2998  if (!new_val)
2999  DBUG_RETURN(false);
3000  if ((!val->null_value && !new_val->null_value) &&
3001  val->value != new_val->value)
3002  DBUG_RETURN(false);
3003  }
3004  if (new_list_vals++)
3005  DBUG_RETURN(false);
3006  }
3007  else
3008  {
3009  DBUG_ASSERT(part_type == RANGE_PARTITION);
3010  if (new_part_elem->range_value != part_elem->range_value)
3011  DBUG_RETURN(false);
3012  }
3013 
3014  if (!use_default_subpartitions)
3015  {
3017  sub_part_it(part_elem->subpartitions);
3019  new_sub_part_it(new_part_elem->subpartitions);
3020  uint j= 0;
3021  do
3022  {
3023  partition_element *sub_part_elem= sub_part_it++;
3024  partition_element *new_sub_part_elem= new_sub_part_it++;
3025  /* new_part_elem may not have engine_type set! */
3026  if (new_sub_part_elem->engine_type &&
3027  sub_part_elem->engine_type != new_sub_part_elem->engine_type)
3028  DBUG_RETURN(false);
3029 
3030  if (strcmp(sub_part_elem->partition_name,
3031  new_sub_part_elem->partition_name) ||
3032  sub_part_elem->part_state != PART_NORMAL ||
3033  new_sub_part_elem->part_state != PART_NORMAL ||
3034  sub_part_elem->part_min_rows !=
3035  new_sub_part_elem->part_min_rows ||
3036  sub_part_elem->part_max_rows !=
3037  new_sub_part_elem->part_max_rows ||
3038  sub_part_elem->nodegroup_id !=
3039  new_sub_part_elem->nodegroup_id)
3040  DBUG_RETURN(false);
3041 
3042  if (strcmp_null(sub_part_elem->data_file_name,
3043  new_sub_part_elem->data_file_name) ||
3044  strcmp_null(sub_part_elem->index_file_name,
3045  new_sub_part_elem->index_file_name) ||
3046  strcmp_null(sub_part_elem->tablespace_name,
3047  new_sub_part_elem->tablespace_name))
3048  DBUG_RETURN(false);
3049 
3050  } while (++j < num_subparts);
3051  }
3052  }
3053  else
3054  {
3055  if (part_elem->part_min_rows != new_part_elem->part_min_rows ||
3056  part_elem->part_max_rows != new_part_elem->part_max_rows ||
3057  part_elem->nodegroup_id != new_part_elem->nodegroup_id)
3058  DBUG_RETURN(false);
3059 
3060  if (strcmp_null(part_elem->data_file_name,
3061  new_part_elem->data_file_name) ||
3062  strcmp_null(part_elem->index_file_name,
3063  new_part_elem->index_file_name) ||
3064  strcmp_null(part_elem->tablespace_name,
3065  new_part_elem->tablespace_name))
3066  DBUG_RETURN(false);
3067  }
3068  } while (++i < num_parts);
3069  }
3070 
3071  /*
3072  Only if key_algorithm was not specified before and it is now set,
3073  consider this as nothing was changed, and allow change without rebuild!
3074  */
3075  if (key_algorithm != partition_info::KEY_ALGORITHM_NONE ||
3076  new_part_info->key_algorithm == partition_info::KEY_ALGORITHM_NONE)
3077  DBUG_RETURN(false);
3078 
3079  DBUG_RETURN(true);
3080 }
3081 
3082 
3083 void partition_info::print_debug(const char *str, uint *value)
3084 {
3085  DBUG_ENTER("print_debug");
3086  if (value)
3087  DBUG_PRINT("info", ("parser: %s, val = %u", str, *value));
3088  else
3089  DBUG_PRINT("info", ("parser: %s", str));
3090  DBUG_VOID_RETURN;
3091 }
3092 #else /* WITH_PARTITION_STORAGE_ENGINE */
3093  /*
3094  For builds without partitioning we need to define these functions
3095  since we they are called from the parser. The parser cannot
3096  remove code parts using ifdef, but the code parts cannot be called
3097  so we simply need to add empty functions to make the linker happy.
3098  */
3099 part_column_list_val *partition_info::add_column_value()
3100 {
3101  return NULL;
3102 }
3103 
3104 bool partition_info::set_part_expr(char *start_token, Item *item_ptr,
3105  char *end_token, bool is_subpart)
3106 {
3107  (void)start_token;
3108  (void)item_ptr;
3109  (void)end_token;
3110  (void)is_subpart;
3111  return FALSE;
3112 }
3113 
3114 bool partition_info::reorganize_into_single_field_col_val()
3115 {
3116  return 0;
3117 }
3118 
3119 bool partition_info::init_column_part()
3120 {
3121  return FALSE;
3122 }
3123 
3124 bool partition_info::add_column_list_value(THD *thd, Item *item)
3125 {
3126  return FALSE;
3127 }
3128 
3129 bool partition_info::add_max_value()
3130 {
3131  return false;
3132 }
3133 
3134 void partition_info::print_debug(const char *str, uint *value)
3135 {
3136 }
3137 
3138 #endif /* WITH_PARTITION_STORAGE_ENGINE */