~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item.cc

move functions from item.cc/item.h to item directory

Show diffs side-by-side

added added

removed removed

Lines of Context:
562
562
}
563
563
 
564
564
 
565
 
Item *Item_static_float_func::safe_charset_converter(const CHARSET_INFO * const)
566
 
{
567
 
  Item_string *conv;
568
 
  char buf[64];
569
 
  String *s, tmp(buf, sizeof(buf), &my_charset_bin);
570
 
  s= val_str(&tmp);
571
 
  if ((conv= new Item_static_string_func(func_name, s->ptr(), s->length(),
572
 
                                         s->charset())))
573
 
  {
574
 
    conv->str_value.copy();
575
 
    conv->str_value.mark_as_const();
576
 
  }
577
 
  return conv;
578
 
}
579
 
 
580
 
 
581
 
Item *Item_string::safe_charset_converter(const CHARSET_INFO * const tocs)
582
 
{
583
 
  Item_string *conv;
584
 
  uint32_t conv_errors;
585
 
  char *ptr;
586
 
  String tmp, cstr, *ostr= val_str(&tmp);
587
 
  cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors);
588
 
  if (conv_errors || !(conv= new Item_string(cstr.ptr(), cstr.length(),
589
 
                                             cstr.charset(),
590
 
                                             collation.derivation)))
591
 
  {
592
 
    /*
593
 
      Safe conversion is not possible (or EOM).
594
 
      We could not convert a string into the requested character set
595
 
      without data loss. The target charset does not cover all the
596
 
      characters from the string. Operation cannot be done correctly.
597
 
    */
598
 
    return NULL;
599
 
  }
600
 
  if (!(ptr= current_session->strmake(cstr.ptr(), cstr.length())))
601
 
    return NULL;
602
 
  conv->str_value.set(ptr, cstr.length(), cstr.charset());
603
 
  /* Ensure that no one is going to change the result string */
604
 
  conv->str_value.mark_as_const();
605
 
  return conv;
606
 
}
607
 
 
608
 
 
609
 
Item *Item_static_string_func::safe_charset_converter(const CHARSET_INFO * const tocs)
610
 
{
611
 
  Item_string *conv;
612
 
  uint32_t conv_errors;
613
 
  String tmp, cstr, *ostr= val_str(&tmp);
614
 
  cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors);
615
 
  if (conv_errors ||
616
 
      !(conv= new Item_static_string_func(func_name,
617
 
                                          cstr.ptr(), cstr.length(),
618
 
                                          cstr.charset(),
619
 
                                          collation.derivation)))
620
 
  {
621
 
    /*
622
 
      Safe conversion is not possible (or EOM).
623
 
      We could not convert a string into the requested character set
624
 
      without data loss. The target charset does not cover all the
625
 
      characters from the string. Operation cannot be done correctly.
626
 
    */
627
 
    return NULL;
628
 
  }
629
 
  conv->str_value.copy();
630
 
  /* Ensure that no one is going to change the result string */
631
 
  conv->str_value.mark_as_const();
632
 
  return conv;
633
 
}
634
 
 
635
 
 
636
 
bool Item_string::eq(const Item *item, bool binary_cmp) const
637
 
{
638
 
  if (type() == item->type() && item->basic_const_item())
639
 
  {
640
 
    if (binary_cmp)
641
 
      return !stringcmp(&str_value, &item->str_value);
642
 
    return (collation.collation == item->collation.collation &&
643
 
            !sortcmp(&str_value, &item->str_value, collation.collation));
644
 
  }
645
 
  return 0;
646
 
}
647
 
 
648
 
 
649
565
/**
650
566
  Get the value of the function as a DRIZZLE_TIME structure.
651
567
  As a extra convenience the time structure is reset on error!
1049
965
  }
1050
966
}
1051
967
 
1052
 
 
1053
 
/**
1054
 
  Create an item from a string we KNOW points to a valid int64_t
1055
 
  end \\0 terminated number string.
1056
 
  This is always 'signed'. Unsigned values are created with Item_uint()
1057
 
*/
1058
 
 
1059
 
Item_int::Item_int(const char *str_arg, uint32_t length)
1060
 
{
1061
 
  char *end_ptr= (char*) str_arg + length;
1062
 
  int error;
1063
 
  value= my_strtoll10(str_arg, &end_ptr, &error);
1064
 
  max_length= (uint) (end_ptr - str_arg);
1065
 
  name= (char*) str_arg;
1066
 
  fixed= 1;
1067
 
}
1068
 
 
1069
 
 
1070
 
my_decimal *Item_int::val_decimal(my_decimal *decimal_value)
1071
 
{
1072
 
  int2my_decimal(E_DEC_FATAL_ERROR, value, unsigned_flag, decimal_value);
1073
 
  return decimal_value;
1074
 
}
1075
 
 
1076
 
String *Item_int::val_str(String *str)
1077
 
{
1078
 
  // following assert is redundant, because fixed=1 assigned in constructor
1079
 
  assert(fixed == 1);
1080
 
  str->set(value, &my_charset_bin);
1081
 
  return str;
1082
 
}
1083
 
 
1084
 
void Item_int::print(String *str, enum_query_type)
1085
 
{
1086
 
  // my_charset_bin is good enough for numbers
1087
 
  str_value.set(value, &my_charset_bin);
1088
 
  str->append(str_value);
1089
 
}
1090
 
 
1091
 
 
1092
 
Item_uint::Item_uint(const char *str_arg, uint32_t length):
1093
 
  Item_int(str_arg, length)
1094
 
{
1095
 
  unsigned_flag= 1;
1096
 
}
1097
 
 
1098
 
 
1099
 
Item_uint::Item_uint(const char *str_arg, int64_t i, uint32_t length):
1100
 
  Item_int(str_arg, i, length)
1101
 
{
1102
 
  unsigned_flag= 1;
1103
 
}
1104
 
 
1105
 
 
1106
 
String *Item_uint::val_str(String *str)
1107
 
{
1108
 
  // following assert is redundant, because fixed=1 assigned in constructor
1109
 
  assert(fixed == 1);
1110
 
  str->set((uint64_t) value, &my_charset_bin);
1111
 
  return str;
1112
 
}
1113
 
 
1114
 
 
1115
 
void Item_uint::print(String *str, enum_query_type)
1116
 
{
1117
 
  // latin1 is good enough for numbers
1118
 
  str_value.set((uint64_t) value, default_charset());
1119
 
  str->append(str_value);
1120
 
}
1121
 
 
1122
 
 
1123
 
Item_decimal::Item_decimal(const char *str_arg, uint32_t length,
1124
 
                           const CHARSET_INFO * const charset)
1125
 
{
1126
 
  str2my_decimal(E_DEC_FATAL_ERROR, str_arg, length, charset, &decimal_value);
1127
 
  name= (char*) str_arg;
1128
 
  decimals= (uint8_t) decimal_value.frac;
1129
 
  fixed= 1;
1130
 
  max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
1131
 
                                             decimals, unsigned_flag);
1132
 
}
1133
 
 
1134
 
Item_decimal::Item_decimal(int64_t val, bool unsig)
1135
 
{
1136
 
  int2my_decimal(E_DEC_FATAL_ERROR, val, unsig, &decimal_value);
1137
 
  decimals= (uint8_t) decimal_value.frac;
1138
 
  fixed= 1;
1139
 
  max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
1140
 
                                             decimals, unsigned_flag);
1141
 
}
1142
 
 
1143
 
 
1144
 
Item_decimal::Item_decimal(double val, int, int)
1145
 
{
1146
 
  double2my_decimal(E_DEC_FATAL_ERROR, val, &decimal_value);
1147
 
  decimals= (uint8_t) decimal_value.frac;
1148
 
  fixed= 1;
1149
 
  max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
1150
 
                                             decimals, unsigned_flag);
1151
 
}
1152
 
 
1153
 
 
1154
 
Item_decimal::Item_decimal(const char *str, const my_decimal *val_arg,
1155
 
                           uint32_t decimal_par, uint32_t length)
1156
 
{
1157
 
  my_decimal2decimal(val_arg, &decimal_value);
1158
 
  name= (char*) str;
1159
 
  decimals= (uint8_t) decimal_par;
1160
 
  max_length= length;
1161
 
  fixed= 1;
1162
 
}
1163
 
 
1164
 
 
1165
 
Item_decimal::Item_decimal(my_decimal *value_par)
1166
 
{
1167
 
  my_decimal2decimal(value_par, &decimal_value);
1168
 
  decimals= (uint8_t) decimal_value.frac;
1169
 
  fixed= 1;
1170
 
  max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
1171
 
                                             decimals, unsigned_flag);
1172
 
}
1173
 
 
1174
 
 
1175
 
Item_decimal::Item_decimal(const unsigned char *bin, int precision, int scale)
1176
 
{
1177
 
  binary2my_decimal(E_DEC_FATAL_ERROR, bin,
1178
 
                    &decimal_value, precision, scale);
1179
 
  decimals= (uint8_t) decimal_value.frac;
1180
 
  fixed= 1;
1181
 
  max_length= my_decimal_precision_to_length(precision, decimals,
1182
 
                                             unsigned_flag);
1183
 
}
1184
 
 
1185
 
 
1186
 
int64_t Item_decimal::val_int()
1187
 
{
1188
 
  int64_t result;
1189
 
  my_decimal2int(E_DEC_FATAL_ERROR, &decimal_value, unsigned_flag, &result);
1190
 
  return result;
1191
 
}
1192
 
 
1193
 
double Item_decimal::val_real()
1194
 
{
1195
 
  double result;
1196
 
  my_decimal2double(E_DEC_FATAL_ERROR, &decimal_value, &result);
1197
 
  return result;
1198
 
}
1199
 
 
1200
 
String *Item_decimal::val_str(String *result)
1201
 
{
1202
 
  result->set_charset(&my_charset_bin);
1203
 
  my_decimal2string(E_DEC_FATAL_ERROR, &decimal_value, 0, 0, 0, result);
1204
 
  return result;
1205
 
}
1206
 
 
1207
 
void Item_decimal::print(String *str, enum_query_type)
1208
 
{
1209
 
  my_decimal2string(E_DEC_FATAL_ERROR, &decimal_value, 0, 0, 0, &str_value);
1210
 
  str->append(str_value);
1211
 
}
1212
 
 
1213
 
 
1214
 
bool Item_decimal::eq(const Item *item, bool) const
1215
 
{
1216
 
  if (type() == item->type() && item->basic_const_item())
1217
 
  {
1218
 
    /*
1219
 
      We need to cast off const to call val_decimal(). This should
1220
 
      be OK for a basic constant. Additionally, we can pass 0 as
1221
 
      a true decimal constant will return its internal decimal
1222
 
      storage and ignore the argument.
1223
 
    */
1224
 
    Item *arg= (Item*) item;
1225
 
    my_decimal *value= arg->val_decimal(0);
1226
 
    return !my_decimal_cmp(&decimal_value, value);
1227
 
  }
1228
 
  return 0;
1229
 
}
1230
 
 
1231
 
 
1232
 
void Item_decimal::set_decimal_value(my_decimal *value_par)
1233
 
{
1234
 
  my_decimal2decimal(value_par, &decimal_value);
1235
 
  decimals= (uint8_t) decimal_value.frac;
1236
 
  unsigned_flag= !decimal_value.sign();
1237
 
  max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
1238
 
                                             decimals, unsigned_flag);
1239
 
}
1240
 
 
1241
 
 
1242
 
String *Item_float::val_str(String *str)
1243
 
{
1244
 
  // following assert is redundant, because fixed=1 assigned in constructor
1245
 
  assert(fixed == 1);
1246
 
  str->set_real(value,decimals,&my_charset_bin);
1247
 
  return str;
1248
 
}
1249
 
 
1250
 
 
1251
 
int64_t Item_float::val_int()
1252
 
{
1253
 
  assert(fixed == 1);
1254
 
  if (value <= (double) INT64_MIN)
1255
 
  {
1256
 
     return INT64_MIN;
1257
 
  }
1258
 
  else if (value >= (double) (uint64_t) INT64_MAX)
1259
 
  {
1260
 
    return INT64_MAX;
1261
 
  }
1262
 
  return (int64_t) rint(value);
1263
 
}
1264
 
 
1265
 
my_decimal *Item_float::val_decimal(my_decimal *decimal_value)
1266
 
{
1267
 
  // following assert is redundant, because fixed=1 assigned in constructor
1268
 
  assert(fixed == 1);
1269
 
  double2my_decimal(E_DEC_FATAL_ERROR, value, decimal_value);
1270
 
  return (decimal_value);
1271
 
}
1272
 
 
1273
 
 
1274
 
void Item_string::print(String *str, enum_query_type query_type)
1275
 
{
1276
 
  if (query_type == QT_ORDINARY && is_cs_specified())
1277
 
  {
1278
 
    str->append('_');
1279
 
    str->append(collation.collation->csname);
1280
 
  }
1281
 
 
1282
 
  str->append('\'');
1283
 
 
1284
 
  if (query_type == QT_ORDINARY ||
1285
 
      my_charset_same(str_value.charset(), system_charset_info))
1286
 
  {
1287
 
    str_value.print(str);
1288
 
  }
1289
 
  else
1290
 
  {
1291
 
    Session *session= current_session;
1292
 
    LEX_STRING utf8_lex_str;
1293
 
 
1294
 
    session->convert_string(&utf8_lex_str,
1295
 
                        system_charset_info,
1296
 
                        str_value.c_ptr_safe(),
1297
 
                        str_value.length(),
1298
 
                        str_value.charset());
1299
 
 
1300
 
    String utf8_str(utf8_lex_str.str,
1301
 
                    utf8_lex_str.length,
1302
 
                    system_charset_info);
1303
 
 
1304
 
    utf8_str.print(str);
1305
 
  }
1306
 
 
1307
 
  str->append('\'');
1308
 
}
1309
 
 
1310
 
 
1311
 
double Item_string::val_real()
1312
 
{
1313
 
  assert(fixed == 1);
1314
 
  int error;
1315
 
  char *end, *org_end;
1316
 
  double tmp;
1317
 
  const CHARSET_INFO * const cs= str_value.charset();
1318
 
 
1319
 
  org_end= (char*) str_value.ptr() + str_value.length();
1320
 
  tmp= my_strntod(cs, (char*) str_value.ptr(), str_value.length(), &end,
1321
 
                  &error);
1322
 
  if (error || (end != org_end && !check_if_only_end_space(cs, end, org_end)))
1323
 
  {
1324
 
    /*
1325
 
      We can use str_value.ptr() here as Item_string is gurantee to put an
1326
 
      end \0 here.
1327
 
    */
1328
 
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1329
 
                        ER_TRUNCATED_WRONG_VALUE,
1330
 
                        ER(ER_TRUNCATED_WRONG_VALUE), "DOUBLE",
1331
 
                        str_value.ptr());
1332
 
  }
1333
 
  return tmp;
1334
 
}
1335
 
 
1336
 
 
1337
 
/**
1338
 
  @todo
1339
 
  Give error if we wanted a signed integer and we got an unsigned one
1340
 
*/
1341
 
int64_t Item_string::val_int()
1342
 
{
1343
 
  assert(fixed == 1);
1344
 
  int err;
1345
 
  int64_t tmp;
1346
 
  char *end= (char*) str_value.ptr()+ str_value.length();
1347
 
  char *org_end= end;
1348
 
  const CHARSET_INFO * const cs= str_value.charset();
1349
 
 
1350
 
  tmp= (*(cs->cset->strtoll10))(cs, str_value.ptr(), &end, &err);
1351
 
  /*
1352
 
    TODO: Give error if we wanted a signed integer and we got an unsigned
1353
 
    one
1354
 
  */
1355
 
  if (err > 0 ||
1356
 
      (end != org_end && !check_if_only_end_space(cs, end, org_end)))
1357
 
  {
1358
 
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1359
 
                        ER_TRUNCATED_WRONG_VALUE,
1360
 
                        ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER",
1361
 
                        str_value.ptr());
1362
 
  }
1363
 
  return tmp;
1364
 
}
1365
 
 
1366
 
 
1367
 
my_decimal *Item_string::val_decimal(my_decimal *decimal_value)
1368
 
{
1369
 
  return val_decimal_from_string(decimal_value);
1370
 
}
1371
 
 
1372
968
/****************************************************************************
1373
969
  Item_copy_string
1374
970
****************************************************************************/
2085
1681
}
2086
1682
 
2087
1683
 
2088
 
int Item_string::save_in_field(Field *field, bool)
2089
 
{
2090
 
  String *result;
2091
 
  result=val_str(&str_value);
2092
 
  return save_str_value_in_field(field, result);
2093
 
}
2094
 
 
2095
 
 
2096
 
int Item_uint::save_in_field(Field *field, bool no_conversions)
2097
 
{
2098
 
  /* Item_int::save_in_field handles both signed and unsigned. */
2099
 
  return Item_int::save_in_field(field, no_conversions);
2100
 
}
2101
 
 
2102
 
 
2103
 
int Item_int::save_in_field(Field *field, bool)
2104
 
{
2105
 
  int64_t nr=val_int();
2106
 
  if (null_value)
2107
 
    return set_field_to_null(field);
2108
 
  field->set_notnull();
2109
 
  return field->store(nr, unsigned_flag);
2110
 
}
2111
 
 
2112
 
 
2113
 
int Item_decimal::save_in_field(Field *field, bool)
2114
 
{
2115
 
  field->set_notnull();
2116
 
  return field->store_decimal(&decimal_value);
2117
 
}
2118
 
 
2119
 
 
2120
 
bool Item_int::eq(const Item *arg, bool) const
2121
 
{
2122
 
  /* No need to check for null value as basic constant can't be NULL */
2123
 
  if (arg->basic_const_item() && arg->type() == type())
2124
 
  {
2125
 
    /*
2126
 
      We need to cast off const to call val_int(). This should be OK for
2127
 
      a basic constant.
2128
 
    */
2129
 
    Item *item= (Item*) arg;
2130
 
    return item->val_int() == value && item->unsigned_flag == unsigned_flag;
2131
 
  }
2132
 
  return false;
2133
 
}
2134
 
 
2135
 
 
2136
1684
Item *Item_int_with_ref::clone_item()
2137
1685
{
2138
1686
  assert(ref->const_item());
2146
1694
}
2147
1695
 
2148
1696
 
2149
 
static uint32_t nr_of_decimals(const char *str, const char *end)
2150
 
{
2151
 
  const char *decimal_point;
2152
 
 
2153
 
  /* Find position for '.' */
2154
 
  for (;;)
2155
 
  {
2156
 
    if (str == end)
2157
 
      return 0;
2158
 
    if (*str == 'e' || *str == 'E')
2159
 
      return NOT_FIXED_DEC;
2160
 
    if (*str++ == '.')
2161
 
      break;
2162
 
  }
2163
 
  decimal_point= str;
2164
 
  for (; my_isdigit(system_charset_info, *str) ; str++)
2165
 
    ;
2166
 
  if (*str == 'e' || *str == 'E')
2167
 
    return NOT_FIXED_DEC;
2168
 
  return (uint) (str - decimal_point);
2169
 
}
2170
 
 
2171
 
 
2172
 
/**
2173
 
  This function is only called during parsing. We will signal an error if
2174
 
  value is not a true double value (overflow)
2175
 
*/
2176
 
 
2177
 
Item_float::Item_float(const char *str_arg, uint32_t length)
2178
 
{
2179
 
  int error;
2180
 
  char *end_not_used;
2181
 
  value= my_strntod(&my_charset_bin, (char*) str_arg, length, &end_not_used,
2182
 
                    &error);
2183
 
  if (error)
2184
 
  {
2185
 
    /*
2186
 
      Note that we depend on that str_arg is null terminated, which is true
2187
 
      when we are in the parser
2188
 
    */
2189
 
    assert(str_arg[length] == 0);
2190
 
    my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "double", (char*) str_arg);
2191
 
  }
2192
 
  presentation= name=(char*) str_arg;
2193
 
  decimals=(uint8_t) nr_of_decimals(str_arg, str_arg+length);
2194
 
  max_length=length;
2195
 
  fixed= 1;
2196
 
}
2197
 
 
2198
 
 
2199
 
int Item_float::save_in_field(Field *field, bool)
2200
 
{
2201
 
  double nr= val_real();
2202
 
  if (null_value)
2203
 
    return set_field_to_null(field);
2204
 
  field->set_notnull();
2205
 
  return field->store(nr);
2206
 
}
2207
 
 
2208
 
 
2209
 
void Item_float::print(String *str, enum_query_type)
2210
 
{
2211
 
  if (presentation)
2212
 
  {
2213
 
    str->append(presentation);
2214
 
    return;
2215
 
  }
2216
 
  char buffer[20];
2217
 
  String num(buffer, sizeof(buffer), &my_charset_bin);
2218
 
  num.set_real(value, decimals, &my_charset_bin);
2219
 
  str->append(num);
2220
 
}
2221
 
 
2222
 
 
2223
 
/*
2224
 
  hex item
2225
 
  In string context this is a binary string.
2226
 
  In number context this is a int64_t value.
2227
 
*/
2228
 
 
2229
 
bool Item_float::eq(const Item *arg, bool) const
2230
 
{
2231
 
  if (arg->basic_const_item() && arg->type() == type())
2232
 
  {
2233
 
    /*
2234
 
      We need to cast off const to call val_int(). This should be OK for
2235
 
      a basic constant.
2236
 
    */
2237
 
    Item *item= (Item*) arg;
2238
 
    return item->val_real() == value;
2239
 
  }
2240
 
  return false;
2241
 
}
2242
 
 
2243
 
 
2244
1697
inline uint32_t char_val(char X)
2245
1698
{
2246
1699
  return (uint) (X >= '0' && X <= '9' ? X-'0' :