MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sql_analyse.cc
1 /*
2  Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software Foundation,
15  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
16 
17 
18 /* Analyse database */
19 
20 /* TODO: - Check if any character fields can be of any date type
21 ** (date, datetime, year, time, timestamp, newdate)
22 ** - Check if any number field should be a timestamp
23 ** - type set is out of optimization yet
24 */
25 
26 #define MYSQL_LEX 1
27 
28 #include "sql_priv.h"
29 #include "procedure.h"
30 #include "sql_analyse.h"
31 #include "sql_class.h"
32 #include <m_ctype.h>
33 
34 using std::min;
35 using std::max;
36 
37 int sortcmp2(void* cmp_arg __attribute__((unused)),
38  const String *a,const String *b)
39 {
40  return sortcmp(a,b,a->charset());
41 }
42 
43 int compare_double2(void* cmp_arg __attribute__((unused)),
44  const double *s, const double *t)
45 {
46  return compare_double(s,t);
47 }
48 
49 int compare_longlong2(void* cmp_arg __attribute__((unused)),
50  const longlong *s, const longlong *t)
51 {
52  return compare_longlong(s,t);
53 }
54 
55 int compare_ulonglong2(void* cmp_arg __attribute__((unused)),
56  const ulonglong *s, const ulonglong *t)
57 {
58  return compare_ulonglong(s,t);
59 }
60 
61 int compare_decimal2(int* len, const char *s, const char *t)
62 {
63  return memcmp(s, t, *len);
64 }
65 
74 bool
75 select_analyse::init(List<Item> &field_list)
76 {
77  DBUG_ENTER("proc_analyse_init");
78 
79  DBUG_ASSERT(thd->lex->sql_command == SQLCOM_SELECT);
80 
81  if (!(f_info=
82  (field_info**)sql_alloc(sizeof(field_info*)*field_list.elements)))
83  DBUG_RETURN(true);
84 
85  f_end= f_info + field_list.elements;
86 
87  {
88  List_iterator_fast<Item> it(field_list);
89  field_info **info= f_info;
90  Item *item;
91  while ((item = it++))
92  {
93  field_info *new_field;
94  switch (item->result_type()) {
95  case INT_RESULT:
96  // Check if fieldtype is ulonglong
97  if (item->type() == Item::FIELD_ITEM &&
98  ((Item_field*) item)->field->type() == MYSQL_TYPE_LONGLONG &&
99  ((Field_longlong*) ((Item_field*) item)->field)->unsigned_flag)
100  new_field= new field_ulonglong(item, this);
101  else
102  new_field= new field_longlong(item, this);
103  break;
104  case REAL_RESULT:
105  new_field= new field_real(item, this);
106  break;
107  case DECIMAL_RESULT:
108  new_field= new field_decimal(item, this);
109  break;
110  case STRING_RESULT:
111  new_field= new field_str(item, this);
112  break;
113  default:
114  DBUG_RETURN(true);
115  }
116  if (new_field == NULL)
117  DBUG_RETURN(true);
118  *info++= new_field;
119  }
120  }
121  DBUG_RETURN(false);
122 }
123 
124 
125 /*
126  Return 1 if number, else return 0
127  store info about found number in info
128  NOTE:It is expected, that elements of 'info' are all zero!
129 */
130 
131 bool test_if_number(NUM_INFO *info, const char *str, uint str_len)
132 {
133  const char *begin, *end= str + str_len;
134  DBUG_ENTER("test_if_number");
135 
136  /*
137  MySQL removes any endspaces of a string, so we must take care only of
138  spaces in front of a string
139  */
140  for (; str != end && my_isspace(system_charset_info, *str); str++) ;
141  if (str == end)
142  DBUG_RETURN(0);
143 
144  if (*str == '-')
145  {
146  info->negative = 1;
147  if (++str == end || *str == '0') // converting -0 to a number
148  DBUG_RETURN(0); // might lose information
149  }
150  else
151  info->negative = 0;
152  begin = str;
153  for (; str != end && my_isdigit(system_charset_info,*str); str++)
154  {
155  if (!info->integers && *str == '0' && (str + 1) != end &&
156  my_isdigit(system_charset_info,*(str + 1)))
157  info->zerofill = 1; // could be a postnumber for example
158  info->integers++;
159  }
160  if (str == end && info->integers)
161  {
162  char *endpos= (char*) end;
163  int error;
164  info->ullval= (ulonglong) my_strtoll10(begin, &endpos, &error);
165  if (info->integers == 1)
166  DBUG_RETURN(0); // single number can't be zerofill
167  info->maybe_zerofill = 1;
168  DBUG_RETURN(1); // a zerofill number, or an integer
169  }
170  if (*str == '.' || *str == 'e' || *str == 'E')
171  {
172  if (info->zerofill) // can't be zerofill anymore
173  DBUG_RETURN(0);
174  if ((str + 1) == end) // number was something like '123[.eE]'
175  {
176  char *endpos= (char*) str;
177  int error;
178  info->ullval= (ulonglong) my_strtoll10(begin, &endpos, &error);
179  DBUG_RETURN(1);
180  }
181  if (*str == 'e' || *str == 'E') // number may be something like '1e+50'
182  {
183  str++;
184  if (*str != '-' && *str != '+')
185  DBUG_RETURN(0);
186  for (str++; str != end && my_isdigit(system_charset_info,*str); str++) ;
187  if (str == end)
188  {
189  info->is_float = 1; // we can't use variable decimals here
190  DBUG_RETURN(1);
191  }
192  DBUG_RETURN(0);
193  }
194  for (str++; *(end - 1) == '0'; end--) ; // jump over zeros at the end
195  if (str == end) // number was something like '123.000'
196  {
197  char *endpos= (char*) str;
198  int error;
199  info->ullval= (ulonglong) my_strtoll10(begin, &endpos, &error);
200  DBUG_RETURN(1);
201  }
202  for (; str != end && my_isdigit(system_charset_info,*str); str++)
203  info->decimals++;
204  if (str == end)
205  {
206  info->dval = my_atof(begin);
207  DBUG_RETURN(1);
208  }
209  }
210  DBUG_RETURN(0);
211 }
212 
213 
214 /*
215  Stores the biggest and the smallest value from current 'info'
216  to ev_num_info
217  If info contains an ulonglong number, which is bigger than
218  biggest positive number able to be stored in a longlong variable
219  and is marked as negative, function will return 0, else 1.
220 */
221 
222 bool get_ev_num_info(EV_NUM_INFO *ev_info, NUM_INFO *info, const char *num)
223 {
224  if (info->negative)
225  {
226  if (((longlong) info->ullval) < 0)
227  return 0; // Impossible to store as a negative number
228  ev_info->llval = - max<longlong>((ulonglong) -ev_info->llval,
229  info->ullval);
230  ev_info->min_dval = - max<double>(-ev_info->min_dval, info->dval);
231  }
232  else // ulonglong is as big as bigint in MySQL
233  {
234  if ((check_ulonglong(num, info->integers) == DECIMAL_NUM))
235  return 0;
236  ev_info->ullval = max<ulonglong>(ev_info->ullval, info->ullval);
237  ev_info->max_dval = max<double>(ev_info->max_dval, info->dval);
238  }
239  return 1;
240 } // get_ev_num_info
241 
242 
243 void free_string(String *s)
244 {
245  s->free();
246 }
247 
248 
249 void field_str::add()
250 {
251  char buff[MAX_FIELD_WIDTH], *ptr;
252  String s(buff, sizeof(buff),&my_charset_bin), *res;
253  ulong length;
254 
255  if (!(res= item->str_result(&s)))
256  {
257  nulls++;
258  return;
259  }
260 
261  if (!(length = res->length()))
262  empty++;
263  else
264  {
265  ptr = (char*) res->ptr();
266  if (*(ptr + (length - 1)) == ' ')
267  must_be_blob = 1;
268  }
269 
270  if (can_be_still_num)
271  {
272  memset(&num_info, 0, sizeof(num_info));
273  if (!test_if_number(&num_info, res->ptr(), (uint) length))
274  can_be_still_num = 0;
275  if (!found)
276  {
277  memset(&ev_num_info, 0, sizeof(ev_num_info));
278  was_zero_fill = num_info.zerofill;
279  }
280  else if (num_info.zerofill != was_zero_fill && !was_maybe_zerofill)
281  can_be_still_num = 0; // one more check needed, when length is counted
282  if (can_be_still_num)
283  can_be_still_num = get_ev_num_info(&ev_num_info, &num_info, res->ptr());
284  was_maybe_zerofill = num_info.maybe_zerofill;
285  }
286 
287  /* Update min and max arguments */
288  if (!found)
289  {
290  found = 1;
291  min_arg.copy(*res);
292  max_arg.copy(*res);
293  min_length = max_length = length; sum=length;
294  }
295  else if (length)
296  {
297  sum += length;
298  if (length < min_length)
299  min_length = length;
300  if (length > max_length)
301  max_length = length;
302 
303  if (sortcmp(res, &min_arg,item->collation.collation) < 0)
304  min_arg.copy(*res);
305  if (sortcmp(res, &max_arg,item->collation.collation) > 0)
306  max_arg.copy(*res);
307  }
308 
309  if (room_in_tree)
310  {
311  if (res != &s)
312  s.copy(*res);
313  if (!tree_search(&tree, (void*) &s, tree.custom_arg)) // If not in tree
314  {
315  s.copy(); // slow, when SAFE_MALLOC is in use
316  if (!tree_insert(&tree, (void*) &s, 0, tree.custom_arg))
317  {
318  room_in_tree = 0; // Remove tree, out of RAM ?
319  delete_tree(&tree);
320  }
321  else
322  {
323  memset(&s, 0, sizeof(s)); // Let tree handle free of this
324  if ((treemem += length) > pc->max_treemem)
325  {
326  room_in_tree = 0; // Remove tree, too big tree
327  delete_tree(&tree);
328  }
329  }
330  }
331  }
332 
333  if ((num_info.zerofill && (max_length != min_length)) ||
334  (was_zero_fill && (max_length != min_length)))
335  can_be_still_num = 0; // zerofilled numbers must be of same length
336 } // field_str::add
337 
338 
339 void field_real::add()
340 {
341  char buff[MAX_FIELD_WIDTH], *ptr, *end;
342  double num= item->val_result();
343  uint length, zero_count, decs;
344  TREE_ELEMENT *element;
345 
346  if (item->null_value)
347  {
348  nulls++;
349  return;
350  }
351  if (num == 0.0)
352  empty++;
353 
354  if ((decs = decimals()) == NOT_FIXED_DEC)
355  {
356  length= sprintf(buff, "%g", num);
357  if (rint(num) != num)
358  max_notzero_dec_len = 1;
359  }
360  else
361  {
362 #ifdef HAVE_SNPRINTF
363  buff[sizeof(buff)-1]=0; // Safety
364  snprintf(buff, sizeof(buff)-1, "%-.*f", (int) decs, num);
365  length = (uint) strlen(buff);
366 #else
367  length= sprintf(buff, "%-.*f", (int) decs, num);
368 #endif
369 
370  // We never need to check further than this
371  end = buff + length - 1 - decs + max_notzero_dec_len;
372 
373  zero_count = 0;
374  for (ptr = buff + length - 1; ptr > end && *ptr == '0'; ptr--)
375  zero_count++;
376 
377  if ((decs - zero_count > max_notzero_dec_len))
378  max_notzero_dec_len = decs - zero_count;
379  }
380 
381  if (room_in_tree)
382  {
383  if (!(element = tree_insert(&tree, (void*) &num, 0, tree.custom_arg)))
384  {
385  room_in_tree = 0; // Remove tree, out of RAM ?
386  delete_tree(&tree);
387  }
388  /*
389  if element->count == 1, this element can be found only once from tree
390  if element->count == 2, or more, this element is already in tree
391  */
392  else if (element->count == 1 && (tree_elements++) >= pc->max_tree_elements)
393  {
394  room_in_tree = 0; // Remove tree, too many elements
395  delete_tree(&tree);
396  }
397  }
398 
399  if (!found)
400  {
401  found = 1;
402  min_arg = max_arg = sum = num;
403  sum_sqr = num * num;
404  min_length = max_length = length;
405  }
406  else if (num != 0.0)
407  {
408  sum += num;
409  sum_sqr += num * num;
410  if (length < min_length)
411  min_length = length;
412  if (length > max_length)
413  max_length = length;
414  if (compare_double(&num, &min_arg) < 0)
415  min_arg = num;
416  if (compare_double(&num, &max_arg) > 0)
417  max_arg = num;
418  }
419 } // field_real::add
420 
421 
422 void field_decimal::add()
423 {
424  /*TODO - remove rounding stuff after decimal_div returns proper frac */
425  my_decimal dec_buf, *dec= item->val_decimal_result(&dec_buf);
426  my_decimal rounded;
427  uint length;
428  TREE_ELEMENT *element;
429 
430  if (item->null_value)
431  {
432  nulls++;
433  return;
434  }
435 
436  my_decimal_round(E_DEC_FATAL_ERROR, dec, item->decimals, FALSE,&rounded);
437  dec= &rounded;
438 
439  length= my_decimal_string_length(dec);
440 
441  if (decimal_is_zero(dec))
442  empty++;
443 
444  if (room_in_tree)
445  {
447  my_decimal2binary(E_DEC_FATAL_ERROR, dec, buf,
448  item->max_length, item->decimals);
449  if (!(element = tree_insert(&tree, (void*)buf, 0, tree.custom_arg)))
450  {
451  room_in_tree = 0; // Remove tree, out of RAM ?
452  delete_tree(&tree);
453  }
454  /*
455  if element->count == 1, this element can be found only once from tree
456  if element->count == 2, or more, this element is already in tree
457  */
458  else if (element->count == 1 && (tree_elements++) >= pc->max_tree_elements)
459  {
460  room_in_tree = 0; // Remove tree, too many elements
461  delete_tree(&tree);
462  }
463  }
464 
465  if (!found)
466  {
467  found = 1;
468  min_arg = max_arg = sum[0] = *dec;
469  my_decimal_mul(E_DEC_FATAL_ERROR, sum_sqr, dec, dec);
470  cur_sum= 0;
471  min_length = max_length = length;
472  }
473  else if (!decimal_is_zero(dec))
474  {
475  int next_cur_sum= cur_sum ^ 1;
476  my_decimal sqr_buf;
477 
478  my_decimal_add(E_DEC_FATAL_ERROR, sum+next_cur_sum, sum+cur_sum, dec);
479  my_decimal_mul(E_DEC_FATAL_ERROR, &sqr_buf, dec, dec);
480  my_decimal_add(E_DEC_FATAL_ERROR,
481  sum_sqr+next_cur_sum, sum_sqr+cur_sum, &sqr_buf);
482  cur_sum= next_cur_sum;
483  if (length < min_length)
484  min_length = length;
485  if (length > max_length)
486  max_length = length;
487  if (my_decimal_cmp(dec, &min_arg) < 0)
488  {
489  min_arg= *dec;
490  }
491  if (my_decimal_cmp(dec, &max_arg) > 0)
492  {
493  max_arg= *dec;
494  }
495  }
496 }
497 
498 
499 void field_longlong::add()
500 {
501  char buff[MAX_FIELD_WIDTH];
502  longlong num= item->val_int_result();
503  uint length= (uint) (longlong10_to_str(num, buff, -10) - buff);
504  TREE_ELEMENT *element;
505 
506  if (item->null_value)
507  {
508  nulls++;
509  return;
510  }
511  if (num == 0)
512  empty++;
513 
514  if (room_in_tree)
515  {
516  if (!(element = tree_insert(&tree, (void*) &num, 0, tree.custom_arg)))
517  {
518  room_in_tree = 0; // Remove tree, out of RAM ?
519  delete_tree(&tree);
520  }
521  /*
522  if element->count == 1, this element can be found only once from tree
523  if element->count == 2, or more, this element is already in tree
524  */
525  else if (element->count == 1 && (tree_elements++) >= pc->max_tree_elements)
526  {
527  room_in_tree = 0; // Remove tree, too many elements
528  delete_tree(&tree);
529  }
530  }
531 
532  if (!found)
533  {
534  found = 1;
535  min_arg = max_arg = sum = num;
536  sum_sqr = num * num;
537  min_length = max_length = length;
538  }
539  else if (num != 0)
540  {
541  sum += num;
542  sum_sqr += num * num;
543  if (length < min_length)
544  min_length = length;
545  if (length > max_length)
546  max_length = length;
547  if (compare_longlong(&num, &min_arg) < 0)
548  min_arg = num;
549  if (compare_longlong(&num, &max_arg) > 0)
550  max_arg = num;
551  }
552 } // field_longlong::add
553 
554 
555 void field_ulonglong::add()
556 {
557  char buff[MAX_FIELD_WIDTH];
558  longlong num= item->val_int_result();
559  uint length= (uint) (longlong10_to_str(num, buff, 10) - buff);
560  TREE_ELEMENT *element;
561 
562  if (item->null_value)
563  {
564  nulls++;
565  return;
566  }
567  if (num == 0)
568  empty++;
569 
570  if (room_in_tree)
571  {
572  if (!(element = tree_insert(&tree, (void*) &num, 0, tree.custom_arg)))
573  {
574  room_in_tree = 0; // Remove tree, out of RAM ?
575  delete_tree(&tree);
576  }
577  /*
578  if element->count == 1, this element can be found only once from tree
579  if element->count == 2, or more, this element is already in tree
580  */
581  else if (element->count == 1 && (tree_elements++) >= pc->max_tree_elements)
582  {
583  room_in_tree = 0; // Remove tree, too many elements
584  delete_tree(&tree);
585  }
586  }
587 
588  if (!found)
589  {
590  found = 1;
591  min_arg = max_arg = sum = num;
592  sum_sqr = num * num;
593  min_length = max_length = length;
594  }
595  else if (num != 0)
596  {
597  sum += num;
598  sum_sqr += num * num;
599  if (length < min_length)
600  min_length = length;
601  if (length > max_length)
602  max_length = length;
603  if (compare_ulonglong((ulonglong*) &num, &min_arg) < 0)
604  min_arg = num;
605  if (compare_ulonglong((ulonglong*) &num, &max_arg) > 0)
606  max_arg = num;
607  }
608 } // field_ulonglong::add
609 
610 
611 bool select_analyse::send_data(List<Item> & /* field_list */)
612 {
613  field_info **f = f_info;
614 
615  rows++;
616 
617  for (;f != f_end; f++)
618  {
619  (*f)->add();
620  }
621  return false;
622 }
623 
624 
625 bool select_analyse::send_eof()
626 {
627  field_info **f = f_info;
628  char buff[MAX_FIELD_WIDTH];
629  String *res, s_min(buff, sizeof(buff),&my_charset_bin),
630  s_max(buff, sizeof(buff),&my_charset_bin),
631  ans(buff, sizeof(buff),&my_charset_bin);
632 
633  if (rows == 0) // for backward compatibility
634  goto ok;
635 
636  for (; f != f_end; f++)
637  {
638  func_items[0]->set((*f)->item->full_name());
639  if (!(*f)->found)
640  {
641  func_items[1]->null_value = 1;
642  func_items[2]->null_value = 1;
643  }
644  else
645  {
646  func_items[1]->null_value = 0;
647  res = (*f)->get_min_arg(&s_min);
648  func_items[1]->set(res->ptr(), res->length(), res->charset());
649  func_items[2]->null_value = 0;
650  res = (*f)->get_max_arg(&s_max);
651  func_items[2]->set(res->ptr(), res->length(), res->charset());
652  }
653  func_items[3]->set((longlong) (*f)->min_length);
654  func_items[4]->set((longlong) (*f)->max_length);
655  func_items[5]->set((longlong) (*f)->empty);
656  func_items[6]->set((longlong) (*f)->nulls);
657  res = (*f)->avg(&s_max, rows);
658  func_items[7]->set(res->ptr(), res->length(), res->charset());
659  func_items[8]->null_value = 0;
660  res = (*f)->std(&s_max, rows);
661  if (!res)
662  func_items[8]->null_value = 1;
663  else
664  func_items[8]->set(res->ptr(), res->length(), res->charset());
665  /*
666  count the dots, quotas, etc. in (ENUM("a","b","c"...))
667  If tree has been removed, don't suggest ENUM.
668  treemem is used to measure the size of tree for strings,
669  tree_elements is used to count the elements
670  max_treemem tells how long the string starting from ENUM("... and
671  ending to ..") shall at maximum be. If case is about numbers,
672  max_tree_elements will tell the length of the above, now
673  every number is considered as length 1
674  */
675  if (((*f)->treemem || (*f)->tree_elements) &&
676  (*f)->tree.elements_in_tree &&
677  (((*f)->treemem ? max_treemem : max_tree_elements) >
678  (((*f)->treemem ? (*f)->treemem : (*f)->tree_elements) +
679  ((*f)->tree.elements_in_tree * 3 - 1 + 6))))
680  {
681  char tmp[331]; //331, because one double prec. num. can be this long
682  String tmp_str(tmp, sizeof(tmp),&my_charset_bin);
683  TREE_INFO tree_info;
684 
685  tree_info.str = &tmp_str;
686  tree_info.found = 0;
687  tree_info.item = (*f)->item;
688 
689  tmp_str.set(STRING_WITH_LEN("ENUM("),&my_charset_bin);
690  tree_walk(&(*f)->tree, (*f)->collect_enum(), (char*) &tree_info,
691  left_root_right);
692  tmp_str.append(')');
693 
694  if (!(*f)->nulls)
695  tmp_str.append(STRING_WITH_LEN(" NOT NULL"));
696  output_str_length = tmp_str.length();
697  func_items[9]->set(tmp_str.ptr(), tmp_str.length(), tmp_str.charset());
698  if (result->send_data(result_fields))
699  goto error;
700  continue;
701  }
702 
703  ans.length(0);
704  if (!(*f)->treemem && !(*f)->tree_elements)
705  ans.append(STRING_WITH_LEN("CHAR(0)"));
706  else if ((*f)->item->type() == Item::FIELD_ITEM)
707  {
708  switch (((Item_field*) (*f)->item)->field->real_type())
709  {
710  case MYSQL_TYPE_TIMESTAMP:
711  ans.append(STRING_WITH_LEN("TIMESTAMP"));
712  break;
713  case MYSQL_TYPE_DATETIME:
714  ans.append(STRING_WITH_LEN("DATETIME"));
715  break;
716  case MYSQL_TYPE_DATE:
717  case MYSQL_TYPE_NEWDATE:
718  ans.append(STRING_WITH_LEN("DATE"));
719  break;
720  case MYSQL_TYPE_SET:
721  ans.append(STRING_WITH_LEN("SET"));
722  break;
723  case MYSQL_TYPE_YEAR:
724  ans.append(STRING_WITH_LEN("YEAR"));
725  break;
726  case MYSQL_TYPE_TIME:
727  ans.append(STRING_WITH_LEN("TIME"));
728  break;
729  case MYSQL_TYPE_DECIMAL:
730  ans.append(STRING_WITH_LEN("DECIMAL"));
731  // if item is FIELD_ITEM, it _must_be_ Field_num in this case
732  if (((Field_num*) ((Item_field*) (*f)->item)->field)->zerofill)
733  ans.append(STRING_WITH_LEN(" ZEROFILL"));
734  break;
735  default:
736  (*f)->get_opt_type(&ans, rows);
737  break;
738  }
739  }
740  if (!(*f)->nulls)
741  ans.append(STRING_WITH_LEN(" NOT NULL"));
742  func_items[9]->set(ans.ptr(), ans.length(), ans.charset());
743  if (result->send_data(result_fields))
744  goto error;
745  }
746 ok:
747  return result->send_eof();
748 error:
749  abort_result_set();
750  return true;
751 } // select_analyse::send_eof
752 
753 
754 void field_str::get_opt_type(String *answer, ha_rows total_rows)
755 {
756  char buff[MAX_FIELD_WIDTH];
757 
758  if (can_be_still_num)
759  {
760  if (num_info.is_float)
761  sprintf(buff, "DOUBLE"); // number was like 1e+50... TODO:
762  else if (num_info.decimals) // DOUBLE(%d,%d) sometime
763  {
764  if (num_info.dval > -FLT_MAX && num_info.dval < FLT_MAX)
765  sprintf(buff, "FLOAT(%d,%d)", (num_info.integers + num_info.decimals), num_info.decimals);
766  else
767  sprintf(buff, "DOUBLE(%d,%d)", (num_info.integers + num_info.decimals), num_info.decimals);
768  }
769  else if (ev_num_info.llval >= -128 &&
770  ev_num_info.ullval <=
771  (ulonglong) (ev_num_info.llval >= 0 ? 255 : 127))
772  sprintf(buff, "TINYINT(%d)", num_info.integers);
773  else if (ev_num_info.llval >= INT_MIN16 &&
774  ev_num_info.ullval <= (ulonglong) (ev_num_info.llval >= 0 ?
775  UINT_MAX16 : INT_MAX16))
776  sprintf(buff, "SMALLINT(%d)", num_info.integers);
777  else if (ev_num_info.llval >= INT_MIN24 &&
778  ev_num_info.ullval <= (ulonglong) (ev_num_info.llval >= 0 ?
779  UINT_MAX24 : INT_MAX24))
780  sprintf(buff, "MEDIUMINT(%d)", num_info.integers);
781  else if (ev_num_info.llval >= INT_MIN32 &&
782  ev_num_info.ullval <= (ulonglong) (ev_num_info.llval >= 0 ?
783  UINT_MAX32 : INT_MAX32))
784  sprintf(buff, "INT(%d)", num_info.integers);
785  else
786  sprintf(buff, "BIGINT(%d)", num_info.integers);
787  answer->append(buff, (uint) strlen(buff));
788  if (ev_num_info.llval >= 0 && ev_num_info.min_dval >= 0)
789  answer->append(STRING_WITH_LEN(" UNSIGNED"));
790  if (num_info.zerofill)
791  answer->append(STRING_WITH_LEN(" ZEROFILL"));
792  }
793  else if (max_length < 256)
794  {
795  if (must_be_blob)
796  {
797  if (item->collation.collation == &my_charset_bin)
798  answer->append(STRING_WITH_LEN("TINYBLOB"));
799  else
800  answer->append(STRING_WITH_LEN("TINYTEXT"));
801  }
802  else if ((max_length * (total_rows - nulls)) < (sum + total_rows))
803  {
804  sprintf(buff, "CHAR(%d)", (int) max_length);
805  answer->append(buff, (uint) strlen(buff));
806  }
807  else
808  {
809  sprintf(buff, "VARCHAR(%d)", (int) max_length);
810  answer->append(buff, (uint) strlen(buff));
811  }
812  }
813  else if (max_length < (1L << 16))
814  {
815  if (item->collation.collation == &my_charset_bin)
816  answer->append(STRING_WITH_LEN("BLOB"));
817  else
818  answer->append(STRING_WITH_LEN("TEXT"));
819  }
820  else if (max_length < (1L << 24))
821  {
822  if (item->collation.collation == &my_charset_bin)
823  answer->append(STRING_WITH_LEN("MEDIUMBLOB"));
824  else
825  answer->append(STRING_WITH_LEN("MEDIUMTEXT"));
826  }
827  else
828  {
829  if (item->collation.collation == &my_charset_bin)
830  answer->append(STRING_WITH_LEN("LONGBLOB"));
831  else
832  answer->append(STRING_WITH_LEN("LONGTEXT"));
833  }
834 } // field_str::get_opt_type
835 
836 
837 void field_real::get_opt_type(String *answer,
838  ha_rows total_rows __attribute__((unused)))
839 {
840  char buff[MAX_FIELD_WIDTH];
841 
842  if (!max_notzero_dec_len)
843  {
844  int len= (int) max_length - ((item->decimals == NOT_FIXED_DEC) ?
845  0 : (item->decimals + 1));
846 
847  if (min_arg >= -128 && max_arg <= (min_arg >= 0 ? 255 : 127))
848  sprintf(buff, "TINYINT(%d)", len);
849  else if (min_arg >= INT_MIN16 && max_arg <= (min_arg >= 0 ?
850  UINT_MAX16 : INT_MAX16))
851  sprintf(buff, "SMALLINT(%d)", len);
852  else if (min_arg >= INT_MIN24 && max_arg <= (min_arg >= 0 ?
853  UINT_MAX24 : INT_MAX24))
854  sprintf(buff, "MEDIUMINT(%d)", len);
855  else if (min_arg >= INT_MIN32 && max_arg <= (min_arg >= 0 ?
856  UINT_MAX32 : INT_MAX32))
857  sprintf(buff, "INT(%d)", len);
858  else
859  sprintf(buff, "BIGINT(%d)", len);
860  answer->append(buff, (uint) strlen(buff));
861  if (min_arg >= 0)
862  answer->append(STRING_WITH_LEN(" UNSIGNED"));
863  }
864  else if (item->decimals == NOT_FIXED_DEC)
865  {
866  if (min_arg >= -FLT_MAX && max_arg <= FLT_MAX)
867  answer->append(STRING_WITH_LEN("FLOAT"));
868  else
869  answer->append(STRING_WITH_LEN("DOUBLE"));
870  }
871  else
872  {
873  if (min_arg >= -FLT_MAX && max_arg <= FLT_MAX)
874  sprintf(buff, "FLOAT(%d,%d)", (int) max_length - (item->decimals + 1) + max_notzero_dec_len,
875  max_notzero_dec_len);
876  else
877  sprintf(buff, "DOUBLE(%d,%d)", (int) max_length - (item->decimals + 1) + max_notzero_dec_len,
878  max_notzero_dec_len);
879  answer->append(buff, (uint) strlen(buff));
880  }
881  // if item is FIELD_ITEM, it _must_be_ Field_num in this class
882  if (item->type() == Item::FIELD_ITEM &&
883  // a single number shouldn't be zerofill
884  (max_length - (item->decimals + 1)) != 1 &&
885  ((Field_num*) ((Item_field*) item)->field)->zerofill)
886  answer->append(STRING_WITH_LEN(" ZEROFILL"));
887 } // field_real::get_opt_type
888 
889 
890 void field_longlong::get_opt_type(String *answer,
891  ha_rows total_rows __attribute__((unused)))
892 {
893  char buff[MAX_FIELD_WIDTH];
894 
895  if (min_arg >= -128 && max_arg <= (min_arg >= 0 ? 255 : 127))
896  sprintf(buff, "TINYINT(%d)", (int) max_length);
897  else if (min_arg >= INT_MIN16 && max_arg <= (min_arg >= 0 ?
898  UINT_MAX16 : INT_MAX16))
899  sprintf(buff, "SMALLINT(%d)", (int) max_length);
900  else if (min_arg >= INT_MIN24 && max_arg <= (min_arg >= 0 ?
901  UINT_MAX24 : INT_MAX24))
902  sprintf(buff, "MEDIUMINT(%d)", (int) max_length);
903  else if (min_arg >= INT_MIN32 && max_arg <= (min_arg >= 0 ?
904  UINT_MAX32 : INT_MAX32))
905  sprintf(buff, "INT(%d)", (int) max_length);
906  else
907  sprintf(buff, "BIGINT(%d)", (int) max_length);
908  answer->append(buff, (uint) strlen(buff));
909  if (min_arg >= 0)
910  answer->append(STRING_WITH_LEN(" UNSIGNED"));
911 
912  // if item is FIELD_ITEM, it _must_be_ Field_num in this class
913  if ((item->type() == Item::FIELD_ITEM) &&
914  // a single number shouldn't be zerofill
915  max_length != 1 &&
916  ((Field_num*) ((Item_field*) item)->field)->zerofill)
917  answer->append(STRING_WITH_LEN(" ZEROFILL"));
918 } // field_longlong::get_opt_type
919 
920 
921 void field_ulonglong::get_opt_type(String *answer,
922  ha_rows total_rows __attribute__((unused)))
923 {
924  char buff[MAX_FIELD_WIDTH];
925 
926  if (max_arg < 256)
927  sprintf(buff, "TINYINT(%d) UNSIGNED", (int) max_length);
928  else if (max_arg <= ((2 * INT_MAX16) + 1))
929  sprintf(buff, "SMALLINT(%d) UNSIGNED", (int) max_length);
930  else if (max_arg <= ((2 * INT_MAX24) + 1))
931  sprintf(buff, "MEDIUMINT(%d) UNSIGNED", (int) max_length);
932  else if (max_arg < (((ulonglong) 1) << 32))
933  sprintf(buff, "INT(%d) UNSIGNED", (int) max_length);
934  else
935  sprintf(buff, "BIGINT(%d) UNSIGNED", (int) max_length);
936  // if item is FIELD_ITEM, it _must_be_ Field_num in this class
937  answer->append(buff, (uint) strlen(buff));
938  if (item->type() == Item::FIELD_ITEM &&
939  // a single number shouldn't be zerofill
940  max_length != 1 &&
941  ((Field_num*) ((Item_field*) item)->field)->zerofill)
942  answer->append(STRING_WITH_LEN(" ZEROFILL"));
943 } //field_ulonglong::get_opt_type
944 
945 
946 void field_decimal::get_opt_type(String *answer,
947  ha_rows total_rows __attribute__((unused)))
948 {
949  my_decimal zero;
950  char buff[MAX_FIELD_WIDTH];
951  uint length;
952 
953  my_decimal_set_zero(&zero);
954  my_bool is_unsigned= (my_decimal_cmp(&zero, &min_arg) >= 0);
955 
956  length= my_snprintf(buff, sizeof(buff), "DECIMAL(%d, %d)",
957  (int) (max_length - (item->decimals ? 1 : 0)),
958  item->decimals);
959  if (is_unsigned)
960  length= (uint) (strmov(buff+length, " UNSIGNED")- buff);
961  answer->append(buff, length);
962 }
963 
964 
965 String *field_decimal::get_min_arg(String *str)
966 {
967  my_decimal2string(E_DEC_FATAL_ERROR, &min_arg, 0, 0, '0', str);
968  return str;
969 }
970 
971 
972 String *field_decimal::get_max_arg(String *str)
973 {
974  my_decimal2string(E_DEC_FATAL_ERROR, &max_arg, 0, 0, '0', str);
975  return str;
976 }
977 
978 
979 String *field_decimal::avg(String *s, ha_rows rows)
980 {
981  if (!(rows - nulls))
982  {
983  s->set_real((double) 0.0, 1,my_thd_charset);
984  return s;
985  }
986  my_decimal num, avg_val, rounded_avg;
987  int prec_increment= current_thd->variables.div_precincrement;
988 
989  int2my_decimal(E_DEC_FATAL_ERROR, rows - nulls, FALSE, &num);
990  my_decimal_div(E_DEC_FATAL_ERROR, &avg_val, sum+cur_sum, &num, prec_increment);
991  /* TODO remove this after decimal_div returns proper frac */
992  my_decimal_round(E_DEC_FATAL_ERROR, &avg_val,
993  min(sum[cur_sum].frac + prec_increment, DECIMAL_MAX_SCALE),
994  FALSE,&rounded_avg);
995  my_decimal2string(E_DEC_FATAL_ERROR, &rounded_avg, 0, 0, '0', s);
996  return s;
997 }
998 
999 
1000 String *field_decimal::std(String *s, ha_rows rows)
1001 {
1002  if (!(rows - nulls))
1003  {
1004  s->set_real((double) 0.0, 1,my_thd_charset);
1005  return s;
1006  }
1007  my_decimal num, tmp, sum2, sum2d;
1008  double std_sqr;
1009  int prec_increment= current_thd->variables.div_precincrement;
1010 
1011  int2my_decimal(E_DEC_FATAL_ERROR, rows - nulls, FALSE, &num);
1012  my_decimal_mul(E_DEC_FATAL_ERROR, &sum2, sum+cur_sum, sum+cur_sum);
1013  my_decimal_div(E_DEC_FATAL_ERROR, &tmp, &sum2, &num, prec_increment);
1014  my_decimal_sub(E_DEC_FATAL_ERROR, &sum2, sum_sqr+cur_sum, &tmp);
1015  my_decimal_div(E_DEC_FATAL_ERROR, &tmp, &sum2, &num, prec_increment);
1016  my_decimal2double(E_DEC_FATAL_ERROR, &tmp, &std_sqr);
1017  s->set_real(((double) std_sqr <= 0.0 ? 0.0 : sqrt(std_sqr)),
1018  min(item->decimals + prec_increment, NOT_FIXED_DEC), my_thd_charset);
1019 
1020  return s;
1021 }
1022 
1023 
1024 int collect_string(String *element,
1025  element_count count __attribute__((unused)),
1026  TREE_INFO *info)
1027 {
1028  if (info->found)
1029  info->str->append(',');
1030  else
1031  info->found = 1;
1032  info->str->append('\'');
1033  if (append_escaped(info->str, element))
1034  return 1;
1035  info->str->append('\'');
1036  return 0;
1037 } // collect_string
1038 
1039 
1040 int collect_real(double *element, element_count count __attribute__((unused)),
1041  TREE_INFO *info)
1042 {
1043  char buff[MAX_FIELD_WIDTH];
1044  String s(buff, sizeof(buff),current_thd->charset());
1045 
1046  if (info->found)
1047  info->str->append(',');
1048  else
1049  info->found = 1;
1050  info->str->append('\'');
1051  s.set_real(*element, info->item->decimals, current_thd->charset());
1052  info->str->append(s);
1053  info->str->append('\'');
1054  return 0;
1055 } // collect_real
1056 
1057 
1058 int collect_decimal(uchar *element, element_count count,
1059  TREE_INFO *info)
1060 {
1061  char buff[DECIMAL_MAX_STR_LENGTH + 1];
1062  String s(buff, sizeof(buff),&my_charset_bin);
1063 
1064  if (info->found)
1065  info->str->append(',');
1066  else
1067  info->found = 1;
1068  my_decimal dec;
1069  binary2my_decimal(E_DEC_FATAL_ERROR, element, &dec,
1070  info->item->max_length, info->item->decimals);
1071 
1072  info->str->append('\'');
1073  my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, '0', &s);
1074  info->str->append(s);
1075  info->str->append('\'');
1076  return 0;
1077 }
1078 
1079 
1080 int collect_longlong(longlong *element,
1081  element_count count __attribute__((unused)),
1082  TREE_INFO *info)
1083 {
1084  char buff[MAX_FIELD_WIDTH];
1085  String s(buff, sizeof(buff),&my_charset_bin);
1086 
1087  if (info->found)
1088  info->str->append(',');
1089  else
1090  info->found = 1;
1091  info->str->append('\'');
1092  s.set(*element, current_thd->charset());
1093  info->str->append(s);
1094  info->str->append('\'');
1095  return 0;
1096 } // collect_longlong
1097 
1098 
1099 int collect_ulonglong(ulonglong *element,
1100  element_count count __attribute__((unused)),
1101  TREE_INFO *info)
1102 {
1103  char buff[MAX_FIELD_WIDTH];
1104  String s(buff, sizeof(buff),&my_charset_bin);
1105 
1106  if (info->found)
1107  info->str->append(',');
1108  else
1109  info->found = 1;
1110  info->str->append('\'');
1111  s.set(*element, current_thd->charset());
1112  info->str->append(s);
1113  info->str->append('\'');
1114  return 0;
1115 } // collect_ulonglong
1116 
1117 
1121 bool select_analyse::change_columns()
1122 {
1123  func_items[0] = new Item_proc_string("Field_name", 255);
1124  func_items[1] = new Item_proc_string("Min_value", 255);
1125  func_items[1]->maybe_null = 1;
1126  func_items[2] = new Item_proc_string("Max_value", 255);
1127  func_items[2]->maybe_null = 1;
1128  func_items[3] = new Item_proc_int("Min_length");
1129  func_items[4] = new Item_proc_int("Max_length");
1130  func_items[5] = new Item_proc_int("Empties_or_zeros");
1131  func_items[6] = new Item_proc_int("Nulls");
1132  func_items[7] = new Item_proc_string("Avg_value_or_avg_length", 255);
1133  func_items[8] = new Item_proc_string("Std", 255);
1134  func_items[8]->maybe_null = 1;
1135  func_items[9] = new Item_proc_string("Optimal_fieldtype",
1136  max(64U, output_str_length));
1137  result_fields.empty();
1138  for (uint i = 0; i < array_elements(func_items); i++)
1139  {
1140  if (func_items[i] == NULL)
1141  return true;
1142  result_fields.push_back(func_items[i]);
1143  }
1144  return false;
1145 } // select_analyse::change_columns
1146 
1147 
1148 void select_analyse::cleanup()
1149 {
1150  if (f_info)
1151  {
1152  for (field_info **f= f_info; f != f_end; f++)
1153  delete (*f);
1154  f_info= f_end= NULL;
1155  }
1156  rows= 0;
1157  output_str_length= 0;
1158 }
1159 
1160 
1161 bool select_analyse::send_result_set_metadata(List<Item> &fields, uint flag)
1162 {
1163  return (init(fields) || change_columns() ||
1164  result->send_result_set_metadata(result_fields, flag));
1165 }
1166 
1167 
1168 void select_analyse::abort_result_set()
1169 {
1170  cleanup();
1171  return result->abort_result_set();
1172 }
1173 
1174 
1175 int compare_double(const double *s, const double *t)
1176 {
1177  return ((*s < *t) ? -1 : *s > *t ? 1 : 0);
1178 } /* compare_double */
1179 
1180 int compare_longlong(const longlong *s, const longlong *t)
1181 {
1182  return ((*s < *t) ? -1 : *s > *t ? 1 : 0);
1183 } /* compare_longlong */
1184 
1185  int compare_ulonglong(const ulonglong *s, const ulonglong *t)
1186 {
1187  return ((*s < *t) ? -1 : *s > *t ? 1 : 0);
1188 } /* compare_ulonglong */
1189 
1190 
1191 uint check_ulonglong(const char *str, uint length)
1192 {
1193  const char *long_str = "2147483647", *ulonglong_str = "18446744073709551615";
1194  const uint long_len = 10, ulonglong_len = 20;
1195 
1196  while (*str == '0' && length)
1197  {
1198  str++; length--;
1199  }
1200  if (length < long_len)
1201  return NUM;
1202 
1203  uint smaller, bigger;
1204  const char *cmp;
1205 
1206  if (length == long_len)
1207  {
1208  cmp = long_str;
1209  smaller = NUM;
1210  bigger = LONG_NUM;
1211  }
1212  else if (length > ulonglong_len)
1213  return DECIMAL_NUM;
1214  else
1215  {
1216  cmp = ulonglong_str;
1217  smaller = LONG_NUM;
1218  bigger = DECIMAL_NUM;
1219  }
1220  while (*cmp && *cmp++ == *str++) ;
1221  return ((uchar) str[-1] <= (uchar) cmp[-1]) ? smaller : bigger;
1222 } /* check_ulonlong */
1223 
1224 
1225 /*
1226  Quote special characters in a string.
1227 
1228  SYNOPSIS
1229  append_escaped(to_str, from_str)
1230  to_str (in) A pointer to a String.
1231  from_str (to) A pointer to an allocated string
1232 
1233  DESCRIPTION
1234  append_escaped() takes a String type variable, where it appends
1235  escaped the second argument. Only characters that require escaping
1236  will be escaped.
1237 
1238  RETURN VALUES
1239  0 Success
1240  1 Out of memory
1241 */
1242 
1243 bool append_escaped(String *to_str, String *from_str)
1244 {
1245  char *from, *end, c;
1246 
1247  if (to_str->realloc(to_str->length() + from_str->length()))
1248  return 1;
1249 
1250  from= (char*) from_str->ptr();
1251  end= from + from_str->length();
1252  for (; from < end; from++)
1253  {
1254  c= *from;
1255  switch (c) {
1256  case '\0':
1257  c= '0';
1258  break;
1259  case '\032':
1260  c= 'Z';
1261  break;
1262  case '\\':
1263  case '\'':
1264  break;
1265  default:
1266  goto normal_character;
1267  }
1268  if (to_str->append('\\'))
1269  return 1;
1270 
1271  normal_character:
1272  if (to_str->append(c))
1273  return 1;
1274  }
1275  return 0;
1276 }
1277