~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item_func.cc

  • Committer: Paul McCullagh
  • Date: 2008-10-10 12:42:11 UTC
  • mfrom: (499 drizzle)
  • mto: (499.1.1 codestyle)
  • mto: This revision was merged to the branch mainline in revision 505.
  • Revision ID: paul.mccullagh@primebase.org-20081010124211-hxs9ny96auxpq2ag
Merged trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2000-2003 MySQL AB
 
1
/** Copyright (C) 2000-2003 MySQL AB
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
48
48
}
49
49
 
50
50
 
51
 
 
52
 
String *Item_real_func::val_str(String *str)
53
 
{
54
 
  assert(fixed == 1);
55
 
  double nr= val_real();
56
 
  if (null_value)
57
 
    return 0; /* purecov: inspected */
58
 
  str->set_real(nr,decimals, &my_charset_bin);
59
 
  return str;
60
 
}
61
 
 
62
 
 
63
 
my_decimal *Item_real_func::val_decimal(my_decimal *decimal_value)
64
 
{
65
 
  assert(fixed);
66
 
  double nr= val_real();
67
 
  if (null_value)
68
 
    return 0; /* purecov: inspected */
69
 
  double2my_decimal(E_DEC_FATAL_ERROR, nr, decimal_value);
70
 
  return decimal_value;
71
 
}
72
 
 
73
 
 
74
51
void Item_func::fix_num_length_and_dec()
75
52
{
76
53
  uint32_t fl_length= 0;
88
65
  }
89
66
}
90
67
 
91
 
 
92
 
void Item_func_numhybrid::fix_num_length_and_dec()
93
 
{}
94
 
 
95
 
 
96
68
/**
97
69
  Set max_length/decimals of function if function is fixed point and
98
70
  result length/precision depends on argument ones.
198
170
 
199
171
 
200
172
/**
201
 
  Check arguments here to determine result's type for a numeric
202
 
  function of two arguments.
203
 
*/
204
 
 
205
 
void Item_num_op::find_num_type(void)
206
 
{
207
 
  assert(arg_count == 2);
208
 
  Item_result r0= args[0]->result_type();
209
 
  Item_result r1= args[1]->result_type();
210
 
 
211
 
  if (r0 == REAL_RESULT || r1 == REAL_RESULT ||
212
 
      r0 == STRING_RESULT || r1 ==STRING_RESULT)
213
 
  {
214
 
    count_real_length();
215
 
    max_length= float_length(decimals);
216
 
    hybrid_type= REAL_RESULT;
217
 
  }
218
 
  else if (r0 == DECIMAL_RESULT || r1 == DECIMAL_RESULT)
219
 
  {
220
 
    hybrid_type= DECIMAL_RESULT;
221
 
    result_precision();
222
 
  }
223
 
  else
224
 
  {
225
 
    assert(r0 == INT_RESULT && r1 == INT_RESULT);
226
 
    decimals= 0;
227
 
    hybrid_type=INT_RESULT;
228
 
    result_precision();
229
 
  }
230
 
  return;
231
 
}
232
 
 
233
 
 
234
 
/**
235
173
  Set result type for a numeric function of one argument
236
174
  (can be also used by a numeric function of many arguments, if the result
237
175
  type depends only on the first argument)
264
202
}
265
203
 
266
204
 
267
 
void Item_func_numhybrid::fix_length_and_dec()
268
 
{
269
 
  fix_num_length_and_dec();
270
 
  find_num_type();
271
 
}
272
 
 
273
 
 
274
 
String *Item_func_numhybrid::val_str(String *str)
275
 
{
276
 
  assert(fixed == 1);
277
 
  switch (hybrid_type) {
278
 
  case DECIMAL_RESULT:
279
 
  {
280
 
    my_decimal decimal_value, *val;
281
 
    if (!(val= decimal_op(&decimal_value)))
282
 
      return 0;                                 // null is set
283
 
    my_decimal_round(E_DEC_FATAL_ERROR, val, decimals, false, val);
284
 
    my_decimal2string(E_DEC_FATAL_ERROR, val, 0, 0, 0, str);
285
 
    break;
286
 
  }
287
 
  case INT_RESULT:
288
 
  {
289
 
    int64_t nr= int_op();
290
 
    if (null_value)
291
 
      return 0; /* purecov: inspected */
292
 
    str->set_int(nr, unsigned_flag, &my_charset_bin);
293
 
    break;
294
 
  }
295
 
  case REAL_RESULT:
296
 
  {
297
 
    double nr= real_op();
298
 
    if (null_value)
299
 
      return 0; /* purecov: inspected */
300
 
    str->set_real(nr,decimals,&my_charset_bin);
301
 
    break;
302
 
  }
303
 
  case STRING_RESULT:
304
 
    return str_op(&str_value);
305
 
  default:
306
 
    assert(0);
307
 
  }
308
 
  return str;
309
 
}
310
 
 
311
 
 
312
 
double Item_func_numhybrid::val_real()
313
 
{
314
 
  assert(fixed == 1);
315
 
  switch (hybrid_type) {
316
 
  case DECIMAL_RESULT:
317
 
  {
318
 
    my_decimal decimal_value, *val;
319
 
    double result;
320
 
    if (!(val= decimal_op(&decimal_value)))
321
 
      return 0.0;                               // null is set
322
 
    my_decimal2double(E_DEC_FATAL_ERROR, val, &result);
323
 
    return result;
324
 
  }
325
 
  case INT_RESULT:
326
 
  {
327
 
    int64_t result= int_op();
328
 
    return unsigned_flag ? (double) ((uint64_t) result) : (double) result;
329
 
  }
330
 
  case REAL_RESULT:
331
 
    return real_op();
332
 
  case STRING_RESULT:
333
 
  {
334
 
    char *end_not_used;
335
 
    int err_not_used;
336
 
    String *res= str_op(&str_value);
337
 
    return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
338
 
                             &end_not_used, &err_not_used) : 0.0);
339
 
  }
340
 
  default:
341
 
    assert(0);
342
 
  }
343
 
  return 0.0;
344
 
}
345
 
 
346
 
 
347
 
int64_t Item_func_numhybrid::val_int()
348
 
{
349
 
  assert(fixed == 1);
350
 
  switch (hybrid_type) {
351
 
  case DECIMAL_RESULT:
352
 
  {
353
 
    my_decimal decimal_value, *val;
354
 
    if (!(val= decimal_op(&decimal_value)))
355
 
      return 0;                                 // null is set
356
 
    int64_t result;
357
 
    my_decimal2int(E_DEC_FATAL_ERROR, val, unsigned_flag, &result);
358
 
    return result;
359
 
  }
360
 
  case INT_RESULT:
361
 
    return int_op();
362
 
  case REAL_RESULT:
363
 
    return (int64_t) rint(real_op());
364
 
  case STRING_RESULT:
365
 
  {
366
 
    int err_not_used;
367
 
    String *res;
368
 
    if (!(res= str_op(&str_value)))
369
 
      return 0;
370
 
 
371
 
    char *end= (char*) res->ptr() + res->length();
372
 
    const CHARSET_INFO * const cs= str_value.charset();
373
 
    return (*(cs->cset->strtoll10))(cs, res->ptr(), &end, &err_not_used);
374
 
  }
375
 
  default:
376
 
    assert(0);
377
 
  }
378
 
  return 0;
379
 
}
380
 
 
381
 
 
382
 
my_decimal *Item_func_numhybrid::val_decimal(my_decimal *decimal_value)
383
 
{
384
 
  my_decimal *val= decimal_value;
385
 
  assert(fixed == 1);
386
 
  switch (hybrid_type) {
387
 
  case DECIMAL_RESULT:
388
 
    val= decimal_op(decimal_value);
389
 
    break;
390
 
  case INT_RESULT:
391
 
  {
392
 
    int64_t result= int_op();
393
 
    int2my_decimal(E_DEC_FATAL_ERROR, result, unsigned_flag, decimal_value);
394
 
    break;
395
 
  }
396
 
  case REAL_RESULT:
397
 
  {
398
 
    double result= (double)real_op();
399
 
    double2my_decimal(E_DEC_FATAL_ERROR, result, decimal_value);
400
 
    break;
401
 
  }
402
 
  case STRING_RESULT:
403
 
  {
404
 
    String *res;
405
 
    if (!(res= str_op(&str_value)))
406
 
      return NULL;
407
 
 
408
 
    str2my_decimal(E_DEC_FATAL_ERROR, (char*) res->ptr(),
409
 
                   res->length(), res->charset(), decimal_value);
410
 
    break;
411
 
  }  
412
 
  case ROW_RESULT:
413
 
  default:
414
 
    assert(0);
415
 
  }
416
 
  return val;
417
 
}
418
 
 
419
 
 
420
205
void Item_func_signed::print(String *str, enum_query_type query_type)
421
206
{
422
207
  str->append(STRING_WITH_LEN("cast("));
425
210
 
426
211
}
427
212
 
428
 
 
429
213
int64_t Item_func_signed::val_int_from_str(int *error)
430
214
{
431
215
  char buff[MAX_FIELD_WIDTH], *end, *start;