~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sys_var.cc

Merge in Monty for set_var

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
  @todo
37
37
    Add full support for the variable character_set (for 4.1)
38
38
 
39
 
  @note
40
 
    Be careful with var->save_result: sys_var::check() only updates
41
 
    uint64_t_value; so other members of the union are garbage then; to use
42
 
    them you must first assign a value to them (in specific ::check() for
43
 
    example).
44
39
*/
45
40
 
46
41
#include "config.h"
110
105
static void fix_max_join_size(Session *session, sql_var_t type);
111
106
static void fix_session_mem_root(Session *session, sql_var_t type);
112
107
static void fix_server_id(Session *session, sql_var_t type);
113
 
static bool get_unsigned32(Session *session, set_var *var);
114
 
static bool get_unsigned64(Session *session, set_var *var);
115
108
bool throw_bounds_warning(Session *session, bool fixed, bool unsignd,
116
109
                          const std::string &name, int64_t val);
117
110
static unsigned char *get_error_count(Session *session);
329
322
      my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), getName().c_str(), var->value->str_value.ptr());
330
323
    return res;
331
324
  }
332
 
  var->save_result.uint64_t_value= var->value->val_int();
 
325
  var->updateValue();
333
326
  return 0;
334
327
}
335
328
 
474
467
  return out;
475
468
}
476
469
 
477
 
static bool get_unsigned32(Session *session, set_var *var)
478
 
{
479
 
  if (var->value->unsigned_flag)
480
 
    var->save_result.uint32_t_value= 
481
 
      static_cast<uint32_t>(var->value->val_int());
482
 
  else
483
 
  {
484
 
    int64_t v= var->value->val_int();
485
 
    if (v > UINT32_MAX)
486
 
      throw_bounds_warning(session, true, true,var->var->getName().c_str(), v);
487
 
    
488
 
    var->save_result.uint32_t_value= 
489
 
      static_cast<uint32_t>((v > UINT32_MAX) ? UINT32_MAX : (v < 0) ? 0 : v);
490
 
  }
491
 
  return false;
492
 
}
493
 
 
494
 
static bool get_unsigned64(Session *, set_var *var)
495
 
{
496
 
  if (var->value->unsigned_flag)
497
 
      var->save_result.uint64_t_value=(uint64_t) var->value->val_int();
498
 
  else
499
 
  {
500
 
    int64_t v= var->value->val_int();
501
 
      var->save_result.uint64_t_value= (uint64_t) ((v < 0) ? 0 : v);
502
 
  }
503
 
  return 0;
504
 
}
505
 
 
506
 
static bool get_size_t(Session *, set_var *var)
507
 
{
508
 
  if (var->value->unsigned_flag)
509
 
    var->save_result.size_t_value= (size_t) var->value->val_int();
510
 
  else
511
 
  {
512
 
    ssize_t v= (ssize_t)var->value->val_int();
513
 
    var->save_result.size_t_value= (size_t) ((v < 0) ? 0 : v);
514
 
  }
515
 
  return 0;
516
 
}
517
 
 
518
470
bool sys_var_uint32_t_ptr::check(Session *, set_var *var)
519
471
{
520
 
  var->save_result.uint32_t_value= (uint32_t)var->value->val_int();
 
472
  var->updateValue();
521
473
  return 0;
522
474
}
523
475
 
524
476
bool sys_var_uint32_t_ptr::update(Session *session, set_var *var)
525
477
{
526
 
  uint32_t tmp= var->save_result.uint32_t_value;
 
478
  uint64_t tmp= var->getInteger();
527
479
  LOCK_global_system_variables.lock();
528
480
  if (option_limits)
529
481
  {
530
482
    uint32_t newvalue= (uint32_t) fix_unsigned(session, tmp, option_limits);
531
 
    if(newvalue==tmp)
 
483
    if(static_cast<uint64_t>(newvalue) == tmp)
532
484
      *value= newvalue;
533
485
  }
534
486
  else
535
 
    *value= (uint32_t) tmp;
 
487
    *value= static_cast<uint32_t>(tmp);
536
488
  LOCK_global_system_variables.unlock();
537
489
  return 0;
538
490
}
550
502
 
551
503
bool sys_var_uint64_t_ptr::update(Session *session, set_var *var)
552
504
{
553
 
  uint64_t tmp= var->save_result.uint64_t_value;
 
505
  uint64_t tmp= var->getInteger();
554
506
  LOCK_global_system_variables.lock();
555
507
  if (option_limits)
556
508
  {
557
 
    uint64_t newvalue= (uint64_t) fix_unsigned(session, tmp, option_limits);
 
509
    uint64_t newvalue= fix_unsigned(session, tmp, option_limits);
558
510
    if(newvalue==tmp)
559
511
      *value= newvalue;
560
512
  }
561
513
  else
562
 
    *value= (uint64_t) tmp;
 
514
    *value= tmp;
563
515
  LOCK_global_system_variables.unlock();
564
516
  return 0;
565
517
}
584
536
 
585
537
bool sys_var_size_t_ptr::update(Session *session, set_var *var)
586
538
{
587
 
  size_t tmp= var->save_result.size_t_value;
 
539
  size_t tmp= size_t(var->getInteger());
588
540
  LOCK_global_system_variables.lock();
589
541
  if (option_limits)
590
542
    *value= fix_size_t(session, tmp, option_limits);
606
558
 
607
559
bool sys_var_bool_ptr::update(Session *, set_var *var)
608
560
{
609
 
  *value= (bool) var->save_result.uint32_t_value;
 
561
  *value= bool(var->getInteger());
610
562
  return 0;
611
563
}
612
564
 
622
574
*/
623
575
bool sys_var_session_uint32_t::check(Session *session, set_var *var)
624
576
{
625
 
  return (get_unsigned32(session, var) ||
626
 
          (check_func && (*check_func)(session, var)));
 
577
  var->updateValue();
 
578
  return (check_func && (*check_func)(session, var));
627
579
}
628
580
 
629
581
bool sys_var_session_uint32_t::update(Session *session, set_var *var)
630
582
{
631
 
  uint64_t tmp= (uint64_t) var->save_result.uint32_t_value;
 
583
  uint64_t tmp= var->getInteger();
632
584
 
633
585
  /* Don't use bigger value than given with --maximum-variable-name=.. */
634
586
  if ((uint32_t) tmp > max_system_variables.*offset)
642
594
  else if (tmp > UINT32_MAX)
643
595
  {
644
596
    tmp= UINT32_MAX;
645
 
    throw_bounds_warning(session, true, true, getName(), (int64_t) var->save_result.uint64_t_value);
 
597
    throw_bounds_warning(session, true, true, getName(), int64_t(var->getInteger()));
646
598
  }
647
599
 
648
600
  if (var->type == OPT_GLOBAL)
681
633
 
682
634
bool sys_var_session_ha_rows::update(Session *session, set_var *var)
683
635
{
684
 
  uint64_t tmp= var->save_result.uint64_t_value;
 
636
  uint64_t tmp= var->getInteger();
685
637
 
686
638
  /* Don't use bigger value than given with --maximum-variable-name=.. */
687
639
  if ((ha_rows) tmp > max_system_variables.*offset)
730
682
 
731
683
bool sys_var_session_uint64_t::check(Session *session, set_var *var)
732
684
{
733
 
  return (get_unsigned64(session, var) ||
734
 
          (check_func && (*check_func)(session, var)));
 
685
  var->updateValue();
 
686
  return (check_func && (*check_func)(session, var));
735
687
}
736
688
 
737
689
bool sys_var_session_uint64_t::update(Session *session,  set_var *var)
738
690
{
739
 
  uint64_t tmp= var->save_result.uint64_t_value;
 
691
  uint64_t tmp= var->getInteger();
740
692
 
741
693
  if (tmp > max_system_variables.*offset)
742
694
  {
786
738
 
787
739
bool sys_var_session_size_t::check(Session *session, set_var *var)
788
740
{
789
 
  return (get_size_t(session, var) ||
790
 
          (check_func && (*check_func)(session, var)));
 
741
  var->updateValue();
 
742
  return (check_func && (*check_func)(session, var));
791
743
}
792
744
 
793
745
bool sys_var_session_size_t::update(Session *session,  set_var *var)
794
746
{
795
 
  size_t tmp= var->save_result.size_t_value;
 
747
  size_t tmp= size_t(var->getInteger());
796
748
 
797
749
  if (tmp > max_system_variables.*offset)
798
750
    tmp= max_system_variables.*offset;
841
793
bool sys_var_session_bool::update(Session *session,  set_var *var)
842
794
{
843
795
  if (var->type == OPT_GLOBAL)
844
 
    global_system_variables.*offset= (bool) var->save_result.uint32_t_value;
 
796
    global_system_variables.*offset= bool(var->getInteger());
845
797
  else
846
 
    session->variables.*offset= (bool) var->save_result.uint32_t_value;
 
798
    session->variables.*offset= bool(var->getInteger());
847
799
  return 0;
848
800
}
849
801
 
876
828
 
877
829
  if (var->value->result_type() == STRING_RESULT)
878
830
  {
879
 
    if (!(res=var->value->val_str(&str)) ||
880
 
        (var->save_result.uint32_t_value= find_type(enum_names, res->ptr(),
881
 
                                                    res->length(),1)) == 0)
 
831
    res= var->value->val_str(&str);
 
832
    if (res == NULL)
882
833
    {
883
 
      value= res ? res->c_ptr() : "NULL";
 
834
      value= "NULL";
884
835
      goto err;
885
836
    }
886
837
 
887
 
    var->save_result.uint32_t_value--;
 
838
    uint64_t tmp_val= find_type(enum_names, res->ptr(), res->length(),1);
 
839
    if (tmp_val == 0)
 
840
    {
 
841
      value= res->c_ptr();
 
842
      goto err;
 
843
    }
 
844
    var->setValue(tmp_val-1);
888
845
  }
889
846
  else
890
847
  {
891
 
    uint64_t tmp=var->value->val_int();
 
848
    uint64_t tmp= var->value->val_int();
892
849
    if (tmp >= enum_names->count)
893
850
    {
894
851
      internal::llstr(tmp,buff);
895
852
      value=buff;                               // Wrong value is here
896
853
      goto err;
897
854
    }
898
 
    var->save_result.uint32_t_value= (uint32_t) tmp;    // Save for update
 
855
    var->setValue(tmp); // Save for update
899
856
  }
900
857
  return 0;
901
858
 
1022
979
bool sys_var_session_enum::update(Session *session, set_var *var)
1023
980
{
1024
981
  if (var->type == OPT_GLOBAL)
1025
 
    global_system_variables.*offset= var->save_result.uint32_t_value;
 
982
    global_system_variables.*offset= var->getInteger();
1026
983
  else
1027
 
    session->variables.*offset= var->save_result.uint32_t_value;
 
984
    session->variables.*offset= var->getInteger();
1028
985
  return 0;
1029
986
}
1030
987
 
1074
1031
}
1075
1032
 
1076
1033
 
1077
 
typedef struct old_names_map_st
1078
 
{
1079
 
  const char *old_name;
1080
 
  const char *new_name;
1081
 
} my_old_conv;
1082
 
 
1083
 
bool sys_var_collation::check(Session *, set_var *var)
 
1034
bool sys_var_collation_sv::update(Session *session, set_var *var)
1084
1035
{
1085
1036
  const CHARSET_INFO *tmp;
1086
1037
 
1090
1041
    String str(buff,sizeof(buff), system_charset_info), *res;
1091
1042
    if (!(res=var->value->val_str(&str)))
1092
1043
    {
1093
 
      my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.c_str(), "NULL");
 
1044
      boost::throw_exception(invalid_option_value(var->var->getName()) << invalid_value(std::string("NULL")));
1094
1045
      return 1;
1095
1046
    }
1096
1047
    if (!(tmp=get_charset_by_name(res->c_ptr())))
1097
1048
    {
1098
1049
      my_error(ER_UNKNOWN_COLLATION, MYF(0), res->c_ptr());
 
1050
      boost::throw_exception(invalid_option_value(var->var->getName()) << invalid_value(std::string(res->c_ptr())));
1099
1051
      return 1;
1100
1052
    }
1101
1053
  }
1106
1058
      char buf[20];
1107
1059
      internal::int10_to_str((int) var->value->val_int(), buf, -10);
1108
1060
      my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
 
1061
      boost::throw_exception(invalid_option_value(var->var->getName()) << invalid_value(boost::lexical_cast<std::string>(var->value->val_int())));
1109
1062
      return 1;
1110
1063
    }
1111
1064
  }
1112
 
  var->save_result.charset= tmp;        // Save for update
1113
 
  return 0;
1114
 
}
1115
 
 
1116
 
 
1117
 
bool sys_var_collation_sv::update(Session *session, set_var *var)
1118
 
{
1119
1065
  if (var->type == OPT_GLOBAL)
1120
 
    global_system_variables.*offset= var->save_result.charset;
 
1066
    global_system_variables.*offset= tmp;
1121
1067
  else
1122
1068
  {
1123
 
    session->variables.*offset= var->save_result.charset;
 
1069
    session->variables.*offset= tmp;
1124
1070
  }
1125
1071
  return 0;
1126
1072
}
1151
1097
 
1152
1098
bool sys_var_timestamp::update(Session *session,  set_var *var)
1153
1099
{
1154
 
  session->set_time((time_t) var->save_result.uint64_t_value);
 
1100
  session->set_time(time_t(var->getInteger()));
1155
1101
  return 0;
1156
1102
}
1157
1103
 
1172
1118
 
1173
1119
bool sys_var_last_insert_id::update(Session *session, set_var *var)
1174
1120
{
1175
 
  session->first_successful_insert_id_in_prev_stmt=
1176
 
    var->save_result.uint64_t_value;
 
1121
  session->first_successful_insert_id_in_prev_stmt= var->getInteger();
1177
1122
  return 0;
1178
1123
}
1179
1124
 
1192
1137
}
1193
1138
 
1194
1139
 
1195
 
bool sys_var_session_time_zone::check(Session *session, set_var *var)
 
1140
bool sys_var_session_time_zone::update(Session *session, set_var *var)
1196
1141
{
1197
1142
  char buff[MAX_TIME_ZONE_NAME_LENGTH];
1198
1143
  String str(buff, sizeof(buff), &my_charset_utf8_general_ci);
1199
1144
  String *res= var->value->val_str(&str);
1200
1145
 
1201
 
  if (!(var->save_result.time_zone= my_tz_find(session, res)))
 
1146
  Time_zone *tmp= my_tz_find(session, res);
 
1147
  if (tmp == NULL)
1202
1148
  {
1203
 
    my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), res ? res->c_ptr() : "NULL");
 
1149
    boost::throw_exception(invalid_option_value(var->var->getName()) << invalid_value(std::string(res ? res->c_ptr() : "NULL")));
1204
1150
    return 1;
1205
1151
  }
1206
 
  return 0;
1207
 
}
1208
 
 
1209
 
 
1210
 
bool sys_var_session_time_zone::update(Session *session, set_var *var)
1211
 
{
1212
1152
  /* We are using Time_zone object found during check() phase. */
1213
1153
  if (var->type == OPT_GLOBAL)
1214
1154
  {
1215
1155
    LOCK_global_system_variables.lock();
1216
 
    global_system_variables.time_zone= var->save_result.time_zone;
 
1156
    global_system_variables.time_zone= tmp;
1217
1157
    LOCK_global_system_variables.unlock();
1218
1158
  }
1219
1159
  else
1220
 
    session->variables.time_zone= var->save_result.time_zone;
 
1160
    session->variables.time_zone= tmp;
1221
1161
  return 0;
1222
1162
}
1223
1163
 
1270
1210
}
1271
1211
 
1272
1212
 
1273
 
bool sys_var_session_lc_time_names::check(Session *, set_var *var)
 
1213
 
 
1214
bool sys_var_session_lc_time_names::update(Session *session, set_var *var)
1274
1215
{
1275
1216
  MY_LOCALE *locale_match;
1276
1217
 
1302
1243
    }
1303
1244
  }
1304
1245
 
1305
 
  var->save_result.locale_value= locale_match;
1306
 
  return 0;
1307
 
}
1308
 
 
1309
 
 
1310
 
bool sys_var_session_lc_time_names::update(Session *session, set_var *var)
1311
 
{
1312
1246
  if (var->type == OPT_GLOBAL)
1313
 
    global_system_variables.lc_time_names= var->save_result.locale_value;
 
1247
    global_system_variables.lc_time_names= locale_match;
1314
1248
  else
1315
 
    session->variables.lc_time_names= var->save_result.locale_value;
 
1249
    session->variables.lc_time_names= locale_match;
1316
1250
  return 0;
1317
1251
}
1318
1252
 
1385
1319
static bool set_option_bit(Session *session, set_var *var)
1386
1320
{
1387
1321
  sys_var_session_bit *sys_var= ((sys_var_session_bit*) var->var);
1388
 
  if ((var->save_result.uint32_t_value != 0) == sys_var->reverse)
 
1322
  if ((var->getInteger() != 0) == sys_var->reverse)
1389
1323
    session->options&= ~sys_var->bit_flag;
1390
1324
  else
1391
1325
    session->options|= sys_var->bit_flag;
1399
1333
 
1400
1334
  uint64_t org_options= session->options;
1401
1335
 
1402
 
  if (var->save_result.uint32_t_value != 0)
 
1336
  if (var->getInteger() != 0)
1403
1337
    session->options&= ~((sys_var_session_bit*) var->var)->bit_flag;
1404
1338
  else
1405
1339
    session->options|= ((sys_var_session_bit*) var->var)->bit_flag;
1425
1359
 
1426
1360
static int check_pseudo_thread_id(Session *, set_var *var)
1427
1361
{
1428
 
  var->save_result.uint64_t_value= var->value->val_int();
 
1362
  var->updateValue();
1429
1363
  return 0;
1430
1364
}
1431
1365
 
1711
1645
 Functions to handle table_type
1712
1646
****************************************************************************/
1713
1647
 
1714
 
/* Based upon sys_var::check_enum() */
1715
 
 
1716
 
bool sys_var_session_storage_engine::check(Session *session, set_var *var)
1717
 
{
1718
 
  char buff[STRING_BUFFER_USUAL_SIZE];
1719
 
  const char *value;
1720
 
  String str(buff, sizeof(buff), &my_charset_utf8_general_ci), *res;
1721
 
 
1722
 
  var->save_result.storage_engine= NULL;
1723
 
  if (var->value->result_type() == STRING_RESULT)
1724
 
  {
1725
 
    res= var->value->val_str(&str);
1726
 
    if (res == NULL || res->ptr() == NULL)
1727
 
    {
1728
 
      value= "NULL";
1729
 
      goto err;
1730
 
    }
1731
 
    else
1732
 
    {
1733
 
      const std::string engine_name(res->ptr());
1734
 
      plugin::StorageEngine *engine;
1735
 
      var->save_result.storage_engine= plugin::StorageEngine::findByName(*session, engine_name);
1736
 
      if (var->save_result.storage_engine == NULL)
1737
 
      {
1738
 
        value= res->c_ptr();
1739
 
        goto err;
1740
 
      }
1741
 
      engine= var->save_result.storage_engine;
1742
 
    }
1743
 
    return 0;
1744
 
  }
1745
 
  value= "unknown";
1746
 
 
1747
 
err:
1748
 
  my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), value);
1749
 
  return 1;
1750
 
}
1751
 
 
1752
 
 
1753
1648
unsigned char *sys_var_session_storage_engine::value_ptr(Session *session,
1754
1649
                                                         sql_var_t type,
1755
1650
                                                         const LEX_STRING *)
1787
1682
 
1788
1683
bool sys_var_session_storage_engine::update(Session *session, set_var *var)
1789
1684
{
1790
 
  plugin::StorageEngine **value= &(global_system_variables.*offset), *old_value;
 
1685
  char buff[STRING_BUFFER_USUAL_SIZE];
 
1686
  const char *name_value;
 
1687
  String str(buff, sizeof(buff), &my_charset_utf8_general_ci), *res;
 
1688
 
 
1689
  plugin::StorageEngine *tmp= NULL;
 
1690
  plugin::StorageEngine **value= NULL;
 
1691
    
 
1692
  if (var->value->result_type() == STRING_RESULT)
 
1693
  {
 
1694
    res= var->value->val_str(&str);
 
1695
    if (res == NULL || res->ptr() == NULL)
 
1696
    {
 
1697
      name_value= "NULL";
 
1698
      goto err;
 
1699
    }
 
1700
    else
 
1701
    {
 
1702
      const std::string engine_name(res->ptr());
 
1703
      tmp= plugin::StorageEngine::findByName(*session, engine_name);
 
1704
      if (tmp == NULL)
 
1705
      {
 
1706
        name_value= res->c_ptr();
 
1707
        goto err;
 
1708
      }
 
1709
    }
 
1710
  }
 
1711
  else
 
1712
  {
 
1713
    name_value= "unknown";
 
1714
  }
 
1715
 
 
1716
  value= &(global_system_variables.*offset);
1791
1717
   if (var->type != OPT_GLOBAL)
1792
1718
     value= &(session->variables.*offset);
1793
 
  old_value= *value;
1794
 
  if (old_value != var->save_result.storage_engine)
 
1719
  if (*value != tmp)
1795
1720
  {
1796
 
    *value= var->save_result.storage_engine;
 
1721
    *value= tmp;
1797
1722
  }
1798
1723
  return 0;
 
1724
err:
 
1725
  my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name_value);
 
1726
  return 1;
1799
1727
}
1800
1728
 
1801
1729
} /* namespace drizzled */