~ubuntu-branches/ubuntu/lucid/mysql-dfsg-5.1/lucid-security

« back to all changes in this revision

Viewing changes to sql/sql_partition.cc

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2012-02-22 22:33:55 UTC
  • mto: (1.2.1) (37.1.1 lucid-security)
  • mto: This revision was merged to the branch mainline in revision 36.
  • Revision ID: package-import@ubuntu.com-20120222223355-ku1tb4r70osci6v2
Tags: upstream-5.1.61
ImportĀ upstreamĀ versionĀ 5.1.61

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright 2005-2008 MySQL AB, 2008 Sun Microsystems, Inc.
 
1
/* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
2
2
 
3
3
   This program is free software; you can redistribute it and/or modify
4
4
   it under the terms of the GNU General Public License as published by
196
196
{
197
197
  DBUG_ENTER("partition_default_handling");
198
198
 
199
 
  if (part_info->use_default_no_partitions)
200
 
  {
201
 
    if (!is_create_table_ind &&
202
 
        table->file->get_no_parts(normalized_path, &part_info->no_parts))
203
 
    {
204
 
      DBUG_RETURN(TRUE);
205
 
    }
206
 
  }
207
 
  else if (part_info->is_sub_partitioned() &&
208
 
           part_info->use_default_no_subpartitions)
209
 
  {
210
 
    uint no_parts;
211
 
    if (!is_create_table_ind &&
212
 
        (table->file->get_no_parts(normalized_path, &no_parts)))
213
 
    {
214
 
      DBUG_RETURN(TRUE);
215
 
    }
216
 
    DBUG_ASSERT(part_info->no_parts > 0);
217
 
    part_info->no_subparts= no_parts / part_info->no_parts;
218
 
    DBUG_ASSERT((no_parts % part_info->no_parts) == 0);
 
199
  if (!is_create_table_ind)
 
200
  {
 
201
    if (part_info->use_default_no_partitions)
 
202
    {
 
203
      if (table->file->get_no_parts(normalized_path, &part_info->no_parts))
 
204
      {
 
205
        DBUG_RETURN(TRUE);
 
206
      }
 
207
    }
 
208
    else if (part_info->is_sub_partitioned() &&
 
209
             part_info->use_default_no_subpartitions)
 
210
    {
 
211
      uint no_parts;
 
212
      if (table->file->get_no_parts(normalized_path, &no_parts))
 
213
      {
 
214
        DBUG_RETURN(TRUE);
 
215
      }
 
216
      DBUG_ASSERT(part_info->no_parts > 0);
 
217
      DBUG_ASSERT((no_parts % part_info->no_parts) == 0);
 
218
      part_info->no_subparts= no_parts / part_info->no_parts;
 
219
    }
219
220
  }
220
221
  part_info->set_up_defaults_for_partitioning(table->file,
221
222
                                              (ulonglong)0, (uint)0);
760
761
  bool result;
761
762
  char *field_name;
762
763
  bool is_list_empty= TRUE;
 
764
  int fields_handled = 0;
 
765
  char* field_name_array[MAX_KEY];
 
766
 
763
767
  DBUG_ENTER("handle_list_of_fields");
764
768
 
765
769
  while ((field_name= it++))
775
779
      result= TRUE;
776
780
      goto end;
777
781
    }
 
782
 
 
783
    /*
 
784
      Check for duplicate fields in the list.
 
785
      Assuming that there are not many fields in the partition key list.
 
786
      If there were, it would be better to replace the for-loop
 
787
      with a more efficient algorithm.
 
788
    */
 
789
 
 
790
    field_name_array[fields_handled] = field_name;
 
791
    for (int i = 0; i < fields_handled; ++i)
 
792
    {
 
793
      if (my_strcasecmp(system_charset_info,
 
794
                        field_name_array[i], field_name) == 0)
 
795
      {
 
796
        my_error(ER_FIELD_NOT_FOUND_PART_ERROR, MYF(0));
 
797
        DBUG_RETURN(TRUE);
 
798
      }
 
799
    }
 
800
    fields_handled++;
778
801
  }
779
802
  if (is_list_empty)
780
803
  {
869
892
    part_info            Reference to partitioning data structure
870
893
    is_sub_part          Is the table subpartitioned as well
871
894
    is_field_to_be_setup Flag if we are to set-up field arrays
 
895
    is_create_table_ind  Indicator of whether openfrm was called as part of
 
896
                         CREATE or ALTER TABLE
872
897
 
873
898
  RETURN VALUE
874
899
    TRUE                 An error occurred, something was wrong with the
891
916
    on the field object.
892
917
*/
893
918
 
894
 
bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
895
 
                          bool is_sub_part, bool is_field_to_be_setup)
 
919
static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
 
920
                          bool is_sub_part, bool is_field_to_be_setup,
 
921
                          bool is_create_table_ind)
896
922
{
897
923
  partition_info *part_info= table->part_info;
898
924
  uint dir_length, home_dir_length;
904
930
  const char *save_where;
905
931
  char* db_name;
906
932
  char db_name_string[FN_REFLEN];
907
 
  bool save_use_only_table_context;
908
933
  DBUG_ENTER("fix_fields_part_func");
909
934
 
910
935
  if (part_info->fixed)
971
996
    of interesting side effects, both desirable and undesirable.
972
997
  */
973
998
 
974
 
  save_use_only_table_context= thd->lex->use_only_table_context;
975
 
  thd->lex->use_only_table_context= TRUE;
976
 
  thd->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
 
999
  {
 
1000
    const bool save_use_only_table_context= thd->lex->use_only_table_context;
 
1001
    thd->lex->use_only_table_context= TRUE;
 
1002
    thd->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
 
1003
    const bool save_agg_field= thd->lex->current_select->non_agg_field_used();
 
1004
    const bool save_agg_func=  thd->lex->current_select->agg_func_used();
 
1005
    const nesting_map saved_allow_sum_func= thd->lex->allow_sum_func;
 
1006
    thd->lex->allow_sum_func= 0;
977
1007
  
978
 
  error= func_expr->fix_fields(thd, (Item**)&func_expr);
 
1008
    error= func_expr->fix_fields(thd, (Item**)&func_expr);
979
1009
 
980
 
  thd->lex->use_only_table_context= save_use_only_table_context;
 
1010
    /*
 
1011
      Restore agg_field/agg_func and allow_sum_func,
 
1012
      fix_fields should not affect mysql_select later, see Bug#46923.
 
1013
    */
 
1014
    thd->lex->current_select->set_non_agg_field_used(save_agg_field);
 
1015
    thd->lex->current_select->set_agg_func_used(save_agg_func);
 
1016
    thd->lex->allow_sum_func= saved_allow_sum_func;
 
1017
    thd->lex->use_only_table_context= save_use_only_table_context;
 
1018
  }
981
1019
 
982
1020
  context->table_list= save_table_list;
983
1021
  context->first_name_resolution_table= save_first_table;
992
1030
  thd->where= save_where;
993
1031
  if (unlikely(func_expr->const_item()))
994
1032
  {
995
 
    my_error(ER_CONST_EXPR_IN_PARTITION_FUNC_ERROR, MYF(0));
 
1033
    my_error(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR, MYF(0));
996
1034
    clear_field_flag(table);
997
1035
    goto end;
998
1036
  }
 
1037
 
 
1038
  /*
 
1039
    We don't allow creating partitions with expressions with non matching
 
1040
    arguments as a (sub)partitioning function,
 
1041
    but we want to allow such expressions when opening existing tables for
 
1042
    easier maintenance. This exception should be deprecated at some point
 
1043
    in future so that we always throw an error.
 
1044
  */
 
1045
  if (func_expr->walk(&Item::check_valid_arguments_processor,
 
1046
                      0, NULL))
 
1047
  {
 
1048
    if (is_create_table_ind)
 
1049
    {
 
1050
      my_error(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR, MYF(0));
 
1051
      goto end;
 
1052
    }
 
1053
    else
 
1054
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
1055
                   ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR,
 
1056
                   ER(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR));
 
1057
  }
 
1058
 
999
1059
  if ((!is_sub_part) && (error= check_signed_flag(part_info)))
1000
1060
    goto end;
1001
1061
  result= FALSE;
1603
1663
    else
1604
1664
    {
1605
1665
      if (unlikely(fix_fields_part_func(thd, part_info->subpart_expr,
1606
 
                                        table, TRUE, TRUE)))
 
1666
                                        table, TRUE, TRUE,
 
1667
                                        is_create_table_ind)))
1607
1668
        goto end;
1608
1669
      if (unlikely(part_info->subpart_expr->result_type() != INT_RESULT))
1609
1670
      {
1631
1692
    else
1632
1693
    {
1633
1694
      if (unlikely(fix_fields_part_func(thd, part_info->part_expr,
1634
 
                                        table, FALSE, TRUE)))
 
1695
                                        table, FALSE, TRUE,
 
1696
                                        is_create_table_ind)))
1635
1697
        goto end;
1636
1698
      if (unlikely(part_info->part_expr->result_type() != INT_RESULT))
1637
1699
      {
1645
1707
  {
1646
1708
    const char *error_str;
1647
1709
    if (unlikely(fix_fields_part_func(thd, part_info->part_expr,
1648
 
                                      table, FALSE, TRUE)))
 
1710
                                      table, FALSE, TRUE,
 
1711
                                      is_create_table_ind)))
1649
1712
      goto end;
1650
1713
    if (part_info->part_type == RANGE_PARTITION)
1651
1714
    {
1679
1742
  if (((part_info->part_type != HASH_PARTITION ||
1680
1743
      part_info->list_of_part_fields == FALSE) &&
1681
1744
      check_part_func_fields(part_info->part_field_array, TRUE)) ||
1682
 
      (part_info->list_of_part_fields == FALSE &&
 
1745
      (part_info->list_of_subpart_fields == FALSE &&
1683
1746
       part_info->is_sub_partitioned() &&
1684
1747
       check_part_func_fields(part_info->subpart_field_array, TRUE)))
1685
1748
  {
2836
2899
  *func_value= part_func_value;
2837
2900
  if (unsigned_flag)
2838
2901
    part_func_value-= 0x8000000000000000ULL;
 
2902
  /* Search for the partition containing part_func_value */
2839
2903
  while (max_part_id > min_part_id)
2840
2904
  {
2841
 
    loc_part_id= (max_part_id + min_part_id + 1) >> 1;
 
2905
    loc_part_id= (max_part_id + min_part_id) / 2;
2842
2906
    if (range_array[loc_part_id] <= part_func_value)
2843
2907
      min_part_id= loc_part_id + 1;
2844
2908
    else
2845
 
      max_part_id= loc_part_id - 1;
 
2909
      max_part_id= loc_part_id;
2846
2910
  }
2847
2911
  loc_part_id= max_part_id;
2848
 
  if (part_func_value >= range_array[loc_part_id])
2849
 
    if (loc_part_id != max_partition)
2850
 
      loc_part_id++;
2851
2912
  *part_id= (uint32)loc_part_id;
2852
2913
  if (loc_part_id == max_partition &&
2853
2914
      part_func_value >= range_array[loc_part_id] &&
2921
2982
                                           bool include_endpoint)
2922
2983
{
2923
2984
  longlong *range_array= part_info->range_int_array;
 
2985
  longlong part_end_val;
2924
2986
  uint max_partition= part_info->no_parts - 1;
2925
2987
  uint min_part_id= 0, max_part_id= max_partition, loc_part_id;
2926
2988
  /* Get the partitioning function value for the endpoint */
2954
3016
    }
2955
3017
  }
2956
3018
 
2957
 
 
2958
3019
  if (unsigned_flag)
2959
3020
    part_func_value-= 0x8000000000000000ULL;
2960
3021
  if (left_endpoint && !include_endpoint)
2961
3022
    part_func_value++;
 
3023
 
 
3024
  /*
 
3025
    Search for the partition containing part_func_value
 
3026
    (including the right endpoint).
 
3027
  */
2962
3028
  while (max_part_id > min_part_id)
2963
3029
  {
2964
 
    loc_part_id= (max_part_id + min_part_id + 1) >> 1;
2965
 
    if (range_array[loc_part_id] <= part_func_value)
 
3030
    loc_part_id= (max_part_id + min_part_id) / 2;
 
3031
    if (range_array[loc_part_id] < part_func_value)
2966
3032
      min_part_id= loc_part_id + 1;
2967
3033
    else
2968
 
      max_part_id= loc_part_id - 1;
 
3034
      max_part_id= loc_part_id;
2969
3035
  }
2970
3036
  loc_part_id= max_part_id;
2971
 
  if (loc_part_id < max_partition && 
2972
 
      part_func_value >= range_array[loc_part_id+1])
2973
 
  {
2974
 
   loc_part_id++;
2975
 
  }
 
3037
 
 
3038
  /* Adjust for endpoints */
 
3039
  part_end_val= range_array[loc_part_id];
2976
3040
  if (left_endpoint)
2977
3041
  {
2978
 
    longlong bound= range_array[loc_part_id];
 
3042
    DBUG_ASSERT(part_func_value > part_end_val ?
 
3043
                (loc_part_id == max_partition &&
 
3044
                 !part_info->defined_max_value) :
 
3045
                1);
2979
3046
    /*
2980
3047
      In case of PARTITION p VALUES LESS THAN MAXVALUE
2981
 
      the maximum value is in the current partition.
 
3048
      the maximum value is in the current (last) partition.
 
3049
      If value is equal or greater than the endpoint,
 
3050
      the range starts from the next partition.
2982
3051
    */
2983
 
    if (part_func_value > bound ||
2984
 
        (part_func_value == bound &&
2985
 
         (!part_info->defined_max_value || loc_part_id < max_partition)))
 
3052
    if (part_func_value >= part_end_val &&
 
3053
        (loc_part_id < max_partition || !part_info->defined_max_value))
2986
3054
      loc_part_id++;
2987
3055
  }
2988
3056
  else 
2989
3057
  {
2990
 
    if (loc_part_id < max_partition)
2991
 
    {
2992
 
      if (part_func_value == range_array[loc_part_id])
2993
 
        loc_part_id += test(include_endpoint);
2994
 
      else if (part_func_value > range_array[loc_part_id])
2995
 
        loc_part_id++;
2996
 
    }
 
3058
    /* if 'WHERE <= X' and partition is LESS THAN (X) include next partition */
 
3059
    if (include_endpoint && loc_part_id < max_partition &&
 
3060
        part_func_value == part_end_val)
 
3061
      loc_part_id++;
 
3062
 
 
3063
    /* Right endpoint, set end after correct partition */
2997
3064
    loc_part_id++;
2998
3065
  }
2999
3066
  DBUG_RETURN(loc_part_id);
3832
3899
*/
3833
3900
 
3834
3901
bool mysql_unpack_partition(THD *thd,
3835
 
                            const char *part_buf, uint part_info_len,
 
3902
                            char *part_buf, uint part_info_len,
3836
3903
                            const char *part_state, uint part_state_len,
3837
3904
                            TABLE* table, bool is_create_table_ind,
3838
3905
                            handlerton *default_db_type,
3848
3915
  thd->lex= &lex;
3849
3916
  thd->variables.character_set_client= system_charset_info;
3850
3917
 
3851
 
  Parser_state parser_state(thd, part_buf, part_info_len);
 
3918
  Parser_state parser_state;
 
3919
  if (parser_state.init(thd, part_buf, part_info_len))
 
3920
    goto end;
3852
3921
 
3853
3922
  lex_start(thd);
3854
3923
  *work_part_info_used= false;
4076
4145
  }
4077
4146
 
4078
4147
  if ((!is_empty) && (!written_bin_log) &&
4079
 
      (!thd->lex->no_write_to_binlog))
4080
 
    write_bin_log(thd, FALSE, thd->query(), thd->query_length());
 
4148
      (!thd->lex->no_write_to_binlog) &&
 
4149
    write_bin_log(thd, FALSE, thd->query(), thd->query_length()))
 
4150
    DBUG_RETURN(TRUE);
4081
4151
 
4082
4152
  my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
4083
4153
              (ulong) (copied + deleted),
4235
4305
{
4236
4306
  DBUG_ENTER("prep_alter_part_table");
4237
4307
 
 
4308
  /* Foreign keys on partitioned tables are not supported, waits for WL#148 */
 
4309
  if (table->part_info && (alter_info->flags & ALTER_FOREIGN_KEY))
 
4310
  {
 
4311
    my_error(ER_FOREIGN_KEY_ON_PARTITIONED, MYF(0));
 
4312
    DBUG_RETURN(TRUE);
 
4313
  }
4238
4314
  /*
4239
4315
    We are going to manipulate the partition info on the table object
4240
4316
    so we need to ensure that the data structure of the table object
5668
5744
  part_info->first_log_entry= NULL;
5669
5745
  build_table_filename(path, sizeof(path) - 1, lpt->db,
5670
5746
                       lpt->table_name, "", 0);
5671
 
  build_table_filename(tmp_path, sizeof(tmp_path) - 1, lpt->db,
5672
 
                       lpt->table_name, "#", 0);
 
5747
  build_table_shadow_filename(tmp_path, sizeof(tmp_path) - 1, lpt);
5673
5748
  pthread_mutex_lock(&LOCK_gdl);
5674
5749
  if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path,
5675
5750
                                   FALSE))
5725
5800
 
5726
5801
  build_table_filename(path, sizeof(path) - 1, lpt->db,
5727
5802
                       lpt->table_name, "", 0);
5728
 
  build_table_filename(tmp_path, sizeof(tmp_path) - 1, lpt->db,
5729
 
                       lpt->table_name, "#", 0);
 
5803
  build_table_shadow_filename(tmp_path, sizeof(tmp_path) - 1, lpt);
5730
5804
  pthread_mutex_lock(&LOCK_gdl);
5731
5805
  if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path,
5732
5806
                                   FALSE))
5884
5958
  if (lpt->thd->locked_tables)
5885
5959
  {
5886
5960
    /*
 
5961
      Close the table if open, to remove/destroy the already altered
 
5962
      table->part_info object, so that it is not reused.
 
5963
    */
 
5964
    if (lpt->table->db_stat)
 
5965
      abort_and_upgrade_lock_and_close_table(lpt);
 
5966
    /*
5887
5967
      When we have the table locked, it is necessary to reopen the table
5888
5968
      since all table objects were closed and removed as part of the
5889
5969
      ALTER TABLE of partitioning structure.
5906
5986
  }
5907
5987
}
5908
5988
 
5909
 
/*
5910
 
  Unlock and close table before renaming and dropping partitions
5911
 
  SYNOPSIS
5912
 
    alter_close_tables()
5913
 
    lpt                        Struct carrying parameters
5914
 
  RETURN VALUES
5915
 
    0
5916
 
*/
5917
 
 
5918
 
static int alter_close_tables(ALTER_PARTITION_PARAM_TYPE *lpt)
5919
 
{
5920
 
  THD *thd= lpt->thd;
5921
 
  const char *db= lpt->db;
5922
 
  const char *table_name= lpt->table_name;
5923
 
  DBUG_ENTER("alter_close_tables");
5924
 
  /*
5925
 
    We need to also unlock tables and close all handlers.
5926
 
    We set lock to zero to ensure we don't do this twice
5927
 
    and we set db_stat to zero to ensure we don't close twice.
5928
 
  */
5929
 
  pthread_mutex_lock(&LOCK_open);
5930
 
  close_data_files_and_morph_locks(thd, db, table_name);
5931
 
  pthread_mutex_unlock(&LOCK_open);
5932
 
  DBUG_RETURN(0);
5933
 
}
5934
 
 
5935
5989
 
5936
5990
/*
5937
5991
  Handle errors for ALTER TABLE for partitioning
5951
6005
  partition_info *part_info= lpt->part_info;
5952
6006
  DBUG_ENTER("handle_alter_part_error");
5953
6007
 
5954
 
  if (!part_info->first_log_entry &&
 
6008
  if (part_info->first_log_entry &&
5955
6009
      execute_ddl_log_entry(current_thd,
5956
6010
                            part_info->first_log_entry->entry_pos))
5957
6011
  {
6229
6283
        write_log_drop_partition(lpt) ||
6230
6284
        ERROR_INJECT_CRASH("crash_drop_partition_3") ||
6231
6285
        (not_completed= FALSE) ||
6232
 
        abort_and_upgrade_lock(lpt) || /* Always returns 0 */
6233
 
        ERROR_INJECT_CRASH("crash_drop_partition_4") ||
6234
 
        alter_close_tables(lpt) ||
 
6286
        abort_and_upgrade_lock_and_close_table(lpt) ||
6235
6287
        ERROR_INJECT_CRASH("crash_drop_partition_5") ||
6236
6288
        ((!thd->lex->no_write_to_binlog) &&
6237
6289
         (write_bin_log(thd, FALSE,
6296
6348
        ERROR_INJECT_CRASH("crash_add_partition_2") ||
6297
6349
        mysql_change_partitions(lpt) ||
6298
6350
        ERROR_INJECT_CRASH("crash_add_partition_3") ||
6299
 
        abort_and_upgrade_lock(lpt) || /* Always returns 0 */
6300
 
        ERROR_INJECT_CRASH("crash_add_partition_4") ||
6301
 
        alter_close_tables(lpt) ||
 
6351
        abort_and_upgrade_lock_and_close_table(lpt) ||
6302
6352
        ERROR_INJECT_CRASH("crash_add_partition_5") ||
6303
6353
        ((!thd->lex->no_write_to_binlog) &&
6304
6354
         (write_bin_log(thd, FALSE,
6386
6436
        write_log_final_change_partition(lpt) ||
6387
6437
        ERROR_INJECT_CRASH("crash_change_partition_4") ||
6388
6438
        (not_completed= FALSE) ||
6389
 
        abort_and_upgrade_lock(lpt) || /* Always returns 0 */
6390
 
        ERROR_INJECT_CRASH("crash_change_partition_5") ||
6391
 
        alter_close_tables(lpt) ||
 
6439
        abort_and_upgrade_lock_and_close_table(lpt) ||
6392
6440
        ERROR_INJECT_CRASH("crash_change_partition_6") ||
6393
6441
        ((!thd->lex->no_write_to_binlog) &&
6394
6442
         (write_bin_log(thd, FALSE,
6417
6465
                                 table, table_list, FALSE, NULL,
6418
6466
                                 written_bin_log));
6419
6467
err:
6420
 
  close_thread_tables(thd);
 
6468
  if (thd->locked_tables)
 
6469
  {
 
6470
    /*
 
6471
      table->part_info was altered in prep_alter_part_table and must be
 
6472
      destroyed and recreated, since otherwise it will be reused, since
 
6473
      we are under LOCK TABLE.
 
6474
    */
 
6475
    alter_partition_lock_handling(lpt);
 
6476
  }
 
6477
  else
 
6478
  {
 
6479
    /* Force the table to be closed to avoid reuse of the table->part_info */
 
6480
    close_thread_tables(thd);
 
6481
  }
6421
6482
  DBUG_RETURN(TRUE);
6422
6483
}
6423
6484
#endif
6510
6571
 
6511
6572
void mem_alloc_error(size_t size)
6512
6573
{
6513
 
  my_error(ER_OUTOFMEMORY, MYF(0), size);
 
6574
  my_error(ER_OUTOFMEMORY, MYF(0), static_cast<int>(size));
6514
6575
}
6515
6576
 
6516
6577
#ifdef WITH_PARTITION_STORAGE_ENGINE
6728
6789
{
6729
6790
  DBUG_ASSERT(!is_subpart);
6730
6791
  Field *field= part_info->part_field_array[0];
6731
 
  uint32             max_endpoint_val;
6732
 
  get_endpoint_func  get_endpoint;
 
6792
  uint32             UNINIT_VAR(max_endpoint_val);
 
6793
  get_endpoint_func  UNINIT_VAR(get_endpoint);
6733
6794
  bool               can_match_multiple_values;  /* is not '=' */
6734
6795
  uint field_len= field->pack_length_in_rec();
6735
6796
  part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE;
6767
6828
    }
6768
6829
  }
6769
6830
  else
6770
 
    assert(0);
6771
 
  
 
6831
    MY_ASSERT_UNREACHABLE();
 
6832
 
6772
6833
  can_match_multiple_values= (flags || !min_value || !max_value ||
6773
6834
                              memcmp(min_value, max_value, field_len));
6774
6835
  if (can_match_multiple_values &&