home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 January / Chip_2001-01_cd1.bin / tema / mysql / mysql-3.23.28g-win-source.exe / sql / field.cpp < prev    next >
C/C++ Source or Header  |  2000-10-25  |  101KB  |  4,664 lines

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    
  3.    This program is free software; you can redistribute it and/or modify
  4.    it under the terms of the GNU General Public License as published by
  5.    the Free Software Foundation; either version 2 of the License, or
  6.    (at your option) any later version.
  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
  15.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  16.  
  17.  
  18. /*
  19.   NOTES:
  20.   Some of the number class uses the system functions strtol(), strtoll()...
  21.   To avoid patching the end \0 or copying the buffer unnecessary, all calls
  22.   to system functions are wrapped to a String object that adds the end null
  23.   if it only if it isn't there.
  24.   This adds some overhead when assigning numbers from strings but makes
  25.   everything simpler.
  26.   */
  27.  
  28. /*****************************************************************************
  29. ** This file implements classes defined in field.h
  30. *****************************************************************************/
  31.  
  32. #ifdef __GNUC__
  33. #pragma implementation                // gcc: Class implementation
  34. #endif
  35.  
  36. #include "mysql_priv.h"
  37. #include "sql_select.h"
  38. #include <m_ctype.h>
  39. #include <errno.h>
  40. #ifdef HAVE_FCONVERT
  41. #include <floatingpoint.h>
  42. #endif
  43.  
  44. /*****************************************************************************
  45. ** Instansiate templates and static variables
  46. *****************************************************************************/
  47.  
  48. #ifdef __GNUC__
  49. template class List<create_field>;
  50. template class List_iterator<create_field>;
  51. #endif
  52.  
  53. struct st_decstr {
  54.   uint nr_length,nr_dec,sign,extra;
  55.   char sign_char;
  56. };
  57.  
  58. uchar Field_null::null[1]={1};
  59. const char field_separator=',';
  60.  
  61. /*****************************************************************************
  62. ** Static help functions
  63. *****************************************************************************/
  64.  
  65.     /*
  66.     ** Calculate length of number and it's parts
  67.     ** Increment cuted_fields if wrong number
  68.     */
  69.  
  70. static bool
  71. number_dec(struct st_decstr *sdec, const char *str, const char *end)
  72. {
  73.   sdec->sign=sdec->extra=0;
  74.   if (str == end)
  75.   {
  76.     current_thd->cuted_fields++;
  77.     sdec->nr_length=sdec->nr_dec=sdec->sign=0;
  78.     sdec->extra=1;                // We must put one 0 before .
  79.     return 1;
  80.   }
  81.  
  82.   if (*str == '-' || *str == '+')        /* sign */
  83.   {
  84.     sdec->sign_char= *str;
  85.     sdec->sign=1;
  86.     str++;
  87.   }
  88.   const char *start=str;
  89.   while (str != end && isdigit(*str))
  90.     str++;
  91.   if (!(sdec->nr_length=(uint) (str-start)))
  92.     sdec->extra=1;                // We must put one 0 before .
  93.   start=str;
  94.   if (str != end && *str == '.')
  95.   {
  96.     str++;
  97.     start=str;
  98.     while (str != end && isdigit(*str))
  99.       str++;
  100.   }
  101.   sdec->nr_dec=(uint) (str-start);
  102.   if (current_thd->count_cuted_fields)
  103.   {
  104.     while (str != end && isspace(*str))
  105.       str++; /* purecov: inspected */
  106.     if (str != end)
  107.     {
  108.       current_thd->cuted_fields++;
  109.       return 1;
  110.     }
  111.   }
  112.   return 0;
  113. }
  114.  
  115.  
  116. void Field_num::prepend_zeros(String *value)
  117. {
  118.   int diff;
  119.   if ((diff= (int) (field_length - value->length())) > 0)
  120.   {
  121.     bmove_upp((char*) value->ptr()+field_length,value->ptr()+value->length(),
  122.           value->length());
  123.     bfill((char*) value->ptr(),diff,'0');
  124.     value->length(field_length);
  125.     (void) value->c_ptr_quick();        // Avoid warnings in purify
  126.   }
  127. }
  128.  
  129. /*
  130. ** Test if given number is a int (or a fixed format float with .000)
  131. ** This is only used to give warnings in ALTER TABLE or LOAD DATA...
  132. */
  133.  
  134. bool test_if_int(const char *str,int length)
  135. {
  136.   const char *end=str+length;
  137.  
  138.   while (str != end && isspace(*str))    // Allow start space
  139.     str++; /* purecov: inspected */
  140.   if (str != end && (*str == '-' || *str == '+'))
  141.     str++;
  142.   if (str == end)
  143.     return 0;                    // Error: Empty string
  144.   for ( ; str != end ; str++)
  145.   {
  146.     if (!isdigit(*str))
  147.     {
  148.       if (*str == '.')
  149.       {                        // Allow '.0000'
  150.     for (str++ ; str != end && *str == '0'; str++) ;
  151.     if (str == end)
  152.       return 1;
  153.       }
  154.       if (!isspace(*str))
  155.     return 0;
  156.       for (str++ ; str != end ; str++)
  157.     if (!isspace(*str))
  158.       return 0;
  159.       return 1;
  160.     }
  161.   }
  162.   return 1;
  163. }
  164.  
  165.  
  166. static bool test_if_real(const char *str,int length)
  167. {
  168.   while (length && isspace(*str))
  169.   {                        // Allow start space
  170.     length--; str++;
  171.   }
  172.   if (!length)
  173.     return 0;
  174.   if (*str == '+' || *str == '-')
  175.   {
  176.     length--; str++;
  177.     if (!length || !(isdigit(*str) || *str == '.'))
  178.       return 0;
  179.   }
  180.   while (length && isdigit(*str))
  181.   {
  182.     length--; str++;
  183.   }
  184.   if (!length)
  185.     return 1;
  186.   if (*str == '.')
  187.   {
  188.     length--; str++;
  189.     while (length && isdigit(*str))
  190.     {
  191.       length--; str++;
  192.     }
  193.   }
  194.   if (!length)
  195.     return 1;
  196.   if (*str == 'E' || *str == 'e')
  197.   {
  198.     if (length < 3 || (str[1] != '+' && str[1] != '-') || !isdigit(str[2]))
  199.       return 0;
  200.     length-=3;
  201.     str+=3;
  202.     while (length && isdigit(*str))
  203.     {
  204.       length--; str++;
  205.     }
  206.   }
  207.   for ( ; length ; length--, str++)
  208.   {                        // Allow end space
  209.     if (!isspace(*str))
  210.       return 0;
  211.   }
  212.   return 1;
  213. }
  214.  
  215.  
  216. /****************************************************************************
  217. ** Functions for the base classes
  218. ** This is a unpacked number.
  219. ****************************************************************************/
  220.  
  221. Field::Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
  222.          uint null_bit_arg,
  223.          utype unireg_check_arg, const char *field_name_arg,
  224.          struct st_table *table_arg)
  225.   :ptr(ptr_arg),null_ptr(null_ptr_arg),null_bit(null_bit_arg),
  226.    table(table_arg),query_id(0),key_start(0),part_of_key(0),
  227.    table_name(table_arg ? table_arg->table_name : 0),
  228.    field_name(field_name_arg), unireg_check(unireg_check_arg),
  229.    field_length(length_arg)
  230. {
  231.   flags=null_ptr ? 0: NOT_NULL_FLAG;
  232. }
  233.  
  234. uint Field::offset()
  235. {
  236.   return (uint) (ptr - (char*) table->record[0]);
  237. }
  238.  
  239.  
  240. void Field::copy_from_tmp(int row_offset)
  241. {
  242.   memcpy(ptr,ptr+row_offset,pack_length());
  243.   if (null_ptr)
  244.   {
  245.     *null_ptr= ((null_ptr[0] & (uchar) ~(uint) null_bit) |
  246.         null_ptr[row_offset] & (uchar) null_bit);
  247.   }
  248. }
  249.  
  250.  
  251. bool Field::send(String *packet)
  252. {
  253.   if (is_null())
  254.     return net_store_null(packet);
  255.   char buff[MAX_FIELD_WIDTH];
  256.   String tmp(buff,sizeof(buff));
  257.   val_str(&tmp,&tmp);
  258.   CONVERT *convert;
  259.   if ((convert=current_thd->convert_set))
  260.     return convert->store(packet,tmp.ptr(),tmp.length());
  261.   return net_store_data(packet,tmp.ptr(),tmp.length());
  262. }
  263.  
  264.  
  265. void Field_num::add_zerofill_and_unsigned(String &res) const
  266. {
  267.   res.length((uint) strlen(res.ptr()));        // Fix length
  268.   if (unsigned_flag)
  269.     res.append(" unsigned");
  270.   if (zerofill)
  271.     res.append(" zerofill");
  272. }
  273.  
  274. void Field_num::make_field(Send_field *field)
  275. {
  276.   field->table_name=table_name;
  277.   field->col_name=field_name;
  278.   field->length=field_length;
  279.   field->type=type();
  280.   field->flags=table->maybe_null ? (flags & ~NOT_NULL_FLAG) : flags;
  281.   field->decimals=dec;
  282. }
  283.  
  284.  
  285. void Field_str::make_field(Send_field *field)
  286. {
  287.   field->table_name=table_name;
  288.   field->col_name=field_name;
  289.   field->length=field_length;
  290.   field->type=type();
  291.   field->flags=table->maybe_null ? (flags & ~NOT_NULL_FLAG) : flags;
  292.   field->decimals=0;
  293. }
  294.  
  295.  
  296. uint Field::fill_cache_field(CACHE_FIELD *copy)
  297. {
  298.   copy->str=ptr;
  299.   copy->length=pack_length();
  300.   copy->blob_field=0;
  301.   if (flags & BLOB_FLAG)
  302.   {
  303.     copy->blob_field=(Field_blob*) this;
  304.     copy->strip=0;
  305.     copy->length-=table->blob_ptr_size;
  306.     return copy->length;
  307.   }
  308.   else if (!zero_pack() && (type() == FIELD_TYPE_STRING && copy->length > 4 ||
  309.                 type() == FIELD_TYPE_VAR_STRING))
  310.     copy->strip=1;                /* Remove end space */
  311.   else
  312.     copy->strip=0;
  313.   return copy->length+(int) copy->strip;
  314. }
  315.  
  316. bool Field::get_date(TIME *ltime,bool fuzzydate)
  317. {
  318.   char buff[40];
  319.   String tmp(buff,sizeof(buff)),tmp2,*res;
  320.   if (!(res=val_str(&tmp,&tmp2)) ||
  321.       str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate) == TIMESTAMP_NONE)
  322.     return 1;
  323.   return 0;
  324. }
  325.  
  326. bool Field::get_time(TIME *ltime)
  327. {
  328.   char buff[40];
  329.   String tmp(buff,sizeof(buff)),tmp2,*res;
  330.   if (!(res=val_str(&tmp,&tmp2)) ||
  331.       str_to_time(res->ptr(),res->length(),ltime) == TIMESTAMP_NONE)
  332.     return 1;
  333.   return 0;
  334. }
  335.  
  336.  
  337. /* This is called when storing a date in a string */
  338. void Field::store_time(TIME *ltime,timestamp_type type)
  339. {
  340.   char buff[25];
  341.   switch (type)  {
  342.   case TIMESTAMP_NONE:
  343.     store("",0);            // Probably an error
  344.     break;
  345.   case TIMESTAMP_DATE:
  346.     sprintf(buff,"%04d-%02d-%02d", ltime->year,ltime->month,ltime->day);
  347.     store(buff,10);
  348.     break;
  349.   case TIMESTAMP_FULL:
  350.     sprintf(buff,"%04d-%02d-%02d %02d:%02d:%02d",
  351.         ltime->year,ltime->month,ltime->day,
  352.         ltime->hour,ltime->minute,ltime->second);
  353.     store(buff,19);
  354.     break;
  355.   case TIMESTAMP_TIME:
  356.     sprintf(buff, "%02d:%02d:%02d",
  357.         ltime->hour,ltime->minute,ltime->second);
  358.     store(buff,(uint) strlen(buff));
  359.     break;
  360.   }
  361. }
  362.  
  363.  
  364. bool Field::optimize_range()
  365. {
  366.   return test(table->file->option_flag() & HA_READ_NEXT);
  367. }
  368.  
  369. /****************************************************************************
  370. ** Functions for the Field_decimal class
  371. ** This is a unpacked number.
  372. ****************************************************************************/
  373.  
  374. void
  375. Field_decimal::reset(void)
  376. {
  377.   Field_decimal::store("0",1);
  378. }
  379.  
  380. void Field_decimal::overflow(bool negative)
  381. {
  382.   uint len=field_length;
  383.   char *to=ptr;
  384.   if (negative && !unsigned_flag)
  385.   {
  386.     *to++ = '-';
  387.     len--;
  388.   }
  389.   bfill(to,len,negative && unsigned_flag ? '0' : '9');
  390.   if (dec)
  391.     ptr[field_length-dec-1]='.';
  392.   return;
  393. }
  394.  
  395.  
  396. void Field_decimal::store(const char *from,uint len)
  397. {
  398.   reg3 int i;
  399.   uint tmp_dec;
  400.   char fyllchar;
  401.   const char *end=from+len;
  402.   struct st_decstr decstr;
  403.   bool error;
  404.  
  405.   if ((tmp_dec= dec))
  406.     tmp_dec++;                    // Calculate pos of '.'
  407.   while (from != end && isspace(*from))
  408.     from++;
  409.   if (zerofill)
  410.   {
  411.     fyllchar = '0';
  412.     if (from != end)
  413.       while (*from == '0' && from != end-1)    // Skipp prezero
  414.     from++;
  415.   }
  416.   else
  417.     fyllchar=' ';
  418.   error=number_dec(&decstr,from,end);
  419.   if (decstr.sign)
  420.   {
  421.     from++;
  422.     if (unsigned_flag)                // No sign with zerofill
  423.     {
  424.       if (!error)
  425.     current_thd->cuted_fields++;
  426.       Field_decimal::overflow(1);
  427.       return;
  428.     }
  429.   }
  430.   /*
  431.   ** Remove pre-zeros if too big number
  432.   */
  433.   for (i= (int) (decstr.nr_length+decstr.extra -(field_length-tmp_dec)+
  434.          decstr.sign) ;
  435.        i > 0 ;
  436.        i--)
  437.   {
  438.     if (*from == '0')
  439.     {
  440.       from++;
  441.       decstr.nr_length--;
  442.       continue;
  443.     }
  444.     if (decstr.sign && decstr.sign_char == '+' && i == 1)
  445.     {                        // Remove pre '+'
  446.       decstr.sign=0;
  447.       break;
  448.     }
  449.     current_thd->cuted_fields++;
  450.     // too big number, change to max or min number
  451.     Field_decimal::overflow(decstr.sign && decstr.sign_char == '-');
  452.     return;
  453.   }
  454.   char *to=ptr;
  455.   for (i=(int) (field_length-tmp_dec-decstr.nr_length-decstr.extra - decstr.sign) ;
  456.        i-- > 0 ;)
  457.     *to++ = fyllchar;
  458.   if (decstr.sign)
  459.     *to++= decstr.sign_char;
  460.   if (decstr.extra)
  461.     *to++ = '0';
  462.   for (i=(int) decstr.nr_length ; i-- > 0 ; )
  463.     *to++ = *from++;
  464.   if (tmp_dec--)
  465.   {
  466.     *to++ ='.';
  467.     if (decstr.nr_dec) from++;            // Skipp '.'
  468.     for (i=(int) min(decstr.nr_dec,tmp_dec) ; i-- > 0 ; ) *to++ = *from++;
  469.     for (i=(int) (tmp_dec-min(decstr.nr_dec,tmp_dec)) ; i-- > 0 ; ) *to++ = '0';
  470.   }
  471.  
  472.   /*
  473.   ** Check for incorrect string if in batch mode (ALTER TABLE/LOAD DATA...)
  474.   */
  475.   if (!error && current_thd->count_cuted_fields && from != end)
  476.   {                        // Check if number was cuted
  477.     for (; from != end ; from++)
  478.     {
  479.       if (*from != '0')
  480.       {
  481.     if (!isspace(*from))            // Space is ok
  482.       current_thd->cuted_fields++;
  483.     break;
  484.       }
  485.     }
  486.   }
  487. }
  488.  
  489.  
  490. void Field_decimal::store(double nr)
  491. {
  492.   if (unsigned_flag && nr < 0)
  493.   {
  494.     overflow(1);
  495.     current_thd->cuted_fields++;
  496.     return;
  497.   }
  498.   reg4 uint i,length;
  499.   char fyllchar,*to;
  500.   char buff[320];
  501.  
  502.   fyllchar = zerofill ? (char) '0' : (char) ' ';
  503. #ifdef HAVE_SNPRINTF_
  504.   buff[sizeof(buff)-1]=0;            // Safety
  505.   snprintf(buff,sizeof(buff)-1, "%.*f",(int) dec,nr);
  506. #else
  507.   sprintf(buff,"%.*f",dec,nr);
  508. #endif
  509.   length=(uint) strlen(buff);
  510.  
  511.   if (length > field_length)
  512.   {
  513.     overflow(nr < 0.0);
  514.     current_thd->cuted_fields++;
  515.   }
  516.   else
  517.   {
  518.     to=ptr;
  519.     for (i=field_length-length ; i-- > 0 ;)
  520.       *to++ = fyllchar;
  521.     memcpy(to,buff,length);
  522.   }
  523. }
  524.  
  525.  
  526. void Field_decimal::store(longlong nr)
  527. {
  528.   if (unsigned_flag && nr < 0)
  529.   {
  530.     overflow(1);
  531.     current_thd->cuted_fields++;
  532.     return;
  533.   }
  534.   char buff[22];
  535.   uint length=(uint) (longlong10_to_str(nr,buff,-10)-buff);
  536.   uint int_part=field_length- (dec  ? dec+1 : 0);
  537.  
  538.   if (length > int_part)
  539.   {
  540.     overflow(test(nr < 0L));            /* purecov: inspected */
  541.     current_thd->cuted_fields++;        /* purecov: inspected */
  542.   }
  543.   else
  544.   {
  545.     char fyllchar = zerofill ? (char) '0' : (char) ' ';
  546.     char *to=ptr;
  547.     for (uint i=int_part-length ; i-- > 0 ;)
  548.       *to++ = fyllchar;
  549.     memcpy(to,buff,length);
  550.     if (dec)
  551.     {
  552.       to[length]='.';
  553.       bfill(to+length+1,dec,'0');
  554.     }
  555.   }
  556. }
  557.  
  558.  
  559. double Field_decimal::val_real(void)
  560. {
  561.   char temp= *(ptr+field_length); *(ptr+field_length) = '\0';
  562.   double nr=atod(ptr);
  563.   *(ptr+field_length)=temp;
  564.   return(nr);
  565. }
  566.  
  567. longlong Field_decimal::val_int(void)
  568. {
  569.   char temp= *(ptr+field_length); *(ptr+field_length) = '\0';
  570.   longlong nr;
  571.   if (unsigned_flag)
  572.     nr=(longlong) strtoull(ptr,NULL,10);
  573.   else
  574.     nr=strtoll(ptr,NULL,10);
  575.   *(ptr+field_length)=temp;
  576.   return(nr);
  577. }
  578.  
  579. String *Field_decimal::val_str(String *val_buffer __attribute__((unused)),
  580.                    String *val_ptr)
  581. {
  582.   char *str;
  583.   for (str=ptr ; *str == ' ' ; str++) ;
  584.   uint tmp_length=(uint) (str-ptr);
  585.   if (field_length < tmp_length)        // Error in data
  586.     val_ptr->length(0);
  587.   else
  588.     val_ptr->set((const char*) str,field_length-tmp_length);
  589.   return val_ptr;
  590. }
  591.  
  592. /*
  593. ** Should be able to handle at least the following fixed decimal formats:
  594. ** 5.00 , -1.0,  05,  -05, +5 with optional pre/end space
  595. */
  596.  
  597. int Field_decimal::cmp(const char *a_ptr,const char *b_ptr)
  598. {
  599.   const char *end;
  600.   /* First remove prefixes '0', ' ', and '-' */
  601.   for (end=a_ptr+field_length;
  602.        a_ptr != end &&
  603.      (*a_ptr == *b_ptr ||
  604.       ((isspace(*a_ptr)  || *a_ptr == '+' || *a_ptr == '0') &&
  605.        (isspace(*b_ptr) || *b_ptr == '+' || *b_ptr == '0')));
  606.        a_ptr++,b_ptr++) ;
  607.  
  608.   if (a_ptr == end)
  609.     return 0;
  610.   int swap=0;
  611.   if (*a_ptr == '-')
  612.   {
  613.     if (*b_ptr != '-')
  614.       return -1;
  615.     swap= -1 ^ 1;                // Swap result
  616.     a_ptr++, b_ptr++;
  617.   } else if (*b_ptr == '-')
  618.     return 1;
  619.  
  620.   while (a_ptr != end)
  621.   {
  622.     if (*a_ptr++ != *b_ptr++)
  623.       return swap ^ (a_ptr[-1] < b_ptr[-1] ? -1 : 1); // compare digits
  624.   }
  625.   return 0;
  626. }
  627.  
  628.  
  629. void Field_decimal::sort_string(char *to,uint length)
  630. {
  631.   char *str,*end;
  632.   for (str=ptr,end=ptr+length;
  633.        str != end &&
  634.      ((isspace(*str) || *str == '+' || *str == '0')) ;
  635.  
  636.        str++)
  637.     *to++=' ';
  638.   if (str == end)
  639.     return;                    /* purecov: inspected */
  640.  
  641.   if (*str == '-')
  642.   {
  643.     *to++=1;                    // Smaller than any number
  644.     str++;
  645.     while (str != end)
  646.       if (isdigit(*str))
  647.     *to++= (char) ('9' - *str++);
  648.       else
  649.     *to++= *str++;
  650.   }
  651.   else memcpy(to,str,(uint) (end-str));
  652. }
  653.  
  654. void Field_decimal::sql_type(String &res) const
  655. {
  656.   uint tmp=field_length;
  657.   if (!unsigned_flag)
  658.     tmp--;
  659.   if (dec)
  660.     tmp--;
  661.   sprintf((char*) res.ptr(),"decimal(%d,%d)",tmp,dec);
  662.   add_zerofill_and_unsigned(res);
  663. }
  664.  
  665.  
  666. /****************************************************************************
  667. ** tiny int
  668. ****************************************************************************/
  669.  
  670. void Field_tiny::store(const char *from,uint len)
  671. {
  672.   String tmp_str(from,len);
  673.   long tmp= strtol(tmp_str.c_ptr(),NULL,10);
  674.  
  675.   if (unsigned_flag)
  676.   {
  677.     if (tmp < 0)
  678.     {
  679.       tmp=0; /* purecov: inspected */
  680.       current_thd->cuted_fields++; /* purecov: inspected */
  681.     }
  682.     else if (tmp > 255)
  683.     {
  684.       tmp= 255;
  685.       current_thd->cuted_fields++;
  686.     }
  687.     else if (current_thd->count_cuted_fields && !test_if_int(from,len))
  688.       current_thd->cuted_fields++;
  689.   }
  690.   else
  691.   {
  692.     if (tmp < -128)
  693.     {
  694.       tmp= -128;
  695.       current_thd->cuted_fields++;
  696.     }
  697.     else if (tmp >= 128)
  698.     {
  699.       tmp= 127;
  700.       current_thd->cuted_fields++;
  701.     }
  702.     else if (current_thd->count_cuted_fields && !test_if_int(from,len))
  703.       current_thd->cuted_fields++;
  704.   }
  705.   ptr[0]= (char) tmp;
  706. }
  707.  
  708.  
  709. void Field_tiny::store(double nr)
  710. {
  711.   nr=rint(nr);
  712.   if (unsigned_flag)
  713.   {
  714.     if (nr < 0.0)
  715.     {
  716.       *ptr=0;
  717.       current_thd->cuted_fields++;
  718.     }
  719.     else if (nr > 255.0)
  720.     {
  721.       *ptr=(char) 255;
  722.       current_thd->cuted_fields++;
  723.     }
  724.     else
  725.       *ptr=(char) nr;
  726.   }
  727.   else
  728.   {
  729.     if (nr < -128.0)
  730.     {
  731.       *ptr= (char) -128;
  732.       current_thd->cuted_fields++;
  733.     }
  734.     else if (nr > 127.0)
  735.     {
  736.       *ptr=127;
  737.       current_thd->cuted_fields++;
  738.     }
  739.     else
  740.       *ptr=(char) nr;
  741.   }
  742. }
  743.  
  744. void Field_tiny::store(longlong nr)
  745. {
  746.   if (unsigned_flag)
  747.   {
  748.     if (nr < 0L)
  749.     {
  750.       *ptr=0;
  751.       current_thd->cuted_fields++;
  752.     }
  753.     else if (nr > 255L)
  754.     {
  755.       *ptr= (char) 255;
  756.       current_thd->cuted_fields++;
  757.     }
  758.     else
  759.       *ptr=(char) nr;
  760.   }
  761.   else
  762.   {
  763.     if (nr < -128L)
  764.     {
  765.       *ptr= (char) -128;
  766.       current_thd->cuted_fields++;
  767.     }
  768.     else if (nr > 127L)
  769.     {
  770.       *ptr=127;
  771.       current_thd->cuted_fields++;
  772.     }
  773.     else
  774.       *ptr=(char) nr;
  775.   }
  776. }
  777.  
  778.  
  779. double Field_tiny::val_real(void)
  780. {
  781.   int tmp= unsigned_flag ? (int) ((uchar*) ptr)[0] :
  782.     (int) ((signed char*) ptr)[0];
  783.   return (double) tmp;
  784. }
  785.  
  786. longlong Field_tiny::val_int(void)
  787. {
  788.   int tmp= unsigned_flag ? (int) ((uchar*) ptr)[0] :
  789.     (int) ((signed char*) ptr)[0];
  790.   return (longlong) tmp;
  791. }
  792.  
  793. String *Field_tiny::val_str(String *val_buffer,
  794.                 String *val_ptr __attribute__((unused)))
  795. {
  796.   uint length;
  797.   val_buffer->alloc(max(field_length+1,5));
  798.   char *to=(char*) val_buffer->ptr();
  799.   if (unsigned_flag)
  800.     length= (uint) (int10_to_str((long) *((uchar*) ptr),to,10)-to);
  801.   else
  802.     length= (uint) (int10_to_str((long) *((signed char*) ptr),to,-10)-to);
  803.   val_buffer->length(length);
  804.   if (zerofill)
  805.     prepend_zeros(val_buffer);
  806.   return val_buffer;
  807. }
  808.  
  809.  
  810. int Field_tiny::cmp(const char *a_ptr, const char *b_ptr)
  811. {
  812.   signed char a,b;
  813.   a=(signed char) a_ptr[0]; b= (signed char) b_ptr[0];
  814.   if (unsigned_flag)
  815.     return ((uchar) a < (uchar) b) ? -1 : ((uchar) a > (uchar) b) ? 1 : 0;
  816.   return (a < b) ? -1 : (a > b) ? 1 : 0;
  817. }
  818.  
  819. void Field_tiny::sort_string(char *to,uint length __attribute__((unused)))
  820. {
  821.   if (unsigned_flag)
  822.     *to= *ptr;
  823.   else
  824.     to[0] = (char) ((uchar) ptr[0] ^ (uchar) 128);    /* Revers signbit */
  825. }
  826.  
  827. void Field_tiny::sql_type(String &res) const
  828. {
  829.   sprintf((char*) res.ptr(),"tinyint(%d)",(int) field_length);
  830.   add_zerofill_and_unsigned(res);
  831. }
  832.  
  833. /****************************************************************************
  834. ** short int
  835. ****************************************************************************/
  836.  
  837.  
  838. // Note:  Sometimes this should be fixed to use one strtol() to use
  839. // len and check for garbage after number.
  840.  
  841. void Field_short::store(const char *from,uint len)
  842. {
  843.   String tmp_str(from,len);
  844.   long tmp= strtol(tmp_str.c_ptr(),NULL,10);
  845.   if (unsigned_flag)
  846.   {
  847.     if (tmp < 0)
  848.     {
  849.       tmp=0;
  850.       current_thd->cuted_fields++;
  851.     }
  852.     else if (tmp > (uint16) ~0)
  853.     {
  854.       tmp=(uint16) ~0;
  855.       current_thd->cuted_fields++;
  856.     }
  857.     else if (current_thd->count_cuted_fields && !test_if_int(from,len))
  858.       current_thd->cuted_fields++;
  859.   }
  860.   else
  861.   {
  862.     if (tmp < INT_MIN16)
  863.     {
  864.       tmp= INT_MIN16;
  865.       current_thd->cuted_fields++;
  866.     }
  867.     else if (tmp > INT_MAX16)
  868.     {
  869.       tmp=INT_MAX16;
  870.       current_thd->cuted_fields++;
  871.     }
  872.     else if (current_thd->count_cuted_fields && !test_if_int(from,len))
  873.       current_thd->cuted_fields++;
  874.   }
  875. #ifdef WORDS_BIGENDIAN
  876.   if (table->db_low_byte_first)
  877.   {
  878.     int2store(ptr,tmp);
  879.   }
  880.   else
  881. #endif
  882.     shortstore(ptr,(short) tmp);
  883. }
  884.  
  885.  
  886. void Field_short::store(double nr)
  887. {
  888.   int16 res;
  889.   nr=rint(nr);
  890.   if (unsigned_flag)
  891.   {
  892.     if (nr < 0)
  893.     {
  894.       res=0;
  895.       current_thd->cuted_fields++;
  896.     }
  897.     else if (nr > (double) (uint16) ~0)
  898.     {
  899.       res=(int16) (uint16) ~0;
  900.       current_thd->cuted_fields++;
  901.     }
  902.     else
  903.       res=(int16) (uint16) nr;
  904.   }
  905.   else
  906.   {
  907.     if (nr < (double) INT_MIN16)
  908.     {
  909.       res=INT_MIN16;
  910.       current_thd->cuted_fields++;
  911.     }
  912.     else if (nr > (double) INT_MAX16)
  913.     {
  914.       res=INT_MAX16;
  915.       current_thd->cuted_fields++;
  916.     }
  917.     else
  918.       res=(int16) nr;
  919.   }
  920. #ifdef WORDS_BIGENDIAN
  921.   if (table->db_low_byte_first)
  922.   {
  923.     int2store(ptr,res);
  924.   }
  925.   else
  926. #endif
  927.     shortstore(ptr,res);
  928. }
  929.  
  930. void Field_short::store(longlong nr)
  931. {
  932.   int16 res;
  933.   if (unsigned_flag)
  934.   {
  935.     if (nr < 0L)
  936.     {
  937.       res=0;
  938.       current_thd->cuted_fields++;
  939.     }
  940.     else if (nr > (longlong) (uint16) ~0)
  941.     {
  942.       res=(int16) (uint16) ~0;
  943.       current_thd->cuted_fields++;
  944.     }
  945.     else
  946.       res=(int16) (uint16) nr;
  947.   }
  948.   else
  949.   {
  950.     if (nr < INT_MIN16)
  951.     {
  952.       res=INT_MIN16;
  953.       current_thd->cuted_fields++;
  954.     }
  955.     else if (nr > INT_MAX16)
  956.     {
  957.       res=INT_MAX16;
  958.       current_thd->cuted_fields++;
  959.     }
  960.     else
  961.       res=(int16) nr;
  962.   }
  963. #ifdef WORDS_BIGENDIAN
  964.   if (table->db_low_byte_first)
  965.   {
  966.     int2store(ptr,res);
  967.   }
  968.   else
  969. #endif
  970.     shortstore(ptr,res);
  971. }
  972.  
  973.  
  974. double Field_short::val_real(void)
  975. {
  976.   short j;
  977. #ifdef WORDS_BIGENDIAN
  978.   if (table->db_low_byte_first)
  979.     j=sint2korr(ptr);
  980.   else
  981. #endif
  982.     shortget(j,ptr);
  983.   return unsigned_flag ? (double) (unsigned short) j : (double) j;
  984. }
  985.  
  986. longlong Field_short::val_int(void)
  987. {
  988.   short j;
  989. #ifdef WORDS_BIGENDIAN
  990.   if (table->db_low_byte_first)
  991.     j=sint2korr(ptr);
  992.   else
  993. #endif
  994.     shortget(j,ptr);
  995.   return unsigned_flag ? (longlong) (unsigned short) j : (longlong) j;
  996. }
  997.  
  998. String *Field_short::val_str(String *val_buffer,
  999.                  String *val_ptr __attribute__((unused)))
  1000. {
  1001.   uint length;
  1002.   val_buffer->alloc(max(field_length+1,7));
  1003.   char *to=(char*) val_buffer->ptr();
  1004.   short j;
  1005. #ifdef WORDS_BIGENDIAN
  1006.   if (table->db_low_byte_first)
  1007.     j=sint2korr(ptr);
  1008.   else
  1009. #endif
  1010.     shortget(j,ptr);
  1011.  
  1012.   if (unsigned_flag)
  1013.     length=(uint) (int10_to_str((long) (uint16) j,to,10)-to);
  1014.   else
  1015.     length=(uint) (int10_to_str((long) j,to,-10)-to);
  1016.   val_buffer->length(length);
  1017.   if (zerofill)
  1018.     prepend_zeros(val_buffer);
  1019.   return val_buffer;
  1020. }
  1021.  
  1022.  
  1023. int Field_short::cmp(const char *a_ptr, const char *b_ptr)
  1024. {
  1025.   short a,b;
  1026. #ifdef WORDS_BIGENDIAN
  1027.   if (table->db_low_byte_first)
  1028.   {
  1029.     a=sint2korr(a_ptr);
  1030.     b=sint2korr(b_ptr);
  1031.   }
  1032.   else
  1033. #endif
  1034.   {
  1035.     shortget(a,a_ptr);
  1036.     shortget(b,b_ptr);
  1037.   }
  1038.  
  1039.   if (unsigned_flag)
  1040.     return ((unsigned short) a < (unsigned short) b) ? -1 :
  1041.     ((unsigned short) a > (unsigned short) b) ? 1 : 0;
  1042.   return (a < b) ? -1 : (a > b) ? 1 : 0;
  1043. }
  1044.  
  1045. void Field_short::sort_string(char *to,uint length __attribute__((unused)))
  1046. {
  1047. #ifdef WORDS_BIGENDIAN
  1048.   if (!table->db_low_byte_first)
  1049.   {
  1050.     if (unsigned_flag)
  1051.       to[0] = ptr[0];
  1052.     else
  1053.       to[0] = ptr[0] ^ 128;            /* Revers signbit */
  1054.     to[1]   = ptr[1];
  1055.   }
  1056.   else
  1057. #endif
  1058.   {
  1059.     if (unsigned_flag)
  1060.       to[0] = ptr[1];
  1061.     else
  1062.       to[0] = ptr[1] ^ 128;            /* Revers signbit */
  1063.     to[1]   = ptr[0];
  1064.   }
  1065. }
  1066.  
  1067. void Field_short::sql_type(String &res) const
  1068. {
  1069.   sprintf((char*) res.ptr(),"smallint(%d)",(int) field_length);
  1070.   add_zerofill_and_unsigned(res);
  1071. }
  1072.  
  1073.  
  1074. /****************************************************************************
  1075. ** medium int
  1076. ****************************************************************************/
  1077.  
  1078. // Note:  Sometimes this should be fixed to use one strtol() to use
  1079. // len and check for garbage after number.
  1080.  
  1081. void Field_medium::store(const char *from,uint len)
  1082. {
  1083.   String tmp_str(from,len);
  1084.   long tmp= strtol(tmp_str.c_ptr(),NULL,10);
  1085.  
  1086.   if (unsigned_flag)
  1087.   {
  1088.     if (tmp < 0)
  1089.     {
  1090.       tmp=0;
  1091.       current_thd->cuted_fields++;
  1092.     }
  1093.     else if (tmp >= (long) (1L << 24))
  1094.     {
  1095.       tmp=(long) (1L << 24)-1L;
  1096.       current_thd->cuted_fields++;
  1097.     }
  1098.     else if (current_thd->count_cuted_fields && !test_if_int(from,len))
  1099.       current_thd->cuted_fields++;
  1100.   }
  1101.   else
  1102.   {
  1103.     if (tmp < INT_MIN24)
  1104.     {
  1105.       tmp= INT_MIN24;
  1106.       current_thd->cuted_fields++;
  1107.     }
  1108.     else if (tmp > INT_MAX24)
  1109.     {
  1110.       tmp=INT_MAX24;
  1111.       current_thd->cuted_fields++;
  1112.     }
  1113.     else if (current_thd->count_cuted_fields && !test_if_int(from,len))
  1114.       current_thd->cuted_fields++;
  1115.   }
  1116.  
  1117.   int3store(ptr,tmp);
  1118. }
  1119.  
  1120.  
  1121. void Field_medium::store(double nr)
  1122. {
  1123.   nr=rint(nr);
  1124.   if (unsigned_flag)
  1125.   {
  1126.     if (nr < 0)
  1127.     {
  1128.       int3store(ptr,0);
  1129.       current_thd->cuted_fields++;
  1130.     }
  1131.     else if (nr >= (double) (long) (1L << 24))
  1132.     {
  1133.       ulong tmp=(ulong) (1L << 24)-1L;
  1134.       int3store(ptr,tmp);
  1135.       current_thd->cuted_fields++;
  1136.     }
  1137.     else
  1138.       int3store(ptr,(ulong) nr);
  1139.   }
  1140.   else
  1141.   {
  1142.     if (nr < (double) INT_MIN24)
  1143.     {
  1144.       long tmp=(long) INT_MIN24;
  1145.       int3store(ptr,tmp);
  1146.       current_thd->cuted_fields++;
  1147.     }
  1148.     else if (nr > (double) INT_MAX24)
  1149.     {
  1150.       long tmp=(long) INT_MAX24;
  1151.       int3store(ptr,tmp);
  1152.       current_thd->cuted_fields++;
  1153.     }
  1154.     else
  1155.       int3store(ptr,(long) nr);
  1156.   }
  1157. }
  1158.  
  1159. void Field_medium::store(longlong nr)
  1160. {
  1161.   if (unsigned_flag)
  1162.   {
  1163.     if (nr < 0L)
  1164.     {
  1165.       int3store(ptr,0);
  1166.       current_thd->cuted_fields++;
  1167.     }
  1168.     else if (nr >= (longlong) (long) (1L << 24))
  1169.     {
  1170.       long tmp=(long) (1L << 24)-1L;;
  1171.       int3store(ptr,tmp);
  1172.       current_thd->cuted_fields++;
  1173.     }
  1174.     else
  1175.       int3store(ptr,(ulong) nr);
  1176.   }
  1177.   else
  1178.   {
  1179.     if (nr < (longlong) INT_MIN24)
  1180.     {
  1181.       long tmp=(long) INT_MIN24;
  1182.       int3store(ptr,tmp);
  1183.       current_thd->cuted_fields++;
  1184.     }
  1185.     else if (nr > (longlong) INT_MAX24)
  1186.     {
  1187.       long tmp=(long) INT_MAX24;
  1188.       int3store(ptr,tmp);
  1189.       current_thd->cuted_fields++;
  1190.     }
  1191.     else
  1192.       int3store(ptr,(long) nr);
  1193.   }
  1194. }
  1195.  
  1196.  
  1197. double Field_medium::val_real(void)
  1198. {
  1199.   long j= unsigned_flag ? (long) uint3korr(ptr) : sint3korr(ptr);
  1200.   return (double) j;
  1201. }
  1202.  
  1203. longlong Field_medium::val_int(void)
  1204. {
  1205.   long j= unsigned_flag ? (long) uint3korr(ptr) : sint3korr(ptr);
  1206.   return (longlong) j;
  1207. }
  1208.  
  1209. String *Field_medium::val_str(String *val_buffer,
  1210.                   String *val_ptr __attribute__((unused)))
  1211. {
  1212.   uint length;
  1213.   val_buffer->alloc(max(field_length+1,10));
  1214.   char *to=(char*) val_buffer->ptr();
  1215.   long j= unsigned_flag ? (long) uint3korr(ptr) : sint3korr(ptr);
  1216.  
  1217.   length=(uint) (int10_to_str(j,to,-10)-to);
  1218.   val_buffer->length(length);
  1219.   if (zerofill)
  1220.     prepend_zeros(val_buffer); /* purecov: inspected */
  1221.   return val_buffer;
  1222. }
  1223.  
  1224.  
  1225. int Field_medium::cmp(const char *a_ptr, const char *b_ptr)
  1226. {
  1227.   long a,b;
  1228.   if (unsigned_flag)
  1229.   {
  1230.     a=uint3korr(a_ptr);
  1231.     b=uint3korr(b_ptr);
  1232.   }
  1233.   else
  1234.   {
  1235.     a=sint3korr(a_ptr);
  1236.     b=sint3korr(b_ptr);
  1237.   }
  1238.   return (a < b) ? -1 : (a > b) ? 1 : 0;
  1239. }
  1240.  
  1241. void Field_medium::sort_string(char *to,uint length __attribute__((unused)))
  1242. {
  1243.   if (unsigned_flag)
  1244.     to[0] = ptr[2];
  1245.   else
  1246.     to[0] = (uchar) (ptr[2] ^ 128);        /* Revers signbit */
  1247.   to[1] = ptr[1];
  1248.   to[2] = ptr[0];
  1249. }
  1250.  
  1251.  
  1252. void Field_medium::sql_type(String &res) const
  1253. {
  1254.   sprintf((char*) res.ptr(),"mediumint(%d)",(int) field_length);
  1255.   add_zerofill_and_unsigned(res);
  1256. }
  1257.  
  1258. /****************************************************************************
  1259. ** long int
  1260. ****************************************************************************/
  1261.  
  1262.  
  1263. // Note:  Sometimes this should be fixed to use one strtol() to use
  1264. // len and check for garbage after number.
  1265.  
  1266. void Field_long::store(const char *from,uint len)
  1267. {
  1268.   while (len && isspace(*from))
  1269.   {
  1270.     len--; from++;
  1271.   }
  1272.   long tmp;
  1273.   String tmp_str(from,len);
  1274.   errno=0;
  1275.   if (unsigned_flag)
  1276.   {
  1277.     if (!len || *from == '-')
  1278.     {
  1279.       tmp=0;                    // Set negative to 0
  1280.       errno=ERANGE;
  1281.     }
  1282.     else
  1283.       tmp=(long) strtoul(tmp_str.c_ptr(),NULL,10);
  1284.   }
  1285.   else
  1286.     tmp=strtol(tmp_str.c_ptr(),NULL,10);
  1287.   if (errno || current_thd->count_cuted_fields && !test_if_int(from,len))
  1288.     current_thd->cuted_fields++;
  1289. #ifdef WORDS_BIGENDIAN
  1290.   if (table->db_low_byte_first)
  1291.   {
  1292.     int4store(ptr,tmp);
  1293.   }
  1294.   else
  1295. #endif
  1296.     longstore(ptr,tmp);
  1297. }
  1298.  
  1299.  
  1300. void Field_long::store(double nr)
  1301. {
  1302.   int32 res;
  1303.   nr=rint(nr);
  1304.   if (unsigned_flag)
  1305.   {
  1306.     if (nr < 0)
  1307.     {
  1308.       res=0;
  1309.       current_thd->cuted_fields++;
  1310.     }
  1311.     else if (nr > (double) (ulong) ~0L)
  1312.     {
  1313.       res=(int32) (uint32) ~0L;
  1314.       current_thd->cuted_fields++;
  1315.     }
  1316.     else
  1317.       res=(int32) (ulong) nr;
  1318.   }
  1319.   else
  1320.   {
  1321.     if (nr < (double) INT_MIN32)
  1322.     {
  1323.       res=(int32) INT_MIN32;
  1324.       current_thd->cuted_fields++;
  1325.     }
  1326.     else if (nr > (double) INT_MAX32)
  1327.     {
  1328.       res=(int32) INT_MAX32;
  1329.       current_thd->cuted_fields++;
  1330.     }
  1331.     else
  1332.       res=(int32) nr;
  1333.   }
  1334. #ifdef WORDS_BIGENDIAN
  1335.   if (table->db_low_byte_first)
  1336.   {
  1337.     int4store(ptr,res);
  1338.   }
  1339.   else
  1340. #endif
  1341.     longstore(ptr,res);
  1342. }
  1343.  
  1344.  
  1345. void Field_long::store(longlong nr)
  1346. {
  1347.   int32 res;
  1348.   if (unsigned_flag)
  1349.   {
  1350.     if (nr < 0)
  1351.     {
  1352.       res=0;
  1353.       current_thd->cuted_fields++;
  1354.     }
  1355.     else if (nr >= (LL(1) << 32))
  1356.     {
  1357.       res=(int32) (uint32) ~0L;
  1358.       current_thd->cuted_fields++;
  1359.     }
  1360.     else
  1361.       res=(int32) (uint32) nr;
  1362.   }
  1363.   else
  1364.   {
  1365.     if (nr < (longlong) INT_MIN32)
  1366.     {
  1367.       res=(int32) INT_MIN32;
  1368.       current_thd->cuted_fields++;
  1369.     }
  1370.     else if (nr > (longlong) INT_MAX32)
  1371.     {
  1372.       res=(int32) INT_MAX32;
  1373.       current_thd->cuted_fields++;
  1374.     }
  1375.     else
  1376.       res=(int32) nr;
  1377.   }
  1378. #ifdef WORDS_BIGENDIAN
  1379.   if (table->db_low_byte_first)
  1380.   {
  1381.     int4store(ptr,res);
  1382.   }
  1383.   else
  1384. #endif
  1385.     longstore(ptr,res);
  1386. }
  1387.  
  1388.  
  1389. double Field_long::val_real(void)
  1390. {
  1391.   int32 j;
  1392. #ifdef WORDS_BIGENDIAN
  1393.   if (table->db_low_byte_first)
  1394.     j=sint4korr(ptr);
  1395.   else
  1396. #endif
  1397.     longget(j,ptr);
  1398.   return unsigned_flag ? (double) (uint32) j : (double) j;
  1399. }
  1400.  
  1401. longlong Field_long::val_int(void)
  1402. {
  1403.   int32 j;
  1404. #ifdef WORDS_BIGENDIAN
  1405.   if (table->db_low_byte_first)
  1406.     j=sint4korr(ptr);
  1407.   else
  1408. #endif
  1409.     longget(j,ptr);
  1410.   return unsigned_flag ? (longlong) (uint32) j : (longlong) j;
  1411. }
  1412.  
  1413. String *Field_long::val_str(String *val_buffer,
  1414.                 String *val_ptr __attribute__((unused)))
  1415. {
  1416.   uint length;
  1417.   val_buffer->alloc(max(field_length+1,12));
  1418.   char *to=(char*) val_buffer->ptr();
  1419.   int32 j;
  1420. #ifdef WORDS_BIGENDIAN
  1421.   if (table->db_low_byte_first)
  1422.     j=sint4korr(ptr);
  1423.   else
  1424. #endif
  1425.     longget(j,ptr);
  1426.  
  1427.   length=(uint) (int10_to_str((unsigned_flag ? (long) (uint32) j : (long) j),
  1428.              to,
  1429.              unsigned_flag ? 10 : -10)-to);
  1430.   val_buffer->length(length);
  1431.   if (zerofill)
  1432.     prepend_zeros(val_buffer);
  1433.   return val_buffer;
  1434. }
  1435.  
  1436.  
  1437. int Field_long::cmp(const char *a_ptr, const char *b_ptr)
  1438. {
  1439.   int32 a,b;
  1440. #ifdef WORDS_BIGENDIAN
  1441.   if (table->db_low_byte_first)
  1442.   {
  1443.     a=sint4korr(a_ptr);
  1444.     b=sint4korr(b_ptr);
  1445.   }
  1446.   else
  1447. #endif
  1448.   {
  1449.     longget(a,a_ptr);
  1450.     longget(b,b_ptr);
  1451.   }
  1452.   if (unsigned_flag)
  1453.     return ((ulong) a < (ulong) b) ? -1 : ((ulong) a > (ulong) b) ? 1 : 0;
  1454.   return (a < b) ? -1 : (a > b) ? 1 : 0;
  1455. }
  1456.  
  1457. void Field_long::sort_string(char *to,uint length __attribute__((unused)))
  1458. {
  1459. #ifdef WORDS_BIGENDIAN
  1460.   if (!table->db_low_byte_first)
  1461.   {
  1462.     if (unsigned_flag)
  1463.       to[0] = ptr[0];
  1464.     else
  1465.       to[0] = ptr[0] ^ 128;            /* Revers signbit */
  1466.     to[1]   = ptr[1];
  1467.     to[2]   = ptr[2];
  1468.     to[3]   = ptr[3];
  1469.   }
  1470.   else
  1471. #endif
  1472.   {
  1473.     if (unsigned_flag)
  1474.       to[0] = ptr[3];
  1475.     else
  1476.       to[0] = ptr[3] ^ 128;            /* Revers signbit */
  1477.     to[1]   = ptr[2];
  1478.     to[2]   = ptr[1];
  1479.     to[3]   = ptr[0];
  1480.   }
  1481. }
  1482.  
  1483.  
  1484. void Field_long::sql_type(String &res) const
  1485. {
  1486.   sprintf((char*) res.ptr(),"int(%d)",(int) field_length);
  1487.   add_zerofill_and_unsigned(res);
  1488. }
  1489.  
  1490. /****************************************************************************
  1491. ** longlong int
  1492. ****************************************************************************/
  1493.  
  1494. void Field_longlong::store(const char *from,uint len)
  1495. {
  1496.   while (len && isspace(*from))
  1497.   {                        // For easy error check
  1498.     len--; from++;
  1499.   }
  1500.   longlong tmp;
  1501.   String tmp_str(from,len);
  1502.   errno=0;
  1503.   if (unsigned_flag)
  1504.   {
  1505.     if (!len || *from == '-')
  1506.     {
  1507.       tmp=0;                    // Set negative to 0
  1508.       errno=ERANGE;
  1509.     }
  1510.     else
  1511.       tmp=(longlong) strtoull(tmp_str.c_ptr(),NULL,10);
  1512.   }
  1513.   else
  1514.     tmp=strtoll(tmp_str.c_ptr(),NULL,10);
  1515.   if (errno || current_thd->count_cuted_fields && !test_if_int(from,len))
  1516.     current_thd->cuted_fields++;
  1517. #ifdef WORDS_BIGENDIAN
  1518.   if (table->db_low_byte_first)
  1519.   {
  1520.     int8store(ptr,tmp);
  1521.   }
  1522.   else
  1523. #endif
  1524.     longlongstore(ptr,tmp);
  1525. }
  1526.  
  1527.  
  1528. void Field_longlong::store(double nr)
  1529. {
  1530.   longlong res;
  1531.   nr=rint(nr);
  1532.   if (unsigned_flag)
  1533.   {
  1534.     if (nr < 0)
  1535.     {
  1536.       res=0;
  1537.       current_thd->cuted_fields++;
  1538.     }
  1539.     else if (nr >= (double) ~ (ulonglong) 0)
  1540.     {
  1541.       res= ~(longlong) 0;
  1542.       current_thd->cuted_fields++;
  1543.     }
  1544.     else
  1545.       res=(longlong) (ulonglong) nr;
  1546.   }
  1547.   else
  1548.   {
  1549.     if (nr <= (double) LONGLONG_MIN)
  1550.     {
  1551.       res=(longlong) LONGLONG_MIN;
  1552.       current_thd->cuted_fields++;
  1553.     }
  1554.     else if (nr >= (double) LONGLONG_MAX)
  1555.     {
  1556.       res=(longlong) LONGLONG_MAX;
  1557.       current_thd->cuted_fields++;
  1558.     }
  1559.     else
  1560.       res=(longlong) nr;
  1561.   }
  1562. #ifdef WORDS_BIGENDIAN
  1563.   if (table->db_low_byte_first)
  1564.   {
  1565.     int8store(ptr,res);
  1566.   }
  1567.   else
  1568. #endif
  1569.     longlongstore(ptr,res);
  1570. }
  1571.  
  1572.  
  1573. void Field_longlong::store(longlong nr)
  1574. {
  1575. #ifdef WORDS_BIGENDIAN
  1576.   if (table->db_low_byte_first)
  1577.   {
  1578.     int8store(ptr,nr);
  1579.   }
  1580.   else
  1581. #endif
  1582.     longlongstore(ptr,nr);
  1583. }
  1584.  
  1585.  
  1586. double Field_longlong::val_real(void)
  1587. {
  1588.   longlong j;
  1589. #ifdef WORDS_BIGENDIAN
  1590.   if (table->db_low_byte_first)
  1591.   {
  1592.     j=sint8korr(ptr);
  1593.   }
  1594.   else
  1595. #endif
  1596.     longlongget(j,ptr);
  1597.   return unsigned_flag ? ulonglong2double(j) : (double) j;
  1598. }
  1599.  
  1600. longlong Field_longlong::val_int(void)
  1601. {
  1602.   longlong j;
  1603. #ifdef WORDS_BIGENDIAN
  1604.   if (table->db_low_byte_first)
  1605.     j=sint8korr(ptr);
  1606.   else
  1607. #endif
  1608.     longlongget(j,ptr);
  1609.   return j;
  1610. }
  1611.  
  1612.  
  1613. String *Field_longlong::val_str(String *val_buffer,
  1614.                 String *val_ptr __attribute__((unused)))
  1615. {
  1616.   uint length;
  1617.   val_buffer->alloc(max(field_length+1,22));
  1618.   char *to=(char*) val_buffer->ptr();
  1619.   longlong j;
  1620. #ifdef WORDS_BIGENDIAN
  1621.   if (table->db_low_byte_first)
  1622.     j=sint8korr(ptr);
  1623.   else
  1624. #endif
  1625.     longlongget(j,ptr);
  1626.  
  1627.   length=(uint) (longlong10_to_str(j,to,unsigned_flag ? 10 : -10)-to);
  1628.   val_buffer->length(length);
  1629.   if (zerofill)
  1630.     prepend_zeros(val_buffer);
  1631.   return val_buffer;
  1632. }
  1633.  
  1634.  
  1635. int Field_longlong::cmp(const char *a_ptr, const char *b_ptr)
  1636. {
  1637.   longlong a,b;
  1638. #ifdef WORDS_BIGENDIAN
  1639.   if (table->db_low_byte_first)
  1640.   {
  1641.     a=sint8korr(a_ptr);
  1642.     b=sint8korr(b_ptr);
  1643.   }
  1644.   else
  1645. #endif
  1646.   {
  1647.     longlongget(a,a_ptr);
  1648.     longlongget(b,b_ptr);
  1649.   }
  1650.   if (unsigned_flag)
  1651.     return ((ulonglong) a < (ulonglong) b) ? -1 :
  1652.     ((ulonglong) a > (ulonglong) b) ? 1 : 0;
  1653.   return (a < b) ? -1 : (a > b) ? 1 : 0;
  1654. }
  1655.  
  1656. void Field_longlong::sort_string(char *to,uint length __attribute__((unused)))
  1657. {
  1658. #ifdef WORDS_BIGENDIAN
  1659.   if (!table->db_low_byte_first)
  1660.   {
  1661.     if (unsigned_flag)
  1662.       to[0] = ptr[0];
  1663.     else
  1664.       to[0] = ptr[0] ^ 128;            /* Revers signbit */
  1665.     to[1]   = ptr[1];
  1666.     to[2]   = ptr[2];
  1667.     to[3]   = ptr[3];
  1668.     to[4]   = ptr[4];
  1669.     to[5]   = ptr[5];
  1670.     to[6]   = ptr[6];
  1671.     to[7]   = ptr[7];
  1672.   }
  1673.   else
  1674. #endif
  1675.   {
  1676.     if (unsigned_flag)
  1677.       to[0] = ptr[7];
  1678.     else
  1679.       to[0] = ptr[7] ^ 128;            /* Revers signbit */
  1680.     to[1]   = ptr[6];
  1681.     to[2]   = ptr[5];
  1682.     to[3]   = ptr[4];
  1683.     to[4]   = ptr[3];
  1684.     to[5]   = ptr[2];
  1685.     to[6]   = ptr[1];
  1686.     to[7]   = ptr[0];
  1687.   }
  1688. }
  1689.  
  1690.  
  1691. void Field_longlong::sql_type(String &res) const
  1692. {
  1693.   sprintf((char*) res.ptr(),"bigint(%d)",(int) field_length);
  1694.   add_zerofill_and_unsigned(res);
  1695. }
  1696.  
  1697. /****************************************************************************
  1698. ** single precision float
  1699. ****************************************************************************/
  1700.  
  1701. void Field_float::store(const char *from,uint len)
  1702. {
  1703.   String tmp_str(from,len);
  1704.   errno=0;
  1705.   Field_float::store(atof(tmp_str.c_ptr()));
  1706.   if (errno || current_thd->count_cuted_fields && !test_if_real(from,len))
  1707.     current_thd->cuted_fields++;
  1708. }
  1709.  
  1710.  
  1711. void Field_float::store(double nr)
  1712. {
  1713.   float j;
  1714.   if (dec < NOT_FIXED_DEC)
  1715.     nr=floor(nr*log_10[dec]+0.5)/log_10[dec]; // To fixed point
  1716.   if (nr < -FLT_MAX)
  1717.   {
  1718.     j= -FLT_MAX;
  1719.     current_thd->cuted_fields++;
  1720.   }
  1721.   else if (nr > FLT_MAX)
  1722.   {
  1723.     j=FLT_MAX;
  1724.     current_thd->cuted_fields++;
  1725.   }
  1726.   else
  1727.     j= (float) nr;
  1728. #ifdef WORDS_BIGENDIAN
  1729.   if (table->db_low_byte_first)
  1730.   {
  1731.     float4store(ptr,j);
  1732.   }
  1733.   else
  1734. #endif
  1735.     memcpy_fixed(ptr,(byte*) &j,sizeof(j));
  1736. }
  1737.  
  1738.  
  1739. void Field_float::store(longlong nr)
  1740. {
  1741.   float j= (float) nr;
  1742. #ifdef WORDS_BIGENDIAN
  1743.   if (table->db_low_byte_first)
  1744.   {
  1745.     float4store(ptr,j);
  1746.   }
  1747.   else
  1748. #endif
  1749.     memcpy_fixed(ptr,(byte*) &j,sizeof(j));
  1750. }
  1751.  
  1752.  
  1753. double Field_float::val_real(void)
  1754. {
  1755.   float j;
  1756. #ifdef WORDS_BIGENDIAN
  1757.   if (table->db_low_byte_first)
  1758.   {
  1759.     float4get(j,ptr);
  1760.   }
  1761.   else
  1762. #endif
  1763.     memcpy_fixed((byte*) &j,ptr,sizeof(j));
  1764.   return ((double) j);
  1765. }
  1766.  
  1767. longlong Field_float::val_int(void)
  1768. {
  1769.   float j;
  1770. #ifdef WORDS_BIGENDIAN
  1771.   if (table->db_low_byte_first)
  1772.   {
  1773.     float4get(j,ptr);
  1774.   }
  1775.   else
  1776. #endif
  1777.     memcpy_fixed((byte*) &j,ptr,sizeof(j));
  1778.   return ((longlong) j);
  1779. }
  1780.  
  1781.  
  1782. String *Field_float::val_str(String *val_buffer,
  1783.                  String *val_ptr __attribute__((unused)))
  1784. {
  1785.   float nr;
  1786. #ifdef WORDS_BIGENDIAN
  1787.   if (table->db_low_byte_first)
  1788.   {
  1789.     float4get(nr,ptr);
  1790.   }
  1791.   else
  1792. #endif
  1793.     memcpy_fixed((byte*) &nr,ptr,sizeof(nr));
  1794.  
  1795.   val_buffer->alloc(max(field_length,70));
  1796.   char *to=(char*) val_buffer->ptr();
  1797.  
  1798.   if (dec >= NOT_FIXED_DEC)
  1799.   {
  1800.     sprintf(to,"%-*.*g",(int) field_length,FLT_DIG,nr);
  1801.     to=strcend(to,' ');
  1802.     *to=0;
  1803.   }
  1804.   else
  1805.   {
  1806. #ifdef HAVE_FCONVERT
  1807.     char buff[70],*pos=buff;
  1808.     int decpt,sign,tmp_dec=dec;
  1809.  
  1810.     VOID(sfconvert(&nr,tmp_dec,&decpt,&sign,buff));
  1811.     if (sign)
  1812.     {
  1813.       *to++='-';
  1814.     }
  1815.     if (decpt < 0)
  1816.     {                    /* val_buffer is < 0 */
  1817.       *to++='0';
  1818.       if (!tmp_dec)
  1819.     goto end;
  1820.       *to++='.';
  1821.       if (-decpt > tmp_dec)
  1822.     decpt= - (int) tmp_dec;
  1823.       tmp_dec=(uint) ((int) tmp_dec+decpt);
  1824.       while (decpt++ < 0)
  1825.     *to++='0';
  1826.     }
  1827.     else if (decpt == 0)
  1828.     {
  1829.       *to++= '0';
  1830.       if (!tmp_dec)
  1831.     goto end;
  1832.       *to++='.';
  1833.     }
  1834.     else
  1835.     {
  1836.       while (decpt-- > 0)
  1837.     *to++= *pos++;
  1838.       if (!tmp_dec)
  1839.     goto end;
  1840.       *to++='.';
  1841.     }
  1842.     while (tmp_dec--)
  1843.       *to++= *pos++;
  1844. #else
  1845. #ifdef HAVE_SNPRINTF_
  1846.     sprintf(to,val_buffer->length(),"%.*f",dec,nr);
  1847. #else
  1848.     sprintf(to,"%.*f",dec,nr);
  1849. #endif
  1850.     to=strend(to);
  1851. #endif
  1852.   }
  1853. #ifdef HAVE_FCONVERT
  1854.  end:
  1855. #endif
  1856.   val_buffer->length((uint) (to-val_buffer->ptr()));
  1857.   if (zerofill)
  1858.     prepend_zeros(val_buffer);
  1859.   return val_buffer;
  1860. }
  1861.  
  1862.  
  1863. int Field_float::cmp(const char *a_ptr, const char *b_ptr)
  1864. {
  1865.   float a,b;
  1866. #ifdef WORDS_BIGENDIAN
  1867.   if (table->db_low_byte_first)
  1868.   {
  1869.     float4get(a,a_ptr);
  1870.     float4get(b,b_ptr);
  1871.   }
  1872.   else
  1873. #endif
  1874.   {
  1875.     memcpy_fixed(&a,a_ptr,sizeof(float));
  1876.     memcpy_fixed(&b,b_ptr,sizeof(float));
  1877.   }
  1878.   return (a < b) ? -1 : (a > b) ? 1 : 0;
  1879. }
  1880.  
  1881. #define FLT_EXP_DIG (sizeof(float)*8-FLT_MANT_DIG)
  1882.  
  1883. void Field_float::sort_string(char *to,uint length __attribute__((unused)))
  1884. {
  1885.   float nr;
  1886. #ifdef WORDS_BIGENDIAN
  1887.   if (table->db_low_byte_first)
  1888.   {
  1889.     float4get(nr,ptr);
  1890.   }
  1891.   else
  1892. #endif
  1893.     memcpy_fixed(&nr,ptr,sizeof(float));
  1894.  
  1895.   uchar *tmp= (uchar*) to;
  1896.   if (nr == (float) 0.0)
  1897.   {                        /* Change to zero string */
  1898.     tmp[0]=(uchar) 128;
  1899.     bzero((char*) tmp+1,sizeof(nr)-1);
  1900.   }
  1901.   else
  1902.   {
  1903. #ifdef WORDS_BIGENDIAN
  1904.     memcpy_fixed(tmp,&nr,sizeof(nr));
  1905. #else
  1906.     tmp[0]= ptr[3]; tmp[1]=ptr[2]; tmp[2]= ptr[1]; tmp[3]=ptr[0];
  1907. #endif
  1908.     if (tmp[0] & 128)                /* Negative */
  1909.     {                        /* make complement */
  1910.       uint i;
  1911.       for (i=0 ; i < sizeof(nr); i++)
  1912.     tmp[i]=tmp[i] ^ (uchar) 255;
  1913.     }
  1914.     else
  1915.     {
  1916.       ushort exp_part=(((ushort) tmp[0] << 8) | (ushort) tmp[1] |
  1917.                (ushort) 32768);
  1918.       exp_part+= (ushort) 1 << (16-1-FLT_EXP_DIG);
  1919.       tmp[0]= (uchar) (exp_part >> 8);
  1920.       tmp[1]= (uchar) exp_part;
  1921.     }
  1922.   }
  1923. }
  1924.  
  1925.  
  1926. void Field_float::sql_type(String &res) const
  1927. {
  1928.   if (dec == NOT_FIXED_DEC)
  1929.     strmov((char*) res.ptr(),"float");
  1930.   else
  1931.     sprintf((char*) res.ptr(),"float(%d,%d)",(int) field_length,dec);
  1932.   add_zerofill_and_unsigned(res);
  1933. }
  1934.  
  1935. /****************************************************************************
  1936. ** double precision floating point numbers
  1937. ****************************************************************************/
  1938.  
  1939. void Field_double::store(const char *from,uint len)
  1940. {
  1941.   String tmp_str(from,len);
  1942.   errno=0;
  1943.   double j= atof(tmp_str.c_ptr());
  1944.   if (errno || current_thd->count_cuted_fields && !test_if_real(from,len))
  1945.     current_thd->cuted_fields++;
  1946. #ifdef WORDS_BIGENDIAN
  1947.   if (table->db_low_byte_first)
  1948.   {
  1949.     float8store(ptr,j);
  1950.   }
  1951.   else
  1952. #endif
  1953.     doublestore(ptr,j);
  1954. }
  1955.  
  1956.  
  1957. void Field_double::store(double nr)
  1958. {
  1959.   if (dec < NOT_FIXED_DEC)
  1960.     nr=floor(nr*log_10[dec]+0.5)/log_10[dec]; // To fixed point
  1961. #ifdef WORDS_BIGENDIAN
  1962.   if (table->db_low_byte_first)
  1963.   {
  1964.     float8store(ptr,nr);
  1965.   }
  1966.   else
  1967. #endif
  1968.     doublestore(ptr,nr);
  1969. }
  1970.  
  1971.  
  1972. void Field_double::store(longlong nr)
  1973. {
  1974.   double j= (double) nr;
  1975. #ifdef WORDS_BIGENDIAN
  1976.   if (table->db_low_byte_first)
  1977.   {
  1978.     float8store(ptr,j);
  1979.   }
  1980.   else
  1981. #endif
  1982.     doublestore(ptr,j);
  1983. }
  1984.  
  1985.  
  1986. double Field_double::val_real(void)
  1987. {
  1988.   double j;
  1989. #ifdef WORDS_BIGENDIAN
  1990.   if (table->db_low_byte_first)
  1991.   {
  1992.     float8get(j,ptr);
  1993.   }
  1994.   else
  1995. #endif
  1996.     doubleget(j,ptr);
  1997.   return j;
  1998. }
  1999.  
  2000. longlong Field_double::val_int(void)
  2001. {
  2002.   double j;
  2003. #ifdef WORDS_BIGENDIAN
  2004.   if (table->db_low_byte_first)
  2005.   {
  2006.     float8get(j,ptr);
  2007.   }
  2008.   else
  2009. #endif
  2010.     doubleget(j,ptr);
  2011.   return ((longlong) j);
  2012. }
  2013.  
  2014.  
  2015. String *Field_double::val_str(String *val_buffer,
  2016.                   String *val_ptr __attribute__((unused)))
  2017. {
  2018.   double nr;
  2019. #ifdef WORDS_BIGENDIAN
  2020.   if (table->db_low_byte_first)
  2021.   {
  2022.     float8get(nr,ptr);
  2023.   }
  2024.   else
  2025. #endif
  2026.     doubleget(nr,ptr);
  2027.  
  2028.   uint to_length=max(field_length,320);
  2029.   val_buffer->alloc(to_length);
  2030.   char *to=(char*) val_buffer->ptr();
  2031.  
  2032.   if (dec >= NOT_FIXED_DEC)
  2033.   {
  2034.     sprintf(to,"%-*.*g",(int) field_length,DBL_DIG,nr);
  2035.     to=strcend(to,' ');
  2036.   }
  2037.   else
  2038.   {
  2039. #ifdef HAVE_FCONVERT
  2040.     char buff[320],*pos=buff;
  2041.     int decpt,sign,tmp_dec=dec;
  2042.  
  2043.     VOID(fconvert(nr,tmp_dec,&decpt,&sign,buff));
  2044.     if (sign)
  2045.     {
  2046.       *to++='-';
  2047.     }
  2048.     if (decpt < 0)
  2049.     {                    /* val_buffer is < 0 */
  2050.       *to++='0';
  2051.       if (!tmp_dec)
  2052.     goto end;
  2053.       *to++='.';
  2054.       if (-decpt > tmp_dec)
  2055.     decpt= - (int) tmp_dec;
  2056.       tmp_dec=(uint) ((int) tmp_dec+decpt);
  2057.       while (decpt++ < 0)
  2058.     *to++='0';
  2059.     }
  2060.     else if (decpt == 0)
  2061.     {
  2062.       *to++= '0';
  2063.       if (!tmp_dec)
  2064.     goto end;
  2065.       *to++='.';
  2066.     }
  2067.     else
  2068.     {
  2069.       while (decpt-- > 0)
  2070.     *to++= *pos++;
  2071.       if (!tmp_dec)
  2072.     goto end;
  2073.       *to++='.';
  2074.     }
  2075.     while (tmp_dec--)
  2076.       *to++= *pos++;
  2077. #else
  2078. #ifdef HAVE_SNPRINTF
  2079.     to[to_length-1]=0;            // Safety
  2080.     snprintf(to,to_length-1,"%.*f",dec,nr);
  2081. #else
  2082.     sprintf(to,"%.*f",dec,nr);
  2083. #endif
  2084.     to=strend(to);
  2085. #endif
  2086.   }
  2087. #ifdef HAVE_FCONVERT
  2088.  end:
  2089. #endif
  2090.  
  2091.   val_buffer->length((uint) (to-val_buffer->ptr()));
  2092.   if (zerofill)
  2093.     prepend_zeros(val_buffer);
  2094.   return val_buffer;
  2095. }
  2096.  
  2097.  
  2098. int Field_double::cmp(const char *a_ptr, const char *b_ptr)
  2099. {
  2100.   double a,b;
  2101. #ifdef WORDS_BIGENDIAN
  2102.   if (table->db_low_byte_first)
  2103.   {
  2104.     float8get(a,a_ptr);
  2105.     float8get(b,b_ptr);
  2106.   }
  2107.   else
  2108. #endif
  2109.   {
  2110.     memcpy_fixed(&a,a_ptr,sizeof(double));
  2111.     memcpy_fixed(&b,b_ptr,sizeof(double));
  2112.   }
  2113.   return (a < b) ? -1 : (a > b) ? 1 : 0;
  2114. }
  2115.  
  2116.  
  2117. #define DBL_EXP_DIG (sizeof(double)*8-DBL_MANT_DIG)
  2118.  
  2119. /* The following should work for IEEE */
  2120.  
  2121. void Field_double::sort_string(char *to,uint length __attribute__((unused)))
  2122. {
  2123.   double nr;
  2124. #ifdef WORDS_BIGENDIAN
  2125.   if (table->db_low_byte_first)
  2126.   {
  2127.     float8get(nr,ptr);
  2128.   }
  2129.   else
  2130. #endif
  2131.     memcpy_fixed(&nr,ptr,sizeof(nr));
  2132.   change_double_for_sort(nr, (byte*) to);
  2133. }
  2134.  
  2135.  
  2136. void Field_double::sql_type(String &res) const
  2137. {
  2138.   if (dec == NOT_FIXED_DEC)
  2139.     strmov((char*) res.ptr(),"double");
  2140.   else
  2141.     sprintf((char*) res.ptr(),"double(%d,%d)",(int) field_length,dec);
  2142.   add_zerofill_and_unsigned(res);
  2143. }
  2144.  
  2145.  
  2146. /****************************************************************************
  2147. ** timestamp
  2148. ** The first timestamp in the table is automaticly updated
  2149. ** by handler.cc.  The form->timestamp points at the automatic timestamp.
  2150. ****************************************************************************/
  2151.  
  2152. Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg,
  2153.                  enum utype unireg_check_arg,
  2154.                  const char *field_name_arg,
  2155.                  struct st_table *table_arg)
  2156.     :Field_num(ptr_arg, len_arg, (uchar*) 0,0,
  2157.            unireg_check_arg, field_name_arg, table_arg,
  2158.            0, 1, 1)
  2159. {
  2160.   if (table && !table->timestamp_field)
  2161.   {
  2162.     table->timestamp_field= this;        // Automatic timestamp
  2163.     table->time_stamp=(ulong) (ptr_arg - (char*) table->record[0])+1;
  2164.     flags|=TIMESTAMP_FLAG;
  2165.   }
  2166. }
  2167.  
  2168.  
  2169. void Field_timestamp::store(const char *from,uint len)
  2170. {
  2171.   long tmp=(long) str_to_timestamp(from,len);
  2172. #ifdef WORDS_BIGENDIAN
  2173.   if (table->db_low_byte_first)
  2174.   {
  2175.     int4store(ptr,tmp);
  2176.   }
  2177.   else
  2178. #endif
  2179.     longstore(ptr,tmp);
  2180. }
  2181.  
  2182. void Field_timestamp::fill_and_store(char *from,uint len)
  2183. {
  2184.   uint res_length;
  2185.   if (len <= field_length)
  2186.     res_length=field_length;
  2187.   else if (len <= 12)
  2188.     res_length=12;                /* purecov: inspected */
  2189.   else if (len <= 14)
  2190.     res_length=14;                /* purecov: inspected */
  2191.   else
  2192.     res_length=(len+1)/2*2;            // must be even
  2193.   if (res_length != len)
  2194.   {
  2195.     bmove_upp(from+res_length,from+len,len);
  2196.     bfill(from,res_length-len,'0');
  2197.     len=res_length;
  2198.   }
  2199.   long tmp=(long) str_to_timestamp(from,len);
  2200. #ifdef WORDS_BIGENDIAN
  2201.   if (table->db_low_byte_first)
  2202.   {
  2203.     int4store(ptr,tmp);
  2204.   }
  2205.   else
  2206. #endif
  2207.     longstore(ptr,tmp);
  2208. }
  2209.  
  2210.  
  2211. void Field_timestamp::store(double nr)
  2212. {
  2213.   if (nr < 0 || nr > 99991231235959.0)
  2214.   {
  2215.     nr=0;                    // Avoid overflow on buff
  2216.     current_thd->cuted_fields++;
  2217.   }
  2218.   Field_timestamp::store((longlong) rint(nr));
  2219. }
  2220.  
  2221.  
  2222. /*
  2223. ** Convert a datetime of formats YYMMDD, YYYYMMDD or YYMMDDHHMSS to
  2224. ** YYYYMMDDHHMMSS.  The high date '99991231235959' is checked before this
  2225. ** function.
  2226. */
  2227.  
  2228. static longlong fix_datetime(longlong nr)
  2229. {
  2230.   if (nr == LL(0) || nr >= LL(10000101000000))
  2231.     return nr;                    // Normal datetime >= Year 1000
  2232.   if (nr < 101)
  2233.     goto err;
  2234.   if (nr <= (YY_PART_YEAR-1)*10000L+1231L)
  2235.     return (nr+20000000L)*1000000L;        // YYMMDD, year: 2000-2069
  2236.   if (nr < (YY_PART_YEAR)*10000L+101L)
  2237.     goto err;
  2238.   if (nr <= 991231L)
  2239.     return (nr+19000000L)*1000000L;        // YYMMDD, year: 1970-1999
  2240.   if (nr < 10000101L)
  2241.     goto err;
  2242.   if (nr <= 99991231L)
  2243.     return nr*1000000L;
  2244.   if (nr < 101000000L)
  2245.     goto err;
  2246.   if (nr <= (YY_PART_YEAR-1)*LL(10000000000)+LL(1231235959))
  2247.     return nr+LL(20000000000000);        // YYMMDDHHMMSS, 2000-2069
  2248.   if (nr <  YY_PART_YEAR*LL(10000000000)+ LL(101000000))
  2249.     goto err;
  2250.   if (nr <= LL(991231235959))
  2251.     return nr+LL(19000000000000);        // YYMMDDHHMMSS, 1970-1999
  2252.  
  2253.  err:
  2254.   current_thd->cuted_fields++;
  2255.   return LL(0);
  2256. }
  2257.  
  2258.  
  2259. void Field_timestamp::store(longlong nr)
  2260. {
  2261.   TIME l_time;
  2262.   time_t timestamp;
  2263.   long part1,part2;
  2264.  
  2265.   if ((nr=fix_datetime(nr)))
  2266.   {
  2267.     part1=(long) (nr/LL(1000000));
  2268.     part2=(long) (nr - (longlong) part1*LL(1000000));
  2269.     l_time.year=  part1/10000L;  part1%=10000L;
  2270.     l_time.month= (int) part1 / 100;
  2271.     l_time.day=    (int) part1 % 100; 
  2272.     l_time.hour=  part2/10000L;  part2%=10000L;
  2273.     l_time.minute=(int) part2 / 100;
  2274.     l_time.second=(int) part2 % 100; 
  2275.     timestamp=my_gmt_sec(&l_time);
  2276.   }
  2277.   else
  2278.     timestamp=0;
  2279. #ifdef WORDS_BIGENDIAN
  2280.   if (table->db_low_byte_first)
  2281.   {
  2282.     int4store(ptr,timestamp);
  2283.   }
  2284.   else
  2285. #endif
  2286.     longstore(ptr,timestamp);
  2287. }
  2288.  
  2289.  
  2290. double Field_timestamp::val_real(void)
  2291. {
  2292.   return (double) Field_timestamp::val_int();
  2293. }
  2294.  
  2295. longlong Field_timestamp::val_int(void)
  2296. {
  2297.   uint len,pos;
  2298.   int part_time;
  2299.   uint32 temp;
  2300.   time_t time_arg;
  2301.   struct tm *l_time;
  2302.   longlong res;
  2303.   struct tm tm_tmp;
  2304.  
  2305. #ifdef WORDS_BIGENDIAN
  2306.   if (table->db_low_byte_first)
  2307.     temp=uint4korr(ptr);
  2308.   else
  2309. #endif
  2310.     longget(temp,ptr);
  2311.  
  2312.   if (temp == 0L)                // No time
  2313.     return(0);                    /* purecov: inspected */
  2314.   time_arg=(time_t) temp;
  2315.   localtime_r(&time_arg,&tm_tmp);
  2316.   l_time=&tm_tmp;
  2317.   res=(longlong) 0;
  2318.   for (pos=len=0; len+1 < (uint) field_length ; len+=2,pos++)
  2319.   {
  2320.     bool year_flag=0;
  2321.     switch (dayord.pos[pos]) {
  2322.     case 0: part_time=l_time->tm_year % 100; year_flag=1 ; break;
  2323.     case 1: part_time=l_time->tm_mon+1; break;
  2324.     case 2: part_time=l_time->tm_mday; break;
  2325.     case 3: part_time=l_time->tm_hour; break;
  2326.     case 4: part_time=l_time->tm_min; break;
  2327.     case 5: part_time=l_time->tm_sec; break;
  2328.     default: part_time=0; break; /* purecov: deadcode */
  2329.     }
  2330.     if (year_flag && (field_length == 8 || field_length == 14))
  2331.     {
  2332.       res=res*(longlong) 10000+(part_time+
  2333.                 ((part_time < YY_PART_YEAR) ? 2000 : 1900));
  2334.       len+=2;
  2335.     }
  2336.     else
  2337.       res=res*(longlong) 100+part_time;
  2338.   }
  2339.   return (longlong) res;
  2340. }
  2341.  
  2342.  
  2343. String *Field_timestamp::val_str(String *val_buffer,
  2344.                  String *val_ptr __attribute__((unused)))
  2345. {
  2346.   uint pos;
  2347.   int part_time;
  2348.   uint32 temp;
  2349.   time_t time_arg;
  2350.   struct tm *l_time;
  2351.   struct tm tm_tmp;
  2352.  
  2353.   val_buffer->alloc(field_length+1);
  2354.   char *to=(char*) val_buffer->ptr(),*end=to+field_length;
  2355.  
  2356. #ifdef WORDS_BIGENDIAN
  2357.   if (table->db_low_byte_first)
  2358.     temp=uint4korr(ptr);
  2359.   else
  2360. #endif
  2361.     longget(temp,ptr);
  2362.  
  2363.   if (temp == 0L)
  2364.   {                      /* Zero time is "000000" */
  2365.     VOID(strfill(to,field_length,'0'));
  2366.     val_buffer->length(field_length);
  2367.     return val_buffer;
  2368.   }
  2369.   time_arg=(time_t) temp;
  2370.   localtime_r(&time_arg,&tm_tmp);
  2371.   l_time=&tm_tmp;
  2372.   for (pos=0; to < end ; pos++)
  2373.   {
  2374.     bool year_flag=0;
  2375.     switch (dayord.pos[pos]) {
  2376.     case 0: part_time=l_time->tm_year % 100; year_flag=1; break;
  2377.     case 1: part_time=l_time->tm_mon+1; break;
  2378.     case 2: part_time=l_time->tm_mday; break;
  2379.     case 3: part_time=l_time->tm_hour; break;
  2380.     case 4: part_time=l_time->tm_min; break;
  2381.     case 5: part_time=l_time->tm_sec; break;
  2382.     default: part_time=0; break; /* purecov: deadcode */
  2383.     }
  2384.     if (year_flag && (field_length == 8 || field_length == 14))
  2385.     {
  2386.       if (part_time < YY_PART_YEAR)
  2387.       {
  2388.     *to++='2'; *to++='0'; /* purecov: inspected */
  2389.       }
  2390.       else
  2391.       {
  2392.     *to++='1'; *to++='9';
  2393.       }
  2394.     }
  2395.     *to++=(char) ('0'+((uint) part_time/10));
  2396.     *to++=(char) ('0'+((uint) part_time % 10));
  2397.   }
  2398.   *to=0;                    // Safeguard
  2399.   val_buffer->length((uint) (to-val_buffer->ptr()));
  2400.   return val_buffer;
  2401. }
  2402.  
  2403. bool Field_timestamp::get_date(TIME *ltime,
  2404.                    bool fuzzydate __attribute__((unused)))
  2405. {
  2406.   long temp;
  2407. #ifdef WORDS_BIGENDIAN
  2408.   if (table->db_low_byte_first)
  2409.     temp=uint4korr(ptr);
  2410.   else
  2411. #endif
  2412.     longget(temp,ptr);
  2413.   if (temp == 0L)
  2414.   {                      /* Zero time is "000000" */
  2415.     bzero((char*) ltime,sizeof(*ltime));
  2416.   }
  2417.   else
  2418.   {
  2419.     struct tm tm_tmp;
  2420.     time_t time_arg= (time_t) temp;
  2421.     localtime_r(&time_arg,&tm_tmp);
  2422.     struct tm *start= &tm_tmp;
  2423.     ltime->year=    start->tm_year+1900;
  2424.     ltime->month=    start->tm_mon+1;
  2425.     ltime->day=        start->tm_mday;
  2426.     ltime->hour=    start->tm_hour;
  2427.     ltime->minute=    start->tm_min;
  2428.     ltime->second=    start->tm_sec;
  2429.     ltime->second_part=    0;
  2430.     ltime->neg=        0;
  2431.     ltime->time_type=TIMESTAMP_FULL;
  2432.   }
  2433.   return 0;
  2434. }
  2435.  
  2436. bool Field_timestamp::get_time(TIME *ltime)
  2437. {
  2438.   Field_timestamp::get_date(ltime,0);
  2439.   return 0;
  2440. }
  2441.  
  2442. int Field_timestamp::cmp(const char *a_ptr, const char *b_ptr)
  2443. {
  2444.   int32 a,b;
  2445. #ifdef WORDS_BIGENDIAN
  2446.   if (table->db_low_byte_first)
  2447.   {
  2448.     a=sint4korr(a_ptr);
  2449.     b=sint4korr(b_ptr);
  2450.   }
  2451.   else
  2452. #endif
  2453.   {
  2454.   longget(a,a_ptr);
  2455.   longget(b,b_ptr);
  2456.   }
  2457.   return ((uint32) a < (uint32) b) ? -1 : ((uint32) a > (uint32) b) ? 1 : 0;
  2458. }
  2459.  
  2460. void Field_timestamp::sort_string(char *to,uint length __attribute__((unused)))
  2461. {
  2462. #ifdef WORDS_BIGENDIAN
  2463.   if (!table->db_low_byte_first)
  2464.   {
  2465.     to[0] = ptr[0];
  2466.     to[1] = ptr[1];
  2467.     to[2] = ptr[2];
  2468.     to[3] = ptr[3];
  2469.   }
  2470.   else
  2471. #endif
  2472.   {
  2473.     to[0] = ptr[3];
  2474.     to[1] = ptr[2];
  2475.     to[2] = ptr[1];
  2476.     to[3] = ptr[0];
  2477.   }
  2478. }
  2479.  
  2480.  
  2481. void Field_timestamp::sql_type(String &res) const
  2482. {
  2483.   sprintf((char*) res.ptr(),"timestamp(%d)",(int) field_length);
  2484.   res.length((uint) strlen(res.ptr()));
  2485. }
  2486.  
  2487.  
  2488. void Field_timestamp::set_time()
  2489. {
  2490.   long tmp= (long) current_thd->query_start();
  2491. #ifdef WORDS_BIGENDIAN
  2492.   if (table->db_low_byte_first)
  2493.   {
  2494.     int4store(ptr,tmp);
  2495.   }
  2496.   else
  2497. #endif
  2498.     longstore(ptr,tmp);
  2499. }
  2500.  
  2501. /****************************************************************************
  2502. ** time type
  2503. ** In string context: HH:MM:SS
  2504. ** In number context: HHMMSS
  2505. ** Stored as a 3 byte unsigned int
  2506. ****************************************************************************/
  2507.  
  2508. void Field_time::store(const char *from,uint len)
  2509. {
  2510.   TIME ltime;
  2511.   long tmp;
  2512.   if (str_to_time(from,len,<ime))
  2513.     tmp=0L;
  2514.   else
  2515.   {
  2516.     if (ltime.month)
  2517.       ltime.day=0;
  2518.     tmp=(ltime.day*24L+ltime.hour)*10000L+(ltime.minute*100+ltime.second);
  2519.     if (tmp > 8385959)
  2520.     {
  2521.       tmp=8385959;
  2522.       current_thd->cuted_fields++;
  2523.     }
  2524.   }
  2525.   if (ltime.neg)
  2526.     tmp= -tmp;
  2527.   Field_time::store((longlong) tmp);
  2528. }
  2529.  
  2530.  
  2531. void Field_time::store(double nr)
  2532. {
  2533.   long tmp;
  2534.   if (nr > 8385959.0)
  2535.   {
  2536.     tmp=8385959L;
  2537.     current_thd->cuted_fields++;
  2538.   }
  2539.   else if (nr < -8385959.0)
  2540.   {
  2541.     tmp= -8385959L;
  2542.     current_thd->cuted_fields++;
  2543.   }
  2544.   else
  2545.   {
  2546.     tmp=(long) floor(fabs(nr));            // Remove fractions
  2547.     if (nr < 0)
  2548.       tmp= -tmp;
  2549.     if (tmp % 100 > 59 || tmp/100 % 100 > 59)
  2550.     {
  2551.       tmp=0;
  2552.       current_thd->cuted_fields++;
  2553.     }
  2554.   }
  2555.   int3store(ptr,tmp);
  2556. }
  2557.  
  2558.  
  2559. void Field_time::store(longlong nr)
  2560. {
  2561.   long tmp;
  2562.   if (nr > (longlong) 8385959L)
  2563.   {
  2564.     tmp=8385959L;
  2565.     current_thd->cuted_fields++;
  2566.   }
  2567.   else if (nr < (longlong) -8385959L)
  2568.   {
  2569.     tmp= -8385959L;
  2570.     current_thd->cuted_fields++;
  2571.   }
  2572.   else
  2573.   {
  2574.     tmp=(long) nr;
  2575.     if (tmp % 100 > 59 || tmp/100 % 100 > 59)
  2576.     {
  2577.       tmp=0;
  2578.       current_thd->cuted_fields++;
  2579.     }
  2580.   }
  2581.   int3store(ptr,tmp);
  2582. }
  2583.  
  2584.  
  2585. double Field_time::val_real(void)
  2586. {
  2587.   ulong j= (ulong) uint3korr(ptr);
  2588.   return (double) j;
  2589. }
  2590.  
  2591. longlong Field_time::val_int(void)
  2592. {
  2593.   return (longlong) sint3korr(ptr);
  2594. }
  2595.  
  2596. String *Field_time::val_str(String *val_buffer,
  2597.                 String *val_ptr __attribute__((unused)))
  2598. {
  2599.   val_buffer->alloc(16);
  2600.   long tmp=(long) sint3korr(ptr);
  2601.   const char *sign="";
  2602.   if (tmp < 0)
  2603.   {
  2604.     tmp= -tmp;
  2605.     sign= "-";
  2606.   }
  2607.   sprintf((char*) val_buffer->ptr(),"%s%02d:%02d:%02d",
  2608.       sign,(int) (tmp/10000), (int) (tmp/100 % 100),
  2609.       (int) (tmp % 100));
  2610.   val_buffer->length((uint) strlen(val_buffer->ptr()));
  2611.   return val_buffer;
  2612. }
  2613.  
  2614. bool Field_time::get_time(TIME *ltime)
  2615. {
  2616.   long tmp=(long) sint3korr(ptr);
  2617.   ltime->neg=0;
  2618.   if (tmp < 0)
  2619.   {
  2620.     ltime->neg= 1;
  2621.     tmp=-tmp;
  2622.   }
  2623.   ltime->hour=tmp/10000;
  2624.   tmp-=ltime->hour*10000;
  2625.   ltime->minute=   tmp/100;
  2626.   ltime->second= tmp % 100;
  2627.   ltime->second_part=0;
  2628.   return 0;
  2629. }
  2630.  
  2631. int Field_time::cmp(const char *a_ptr, const char *b_ptr)
  2632. {
  2633.   long a,b;
  2634.   a=(long) sint3korr(a_ptr);
  2635.   b=(long) sint3korr(b_ptr);
  2636.   return (a < b) ? -1 : (a > b) ? 1 : 0;
  2637. }
  2638.  
  2639. void Field_time::sort_string(char *to,uint length __attribute__((unused)))
  2640. {
  2641.   to[0] = (uchar) (ptr[2] ^ 128);
  2642.   to[1] = ptr[1];
  2643.   to[2] = ptr[0];
  2644. }
  2645.  
  2646. void Field_time::sql_type(String &res) const
  2647. {
  2648.   res.set("time",4);
  2649. }
  2650.  
  2651. /****************************************************************************
  2652. ** year type
  2653. ** Save in a byte the year 0, 1901->2155
  2654. ** Can handle 2 byte or 4 byte years!
  2655. ****************************************************************************/
  2656.  
  2657. void Field_year::store(const char *from, uint len)
  2658. {
  2659.   String tmp_str(from,len);
  2660.   long nr= strtol(tmp_str.c_ptr(),NULL,10);
  2661.  
  2662.   if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155)
  2663.   {
  2664.     *ptr=0;
  2665.     current_thd->cuted_fields++;
  2666.     return;
  2667.   }
  2668.   else if (current_thd->count_cuted_fields && !test_if_int(from,len))
  2669.     current_thd->cuted_fields++;
  2670.   if (nr != 0 || len != 4)
  2671.   {
  2672.     if (nr < YY_PART_YEAR)
  2673.       nr+=100;                    // 2000 - 2069
  2674.     else if (nr > 1900)
  2675.       nr-= 1900;
  2676.   }
  2677.   *ptr= (char) (unsigned char) nr;
  2678. }
  2679.  
  2680. void Field_year::store(double nr)
  2681. {
  2682.   if (nr < 0.0 || nr >= 2155.0)
  2683.     Field_year::store((longlong) -1);
  2684.   else
  2685.     Field_year::store((longlong) nr);
  2686. }
  2687.  
  2688. void Field_year::store(longlong nr)
  2689. {
  2690.   if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155)
  2691.   {
  2692.     *ptr=0;
  2693.     current_thd->cuted_fields++;
  2694.     return;
  2695.   }
  2696.   if (nr != 0 || field_length != 4)        // 0000 -> 0; 00 -> 2000
  2697.   {
  2698.     if (nr < YY_PART_YEAR)
  2699.       nr+=100;                    // 2000 - 2069
  2700.     else if (nr > 1900)
  2701.       nr-= 1900;
  2702.   }
  2703.   *ptr= (char) (unsigned char) nr;
  2704. }
  2705.  
  2706.  
  2707. double Field_year::val_real(void)
  2708. {
  2709.   return (double) Field_year::val_int();
  2710. }
  2711.  
  2712. longlong Field_year::val_int(void)
  2713. {
  2714.   int tmp= (int) ((uchar*) ptr)[0];
  2715.   if (field_length != 4)
  2716.     tmp%=100;                    // Return last 2 char
  2717.   else if (tmp)
  2718.     tmp+=1900;
  2719.   return (longlong) tmp;
  2720. }
  2721.  
  2722. String *Field_year::val_str(String *val_buffer,
  2723.                 String *val_ptr __attribute__((unused)))
  2724. {
  2725.   val_buffer->alloc(5);
  2726.   val_buffer->length(field_length);
  2727.   char *to=(char*) val_buffer->ptr();
  2728.   sprintf(to,field_length == 2 ? "%02d" : "%04d",(int) Field_year::val_int());
  2729.   return val_buffer;
  2730. }
  2731.  
  2732. void Field_year::sql_type(String &res) const
  2733. {
  2734.   sprintf((char*) res.ptr(),"year(%d)",(int) field_length);
  2735.   res.length((uint) strlen(res.ptr()));
  2736. }
  2737.  
  2738.  
  2739. /****************************************************************************
  2740. ** date type
  2741. ** In string context: YYYY-MM-DD
  2742. ** In number context: YYYYMMDD
  2743. ** Stored as a 4 byte unsigned int
  2744. ****************************************************************************/
  2745.  
  2746. void Field_date::store(const char *from,uint len)
  2747. {
  2748.   TIME l_time;
  2749.   ulong tmp;
  2750.   if (str_to_TIME(from,len,&l_time,1) == TIMESTAMP_NONE)
  2751.     tmp=0;
  2752.   else
  2753.     tmp=(ulong) l_time.year*10000L + (ulong) (l_time.month*100+l_time.day);
  2754. #ifdef WORDS_BIGENDIAN
  2755.   if (table->db_low_byte_first)
  2756.   {
  2757.     int4store(ptr,tmp);
  2758.   }
  2759.   else
  2760. #endif
  2761.     longstore(ptr,tmp);
  2762. }
  2763.  
  2764.  
  2765. void Field_date::store(double nr)
  2766. {
  2767.   long tmp;
  2768.   if (nr >= 19000000000000.0 && nr <= 99991231235959.0)
  2769.     nr=floor(nr/1000000.0);            // Timestamp to date
  2770.   if (nr < 0.0 || nr > 99991231.0)
  2771.   {
  2772.     tmp=0L;
  2773.     current_thd->cuted_fields++;
  2774.   }
  2775.   else
  2776.     tmp=(long) rint(nr);
  2777. #ifdef WORDS_BIGENDIAN
  2778.   if (table->db_low_byte_first)
  2779.   {
  2780.     int4store(ptr,tmp);
  2781.   }
  2782.   else
  2783. #endif
  2784.     longstore(ptr,tmp);
  2785. }
  2786.  
  2787.  
  2788. void Field_date::store(longlong nr)
  2789. {
  2790.   long tmp;
  2791.   if (nr >= LL(19000000000000) && nr < LL(99991231235959))
  2792.     nr=nr/LL(1000000);            // Timestamp to date
  2793.   if (nr < 0 || nr > LL(99991231))
  2794.   {
  2795.     tmp=0L;
  2796.     current_thd->cuted_fields++;
  2797.   }
  2798.   else
  2799.     tmp=(long) nr;
  2800. #ifdef WORDS_BIGENDIAN
  2801.   if (table->db_low_byte_first)
  2802.   {
  2803.     int4store(ptr,tmp);
  2804.   }
  2805.   else
  2806. #endif
  2807.     longstore(ptr,tmp);
  2808. }
  2809.  
  2810.  
  2811. double Field_date::val_real(void)
  2812. {
  2813.   int32 j;
  2814. #ifdef WORDS_BIGENDIAN
  2815.   if (table->db_low_byte_first)
  2816.     j=sint4korr(ptr);
  2817.   else
  2818. #endif
  2819.     longget(j,ptr);
  2820.   return (double) (uint32) j;
  2821. }
  2822.  
  2823. longlong Field_date::val_int(void)
  2824. {
  2825.   int32 j;
  2826. #ifdef WORDS_BIGENDIAN
  2827.   if (table->db_low_byte_first)
  2828.     j=sint4korr(ptr);
  2829.   else
  2830. #endif
  2831.     longget(j,ptr);
  2832.   return (longlong) (uint32) j;
  2833. }
  2834.  
  2835. String *Field_date::val_str(String *val_buffer,
  2836.                 String *val_ptr __attribute__((unused)))
  2837. {
  2838.   val_buffer->alloc(field_length);
  2839.   val_buffer->length(field_length);
  2840.   int32 tmp;
  2841. #ifdef WORDS_BIGENDIAN
  2842.   if (table->db_low_byte_first)
  2843.     tmp=sint4korr(ptr);
  2844.   else
  2845. #endif
  2846.     longget(tmp,ptr);
  2847.   sprintf((char*) val_buffer->ptr(),"%04d-%02d-%02d",
  2848.       (int) ((uint32) tmp/10000L % 10000), (int) ((uint32) tmp/100 % 100),
  2849.       (int) ((uint32) tmp % 100));
  2850.   return val_buffer;
  2851. }
  2852.  
  2853. int Field_date::cmp(const char *a_ptr, const char *b_ptr)
  2854. {
  2855.   int32 a,b;
  2856. #ifdef WORDS_BIGENDIAN
  2857.   if (table->db_low_byte_first)
  2858.   {
  2859.     a=sint4korr(a_ptr);
  2860.     b=sint4korr(b_ptr);
  2861.   }
  2862.   else
  2863. #endif
  2864.   {
  2865.     longget(a,a_ptr);
  2866.     longget(b,b_ptr);
  2867.   }
  2868.   return ((uint32) a < (uint32) b) ? -1 : ((uint32) a > (uint32) b) ? 1 : 0;
  2869. }
  2870.  
  2871.  
  2872. void Field_date::sort_string(char *to,uint length __attribute__((unused)))
  2873. {
  2874. #ifdef WORDS_BIGENDIAN
  2875.   if (!table->db_low_byte_first)
  2876.   {
  2877.     to[0] = ptr[0];
  2878.     to[1] = ptr[1];
  2879.     to[2] = ptr[2];
  2880.     to[3] = ptr[3];
  2881.   }
  2882.   else
  2883. #endif
  2884.   {
  2885.     to[0] = ptr[3];
  2886.     to[1] = ptr[2];
  2887.     to[2] = ptr[1];
  2888.     to[3] = ptr[0];
  2889.   }
  2890. }
  2891.  
  2892. void Field_date::sql_type(String &res) const
  2893. {
  2894.   res.set("date",4);
  2895. }
  2896.  
  2897. /****************************************************************************
  2898. ** The new date type
  2899. ** This is identical to the old date type, but stored on 3 bytes instead of 4
  2900. ** In number context: YYYYMMDD
  2901. ****************************************************************************/
  2902.  
  2903. void Field_newdate::store(const char *from,uint len)
  2904. {
  2905.   TIME l_time;
  2906.   long tmp;
  2907.   if (str_to_TIME(from,len,&l_time,1) == TIMESTAMP_NONE)
  2908.     tmp=0L;
  2909.   else
  2910.     tmp= l_time.day + l_time.month*32 + l_time.year*16*32;
  2911.   int3store(ptr,tmp);
  2912. }
  2913.  
  2914. void Field_newdate::store(double nr)
  2915. {
  2916.   if (nr < 0.0 || nr > 99991231235959.0)
  2917.     Field_newdate::store((longlong) -1);
  2918.   else
  2919.     Field_newdate::store((longlong) rint(nr));
  2920. }
  2921.  
  2922.  
  2923. void Field_newdate::store(longlong nr)
  2924. {
  2925.   long tmp;
  2926.   if (nr >= LL(100000000) && nr <= LL(99991231235959))
  2927.     nr=nr/LL(1000000);            // Timestamp to date
  2928.   if (nr < 0L || nr > 99991231L)
  2929.   {
  2930.     tmp=0;
  2931.     current_thd->cuted_fields++;
  2932.   }
  2933.   else
  2934.   {
  2935.     tmp=(long) nr;
  2936.     if (tmp)
  2937.     {
  2938.       if (tmp < YY_PART_YEAR*10000L)            // Fix short dates
  2939.     tmp+=20000000L;
  2940.       else if (tmp < 999999L)
  2941.     tmp+=19000000L;
  2942.     }
  2943.     uint month=((tmp/100) % 100);
  2944.     uint day= tmp%100;
  2945.     if (month > 12 || day > 31)
  2946.     {
  2947.       tmp=0L;                    // Don't allow date to change
  2948.       current_thd->cuted_fields++;
  2949.     }
  2950.     else
  2951.       tmp= day + month*32 + (tmp/10000)*16*32;
  2952.   }
  2953.   int3store(ptr,tmp);
  2954. }
  2955.  
  2956. void Field_newdate::store_time(TIME *ltime,timestamp_type type)
  2957. {
  2958.   long tmp;
  2959.   if (type == TIMESTAMP_DATE || type == TIMESTAMP_FULL)
  2960.     tmp=ltime->year*16*32+ltime->month*32+ltime->day;
  2961.   else
  2962.   {
  2963.     tmp=0;
  2964.     current_thd->cuted_fields++;
  2965.   }
  2966.   int3store(ptr,tmp);
  2967. }
  2968.  
  2969.  
  2970.  
  2971. double Field_newdate::val_real(void)
  2972. {
  2973.   return (double) Field_newdate::val_int();
  2974. }
  2975.  
  2976. longlong Field_newdate::val_int(void)
  2977. {
  2978.   ulong j=uint3korr(ptr);
  2979.   j= (j % 32L)+(j / 32L % 16L)*100L + (j/(16L*32L))*10000L;
  2980.   return (longlong) j;
  2981. }
  2982.  
  2983. String *Field_newdate::val_str(String *val_buffer,
  2984.                    String *val_ptr __attribute__((unused)))
  2985. {
  2986.   val_buffer->alloc(field_length);
  2987.   val_buffer->length(field_length);
  2988.   ulong tmp=(ulong) uint3korr(ptr);
  2989.   int part;
  2990.   char *pos=(char*) val_buffer->ptr()+10;
  2991.  
  2992.   /* Open coded to get more speed */
  2993.   *pos--=0;
  2994.   part=(int) (tmp & 31);
  2995.   *pos--='0'+part%10;
  2996.   *pos--='0'+part/10;
  2997.   *pos--='-';
  2998.   part=(int) (tmp >> 5 & 15);
  2999.   *pos--='0'+part%10;
  3000.   *pos--='0'+part/10;
  3001.   *pos--='-';
  3002.   part=(int) (tmp >> 9);
  3003.   *pos--='0'+part%10; part/=10;
  3004.   *pos--='0'+part%10; part/=10;
  3005.   *pos--='0'+part%10; part/=10;
  3006.   *pos='0'+part;
  3007.   return val_buffer;
  3008. }
  3009.  
  3010. bool Field_newdate::get_date(TIME *ltime,bool fuzzydate)
  3011. {
  3012.   if (is_null())
  3013.     return 1;
  3014.   ulong tmp=(ulong) uint3korr(ptr);
  3015.   bzero((char*) ltime,sizeof(*ltime));
  3016.   ltime->day=   tmp & 31;
  3017.   ltime->month= (tmp >> 5) & 15;
  3018.   ltime->year=  (tmp >> 9);
  3019.   ltime->time_type=TIMESTAMP_DATE;
  3020.   return (!fuzzydate && (!ltime->month || !ltime->day) && ltime->year) ? 1 : 0;
  3021. }
  3022.  
  3023. bool Field_newdate::get_time(TIME *ltime)
  3024. {
  3025.   Field_newdate::get_date(ltime,0);
  3026.   return 0;
  3027. }
  3028.  
  3029. int Field_newdate::cmp(const char *a_ptr, const char *b_ptr)
  3030. {
  3031.   ulong a,b;
  3032.   a=(ulong) uint3korr(a_ptr);
  3033.   b=(ulong) uint3korr(b_ptr);
  3034.   return (a < b) ? -1 : (a > b) ? 1 : 0;
  3035. }
  3036.  
  3037. void Field_newdate::sort_string(char *to,uint length __attribute__((unused)))
  3038. {
  3039.   to[0] = ptr[2];
  3040.   to[1] = ptr[1];
  3041.   to[2] = ptr[0];
  3042. }
  3043.  
  3044. void Field_newdate::sql_type(String &res) const
  3045. {
  3046.   res.set("date",4);
  3047. }
  3048.  
  3049.  
  3050. /****************************************************************************
  3051. ** datetime type
  3052. ** In string context: YYYY-MM-DD HH:MM:DD
  3053. ** In number context: YYYYMMDDHHMMDD
  3054. ** Stored as a 8 byte unsigned int. Should sometimes be change to a 6 byte int.
  3055. ****************************************************************************/
  3056.  
  3057. void Field_datetime::store(const char *from,uint len)
  3058. {
  3059.   longlong tmp=str_to_datetime(from,len,1);
  3060. #ifdef WORDS_BIGENDIAN
  3061.   if (table->db_low_byte_first)
  3062.   {
  3063.     int8store(ptr,tmp);
  3064.   }
  3065.   else
  3066. #endif
  3067.     longlongstore(ptr,tmp);
  3068. }
  3069.  
  3070.  
  3071. void Field_datetime::store(double nr)
  3072. {
  3073.   if (nr < 0.0 || nr > 99991231235959.0)
  3074.   {
  3075.     nr=0.0;
  3076.     current_thd->cuted_fields++;
  3077.   }
  3078.   Field_datetime::store((longlong) rint(nr));
  3079. }
  3080.  
  3081.  
  3082. void Field_datetime::store(longlong nr)
  3083. {
  3084.   if (nr < 0 || nr > LL(99991231235959))
  3085.   {
  3086.     nr=0;
  3087.     current_thd->cuted_fields++;
  3088.   }
  3089.   else
  3090.     nr=fix_datetime(nr);
  3091. #ifdef WORDS_BIGENDIAN
  3092.   if (table->db_low_byte_first)
  3093.   {
  3094.     int8store(ptr,nr);
  3095.   }
  3096.   else
  3097. #endif
  3098.     longlongstore(ptr,nr);
  3099. }
  3100.  
  3101. void Field_datetime::store_time(TIME *ltime,timestamp_type type)
  3102. {
  3103.   longlong tmp;
  3104.   if (type == TIMESTAMP_DATE || type == TIMESTAMP_FULL)
  3105.     tmp=((ltime->year*10000L+ltime->month*100+ltime->day)*LL(1000000)+
  3106.      (ltime->hour*10000L+ltime->minute*100+ltime->second));
  3107.   else
  3108.   {
  3109.     tmp=0;
  3110.     current_thd->cuted_fields++;
  3111.   }
  3112. #ifdef WORDS_BIGENDIAN
  3113.   if (table->db_low_byte_first)
  3114.   {
  3115.     int8store(ptr,tmp);
  3116.   }
  3117.   else
  3118. #endif
  3119.     longlongstore(ptr,tmp);
  3120. }
  3121.  
  3122.  
  3123. double Field_datetime::val_real(void)
  3124. {
  3125.   return (double) Field_datetime::val_int();
  3126. }
  3127.  
  3128. longlong Field_datetime::val_int(void)
  3129. {
  3130.   longlong j;
  3131. #ifdef WORDS_BIGENDIAN
  3132.   if (table->db_low_byte_first)
  3133.     j=sint8korr(ptr);
  3134.   else
  3135. #endif
  3136.     longlongget(j,ptr);
  3137.   return j;
  3138. }
  3139.  
  3140.  
  3141. String *Field_datetime::val_str(String *val_buffer,
  3142.                 String *val_ptr __attribute__((unused)))
  3143. {
  3144.   val_buffer->alloc(field_length);
  3145.   val_buffer->length(field_length);
  3146.   ulonglong tmp;
  3147.   long part1,part2;
  3148.   char *pos;
  3149.   int part3;
  3150.  
  3151. #ifdef WORDS_BIGENDIAN
  3152.   if (table->db_low_byte_first)
  3153.     tmp=sint8korr(ptr);
  3154.   else
  3155. #endif
  3156.     longlongget(tmp,ptr);
  3157.  
  3158.   /*
  3159.     Avoid problem with slow longlong aritmetic and sprintf
  3160.   */
  3161.  
  3162.   part1=(long) (tmp/LL(1000000));
  3163.   part2=(long) (tmp - (ulonglong) part1*LL(1000000));
  3164.  
  3165.   pos=(char*) val_buffer->ptr()+19;
  3166.   *pos--=0;
  3167.   *pos--='0'+(char) (part2%10); part2/=10;
  3168.   *pos--='0'+(char) (part2%10); part3= (int) (part2 / 10);
  3169.   *pos--=':';
  3170.   *pos--='0'+(char) (part3%10); part3/=10;
  3171.   *pos--='0'+(char) (part3%10); part3/=10;
  3172.   *pos--=':';
  3173.   *pos--='0'+(char) (part3%10); part3/=10;
  3174.   *pos--='0'+(char) part3;
  3175.   *pos--=' ';
  3176.   *pos--='0'+(char) (part1%10); part1/=10;
  3177.   *pos--='0'+(char) (part1%10); part1/=10;
  3178.   *pos--='-';
  3179.   *pos--='0'+(char) (part1%10); part1/=10;
  3180.   *pos--='0'+(char) (part1%10); part3= (int) (part1/10);
  3181.   *pos--='-';
  3182.   *pos--='0'+(char) (part3%10); part3/=10;
  3183.   *pos--='0'+(char) (part3%10); part3/=10;
  3184.   *pos--='0'+(char) (part3%10); part3/=10;
  3185.   *pos='0'+(char) part3;
  3186.   return val_buffer;
  3187. }
  3188.  
  3189. bool Field_datetime::get_date(TIME *ltime,bool fuzzydate)
  3190. {
  3191.   longlong tmp=Field_datetime::val_int();
  3192.   long part1,part2;
  3193.   part1=(long) (tmp/LL(1000000));
  3194.   part2=(long) (tmp - (ulonglong) part1*LL(1000000));
  3195.  
  3196.   ltime->time_type=    TIMESTAMP_FULL;
  3197.   ltime->neg=0;
  3198.   ltime->second_part=0;
  3199.   ltime->second=    part2%100;
  3200.   ltime->minute=    part2/100%100;
  3201.   ltime->hour=        part2/10000;
  3202.   ltime->day=        part1%100;
  3203.   ltime->month=     part1/100%100;
  3204.   ltime->year=         part1/10000;
  3205.   return (!fuzzydate && (!ltime->month || !ltime->day) && ltime->year) ? 1 : 0;
  3206. }
  3207.  
  3208. bool Field_datetime::get_time(TIME *ltime)
  3209. {
  3210.   Field_datetime::get_date(ltime,0);
  3211.   return 0;
  3212. }
  3213.  
  3214. int Field_datetime::cmp(const char *a_ptr, const char *b_ptr)
  3215. {
  3216.   longlong a,b;
  3217. #ifdef WORDS_BIGENDIAN
  3218.   if (table->db_low_byte_first)
  3219.   {
  3220.     a=sint8korr(a_ptr);
  3221.     b=sint8korr(b_ptr);
  3222.   }
  3223.   else
  3224. #endif
  3225.   {
  3226.     longlongget(a,a_ptr);
  3227.     longlongget(b,b_ptr);
  3228.   }
  3229.   return ((ulonglong) a < (ulonglong) b) ? -1 :
  3230.     ((ulonglong) a > (ulonglong) b) ? 1 : 0;
  3231. }
  3232.  
  3233. void Field_datetime::sort_string(char *to,uint length __attribute__((unused)))
  3234. {
  3235. #ifdef WORDS_BIGENDIAN
  3236.   if (!table->db_low_byte_first)
  3237.   {
  3238.     to[0] = ptr[0];
  3239.     to[1] = ptr[1];
  3240.     to[2] = ptr[2];
  3241.     to[3] = ptr[3];
  3242.     to[4] = ptr[4];
  3243.     to[5] = ptr[5];
  3244.     to[6] = ptr[6];
  3245.     to[7] = ptr[7];
  3246.   }
  3247.   else
  3248. #endif
  3249.   {
  3250.     to[0] = ptr[7];
  3251.     to[1] = ptr[6];
  3252.     to[2] = ptr[5];
  3253.     to[3] = ptr[4];
  3254.     to[4] = ptr[3];
  3255.     to[5] = ptr[2];
  3256.     to[6] = ptr[1];
  3257.     to[7] = ptr[0];
  3258.   }
  3259. }
  3260.  
  3261.  
  3262. void Field_datetime::sql_type(String &res) const
  3263. {
  3264.   res.set("datetime",8);
  3265. }
  3266.  
  3267. /****************************************************************************
  3268. ** string type
  3269. ** A string may be varchar or binary
  3270. ****************************************************************************/
  3271.  
  3272.     /* Copy a string and fill with space */
  3273.  
  3274. void Field_string::store(const char *from,uint length)
  3275. {
  3276. #ifdef USE_TIS620
  3277.   if(!binary_flag) {
  3278.     ThNormalize((uchar *)ptr, field_length, (uchar *)from, length);
  3279.     if(length < field_length) {
  3280.       bfill(ptr + length, field_length - length, ' ');
  3281.     }
  3282.   }
  3283. #else
  3284.   if (length <= field_length)
  3285.   {
  3286.     memcpy(ptr,from,length);
  3287.     if (length < field_length)
  3288.       bfill(ptr+length,field_length-length,' ');
  3289.   }
  3290.   else
  3291.   {
  3292.     memcpy(ptr,from,field_length);
  3293.     if (current_thd->count_cuted_fields)
  3294.     {                        // Check if we loosed some info
  3295.       const char *end=from+length;
  3296.       for (from+=field_length ; from != end ; from++)
  3297.       {
  3298.     if (!isspace(*from))
  3299.     {
  3300.       current_thd->cuted_fields++;
  3301.       break;
  3302.     }
  3303.       }
  3304.     }
  3305.   }
  3306. #endif /* USE_TIS620 */
  3307. }
  3308.  
  3309.  
  3310. void Field_string::store(double nr)
  3311. {
  3312.   char buff[MAX_FIELD_WIDTH],*end;
  3313.   int width=min(field_length,DBL_DIG+5);
  3314.   sprintf(buff,"%-*.*g",width,max(width-5,0),nr);
  3315.   end=strcend(buff,' ');
  3316.   Field_string::store(buff,(uint) (end - buff));
  3317. }
  3318.  
  3319.  
  3320. void Field_string::store(longlong nr)
  3321. {
  3322.   char buff[22];
  3323.   char *end=longlong10_to_str(nr,buff,-10);
  3324.   Field_string::store(buff,end-buff);
  3325. }
  3326.  
  3327.  
  3328. double Field_string::val_real(void)
  3329. {
  3330.   double value;
  3331.   char save=ptr[field_length];            // Ok to patch record
  3332.   ptr[field_length]=0;
  3333.   value=atof(ptr);
  3334.   ptr[field_length]=save;
  3335.   return value;
  3336. }
  3337.  
  3338.  
  3339. longlong Field_string::val_int(void)
  3340. {
  3341.   longlong value;
  3342.   char save=ptr[field_length];            // Ok to patch record
  3343.   ptr[field_length]=0;
  3344.   value=strtoll(ptr,NULL,10);
  3345.   ptr[field_length]=save;
  3346.   return value;
  3347. }
  3348.  
  3349.  
  3350. String *Field_string::val_str(String *val_buffer __attribute__((unused)),
  3351.                   String *val_ptr)
  3352. {
  3353.   char *end=ptr+field_length;
  3354. #ifdef WANT_TRUE_BINARY_STRINGS
  3355.   if (!binary)
  3356. #endif
  3357.     while (end > ptr && end[-1] == ' ')
  3358.       end--;
  3359.   val_ptr->set((const char*) ptr,(uint) (end - ptr));
  3360.   return val_ptr;
  3361. }
  3362.  
  3363.  
  3364. int Field_string::cmp(const char *a_ptr, const char *b_ptr)
  3365. {
  3366.   if (binary_flag)
  3367.     return memcmp(a_ptr,b_ptr,field_length);
  3368.   else
  3369.     return my_sortcmp(a_ptr,b_ptr,field_length);
  3370. }
  3371.  
  3372. void Field_string::sort_string(char *to,uint length)
  3373. {
  3374.   if (binary_flag)
  3375.     memcpy((byte*) to,(byte*) ptr,(size_t) length);
  3376.   else
  3377.   {
  3378. #ifdef USE_STRCOLL
  3379.     if (use_strcoll(default_charset_info)) {
  3380.       uint tmp=my_strnxfrm(default_charset_info,
  3381.                           (unsigned char *)to, (unsigned char *) ptr,
  3382.                           length, field_length);
  3383.       if (tmp < length)
  3384.         bzero(to + tmp, length - tmp);
  3385.     }
  3386.     else
  3387. #endif
  3388.       for (char *from=ptr,*end=ptr+length ; from != end ;)
  3389.         *to++=(char) my_sort_order[(uint) (uchar) *from++];
  3390.   }
  3391. }
  3392.  
  3393.  
  3394. void Field_string::sql_type(String &res) const
  3395. {
  3396.   sprintf((char*) res.ptr(),"%s(%d)",
  3397.       field_length > 3 &&
  3398.       (table->db_options_in_use & HA_OPTION_PACK_RECORD) ?
  3399.       "varchar" : "char",
  3400.       (int) field_length);
  3401.   res.length((uint) strlen(res.ptr()));
  3402.   if (binary_flag)
  3403.     res.append(" binary");
  3404. }
  3405.  
  3406.  
  3407. char *Field_string::pack(char *to, const char *from, uint max_length)
  3408. {
  3409.   const char *end=from+min(field_length,max_length);
  3410.   uchar length;
  3411.   while (end > from && end[-1] == ' ')
  3412.     end--;
  3413.   *to= length=(uchar) (end-from);
  3414.   memcpy(to+1, from, (int) length);
  3415.   return to+1+length;
  3416. }
  3417.  
  3418.  
  3419. const char *Field_string::unpack(char *to, const char *from)
  3420. {
  3421.   uint length= (uint) (uchar) *from++;
  3422.   memcpy(to, from, (int) length);
  3423.   bfill(to+length, field_length - length, ' ');
  3424.   return from+length;
  3425. }
  3426.  
  3427.  
  3428. int Field_string::pack_cmp(const char *a, const char *b, uint length)
  3429. {
  3430.   uint a_length= (uint) (uchar) *a++;
  3431.   uint b_length= (uint) (uchar) *b++;
  3432.  
  3433.   if (binary_flag)
  3434.   {
  3435.     int cmp= memcmp(a,b,min(a_length,b_length));
  3436.     return cmp ? cmp : (int) (a_length - b_length);
  3437.   }
  3438.   return my_sortncmp(a,a_length, b,b_length);
  3439. }
  3440.  
  3441.  
  3442. int Field_string::pack_cmp(const char *b, uint length)
  3443. {
  3444.   uint b_length= (uint) (uchar) *b++;
  3445.   char *end= ptr + field_length;
  3446.   while (end > ptr && end[-1] == ' ')
  3447.     end--;
  3448.   uint a_length = (uint) (end - ptr);
  3449.  
  3450.   if (binary_flag)
  3451.   {
  3452.     int cmp= memcmp(ptr,b,min(a_length,b_length));
  3453.     return cmp ? cmp : (int) (a_length - b_length);
  3454.   }
  3455.   return my_sortncmp(ptr,a_length, b, b_length);
  3456. }
  3457.  
  3458.  
  3459. uint Field_string::packed_col_length(const char *ptr)
  3460. {
  3461.   if (field_length > 255)
  3462.     return uint2korr(ptr)+2;
  3463.   else
  3464.     return (uint) ((uchar) *ptr)+1;
  3465. }
  3466.  
  3467. uint Field_string::max_packed_col_length(uint max_length)
  3468. {
  3469.   return (field_length > 255 ? 2 : 1)+max_length;
  3470. }
  3471.  
  3472.  
  3473. /****************************************************************************
  3474. ** VARCHAR type  (Not available for the end user yet)
  3475. ****************************************************************************/
  3476.  
  3477.  
  3478. void Field_varstring::store(const char *from,uint length)
  3479. {
  3480. #ifdef USE_TIS620
  3481.   if(!binary_flag)
  3482.   {
  3483.     ThNormalize((uchar *) ptr+2, field_length, (uchar *) from, length);
  3484.   }
  3485. #else
  3486.   if (length <= field_length)
  3487.   {
  3488.     memcpy(ptr+2,from,length);
  3489.   }
  3490.   else
  3491.   {
  3492.     length=field_length;
  3493.     memcpy(ptr+2,from,field_length);
  3494.     current_thd->cuted_fields++;
  3495.   }
  3496. #endif /* USE_TIS620 */
  3497.   int2store(ptr,length);
  3498. }
  3499.  
  3500.  
  3501. void Field_varstring::store(double nr)
  3502. {
  3503.   char buff[MAX_FIELD_WIDTH],*end;
  3504.   int width=min(field_length,DBL_DIG+5);
  3505.   sprintf(buff,"%-*.*g",width,max(width-5,0),nr);
  3506.   end=strcend(buff,' ');
  3507.   Field_varstring::store(buff,(uint) (end - buff));
  3508. }
  3509.  
  3510.  
  3511. void Field_varstring::store(longlong nr)
  3512. {
  3513.   char buff[22];
  3514.   char *end=longlong10_to_str(nr,buff,-10);
  3515.   Field_varstring::store(buff,end-buff);
  3516. }
  3517.  
  3518.  
  3519. double Field_varstring::val_real(void)
  3520. {
  3521.   double value;
  3522.   uint length=uint2korr(ptr)+2;
  3523.   char save=ptr[length];            // Ok to patch record
  3524.   ptr[length]=0;
  3525.   value=atof(ptr+2);
  3526.   ptr[length]=save;
  3527.   return value;
  3528. }
  3529.  
  3530.  
  3531. longlong Field_varstring::val_int(void)
  3532. {
  3533.   longlong value;
  3534.   uint length=uint2korr(ptr)+2;
  3535.   char save=ptr[length];            // Ok to patch record
  3536.   ptr[length]=0;
  3537.   value=strtoll(ptr+2,NULL,10);
  3538.   ptr[length]=save;
  3539.   return value;
  3540. }
  3541.  
  3542.  
  3543. String *Field_varstring::val_str(String *val_buffer __attribute__((unused)),
  3544.                  String *val_ptr)
  3545. {
  3546.   uint length=uint2korr(ptr);
  3547.   val_ptr->set((const char*) ptr+2,length);
  3548.   return val_ptr;
  3549. }
  3550.  
  3551.  
  3552. int Field_varstring::cmp(const char *a_ptr, const char *b_ptr)
  3553. {
  3554.   uint a_length=uint2korr(a_ptr);
  3555.   uint b_length=uint2korr(b_ptr);
  3556.   int diff;
  3557.   if (binary_flag)
  3558.     diff=memcmp(a_ptr+2,b_ptr+2,min(a_length,b_length));
  3559.   else
  3560.     diff=my_sortcmp(a_ptr+2,b_ptr+2,min(a_length,b_length));
  3561.   return diff ? diff : (int) (a_length - b_length);
  3562. }
  3563.  
  3564. void Field_varstring::sort_string(char *to,uint length)
  3565. {
  3566.   uint tot_length=uint2korr(ptr);
  3567.   if (binary_flag)
  3568.     memcpy((byte*) to,(byte*) ptr+2,(size_t) tot_length);
  3569.   else
  3570.   {
  3571. #ifdef USE_STRCOLL
  3572.     if (use_strcoll(default_charset_info))
  3573.       tot_length=my_strnxfrm(default_charset_info,
  3574.                              (unsigned char *) to, (unsigned char *)ptr+2,
  3575.                              length, tot_length);
  3576.     else
  3577.     {
  3578. #endif
  3579.       char *tmp=to;
  3580.       if (tot_length > length)
  3581.         tot_length=length;
  3582.       for (char *from=ptr+2,*end=from+tot_length ; from != end ;)
  3583.         *tmp++=(char) my_sort_order[(uint) (uchar) *from++];
  3584. #ifdef USE_STRCOLL
  3585.     }
  3586. #endif
  3587.   }
  3588.   if (tot_length < length)
  3589.     bzero(to+tot_length,length-tot_length);
  3590. }
  3591.  
  3592.  
  3593. void Field_varstring::sql_type(String &res) const
  3594. {
  3595.   sprintf((char*) res.ptr(),"varchar(%d)",(int) field_length);
  3596.   res.length((uint) strlen(res.ptr()));
  3597.   if (binary_flag)
  3598.     res.append(" binary");
  3599. }
  3600.  
  3601. char *Field_varstring::pack(char *to, const char *from, uint max_length)
  3602. {
  3603.   uint length=uint2korr(to);
  3604.   if (length > max_length)
  3605.     length=max_length;
  3606.   *to++= (length & 255);
  3607.   if (max_length > 255)
  3608.     *to++= (uchar) (length >> 8);
  3609.   if (length)
  3610.     memcpy(to, from+2, length);
  3611.   return to+length;
  3612. }
  3613.  
  3614.  
  3615. const char *Field_varstring::unpack(char *to, const char *from)
  3616. {
  3617.   uint length;
  3618.   if (field_length > 255)
  3619.   {
  3620.     length= (uint) (uchar) (*to= *from++);
  3621.     to[1]=0;
  3622.   }
  3623.   else
  3624.   {
  3625.     length=uint2korr(from);
  3626.     to[0] = *from++;
  3627.     to[1] = *from++;
  3628.   }
  3629.   if (length)
  3630.     memcpy(to+2, from, length);
  3631.   return from+length;
  3632. }
  3633.  
  3634.  
  3635. int Field_varstring::pack_cmp(const char *a, const char *b, uint key_length)
  3636. {
  3637.   uint a_length;
  3638.   uint b_length;
  3639.   if (key_length > 255)
  3640.   {
  3641.     a_length=uint2korr(a); a+=2;
  3642.     b_length=uint2korr(b); b+=2;
  3643.   }
  3644.   else
  3645.   {
  3646.     a_length= (uint) (uchar) *a++;
  3647.     b_length= (uint) (uchar) *b++;
  3648.   }
  3649.   if (binary_flag)
  3650.   {
  3651.     int cmp= memcmp(a,b,min(a_length,b_length));
  3652.     return cmp ? cmp : (int) (a_length - b_length);
  3653.   }
  3654.   return my_sortncmp(a,a_length, b,b_length);
  3655. }
  3656.  
  3657. int Field_varstring::pack_cmp(const char *b, uint key_length)
  3658. {
  3659.   char *a=ptr+2;
  3660.   uint a_length=uint2korr(ptr);
  3661.   uint b_length;
  3662.   if (key_length > 255)
  3663.   {
  3664.     b_length=uint2korr(b); b+=2;
  3665.   }
  3666.   else
  3667.   {
  3668.     b_length= (uint) (uchar) *b++;
  3669.   }
  3670.   if (binary_flag)
  3671.   {
  3672.     int cmp= memcmp(a,b,min(a_length,b_length));
  3673.     return cmp ? cmp : (int) (a_length - b_length);
  3674.   }
  3675.   return my_sortncmp(a,a_length, b,b_length);
  3676. }
  3677.  
  3678. uint Field_varstring::packed_col_length(const char *ptr)
  3679. {
  3680.   if (field_length > 255)
  3681.     return uint2korr(ptr)+2;
  3682.   else
  3683.     return (uint) ((uchar) *ptr)+1;
  3684. }
  3685.  
  3686. uint Field_varstring::max_packed_col_length(uint max_length)
  3687. {
  3688.   return (field_length > 255 ? 2 : 1)+max_length;
  3689. }
  3690.  
  3691. /****************************************************************************
  3692. ** blob type
  3693. ** A blob is saved as a length and a pointer. The length is stored in the
  3694. ** packlength slot and may be from 1-4.
  3695. ****************************************************************************/
  3696.  
  3697. Field_blob::Field_blob(char *ptr_arg, uchar *null_ptr_arg, uint null_bit_arg,
  3698.                enum utype unireg_check_arg, const char *field_name_arg,
  3699.                struct st_table *table_arg,uint blob_pack_length,
  3700.                bool binary_arg)
  3701.   :Field_str(ptr_arg, (1L << min(blob_pack_length,3)*8)-1L,
  3702.          null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg,
  3703.          table_arg),
  3704.    packlength(blob_pack_length),binary_flag(binary_arg)
  3705. {
  3706.   flags|= BLOB_FLAG;
  3707.   if (binary_arg)
  3708.     flags|=BINARY_FLAG;
  3709.   if (table)
  3710.     table->blob_fields++;
  3711. }
  3712.  
  3713.  
  3714. void Field_blob::store_length(ulong number)
  3715. {
  3716.   switch (packlength) {
  3717.   case 1:
  3718.     if (number > 255)
  3719.     {
  3720.       number=255;
  3721.       current_thd->cuted_fields++;
  3722.     }
  3723.     ptr[0]= (uchar) number;
  3724.     break;
  3725.   case 2:
  3726.     if (number > (uint16) ~0)
  3727.     {
  3728.       number= (uint16) ~0;
  3729.       current_thd->cuted_fields++;
  3730.     }
  3731. #ifdef WORDS_BIGENDIAN
  3732.     if (table->db_low_byte_first)
  3733.     {
  3734.       int2store(ptr,(unsigned short) number);
  3735.     }
  3736.     else
  3737. #endif
  3738.       shortstore(ptr,(unsigned short) number);
  3739.     break;
  3740.   case 3:
  3741.     if (number > (ulong) (1L << 24))
  3742.     {
  3743.       number= (ulong) (1L << 24)-1L;
  3744.       current_thd->cuted_fields++;
  3745.     }
  3746.     int3store(ptr,number);
  3747.     break;
  3748.   case 4:
  3749. #ifdef WORDS_BIGENDIAN
  3750.     if (table->db_low_byte_first)
  3751.     {
  3752.       int4store(ptr,number);
  3753.     }
  3754.     else
  3755. #endif
  3756.       longstore(ptr,number);
  3757.   }
  3758. }
  3759.  
  3760.  
  3761. ulong Field_blob::get_length(const char *pos)
  3762. {
  3763.   switch (packlength) {
  3764.   case 1:
  3765.     return (ulong) (uchar) pos[0];
  3766.   case 2:
  3767.     {
  3768.       uint16 tmp;
  3769. #ifdef WORDS_BIGENDIAN
  3770.       if (table->db_low_byte_first)
  3771.     tmp=sint2korr(pos);
  3772.       else
  3773. #endif
  3774.     shortget(tmp,pos);
  3775.       return (ulong) tmp;
  3776.     }
  3777.   case 3:
  3778.     return (ulong) uint3korr(pos);
  3779.   case 4:
  3780.     {
  3781.       uint32 tmp;
  3782. #ifdef WORDS_BIGENDIAN
  3783.       if (table->db_low_byte_first)
  3784.     tmp=uint4korr(pos);
  3785.       else
  3786. #endif
  3787.     longget(tmp,pos);
  3788.       return (ulong) tmp;
  3789.     }
  3790.   }
  3791.   return 0;                    // Impossible
  3792. }
  3793.  
  3794.  
  3795. void Field_blob::store(const char *from,uint len)
  3796. {
  3797.   if (!len)
  3798.   {
  3799.     bzero(ptr,Field_blob::pack_length());
  3800.   }
  3801.   else
  3802.   {
  3803. #ifdef USE_TIS620
  3804.     char *th_ptr=0;
  3805. #endif
  3806.     Field_blob::store_length(len);
  3807.     if (table->copy_blobs || len <= MAX_FIELD_WIDTH)
  3808.     {                        // Must make a copy
  3809. #ifdef USE_TIS620
  3810.       if(!binary_flag)
  3811.       {
  3812.     /* If there isn't enough memory, use original string */
  3813.     if ((th_ptr=(char * ) my_malloc(sizeof(char) * len,MYF(0))))
  3814.     {
  3815.       ThNormalize((uchar *) th_ptr, len, (uchar *) from, len);
  3816.       from= (const char*) th_ptr;
  3817.     }
  3818.       }
  3819. #endif /* USE_TIS620 */
  3820.       value.copy(from,len);
  3821.       from=value.ptr();
  3822. #ifdef USE_TIS620
  3823.       my_free(th_ptr,MYF(MY_ALLOW_ZERO_PTR));
  3824. #endif
  3825.     }
  3826.     bmove(ptr+packlength,(char*) &from,sizeof(char*));
  3827.   }
  3828. }
  3829.  
  3830.  
  3831. void Field_blob::store(double nr)
  3832. {
  3833.   value.set(nr);
  3834.   Field_blob::store(value.ptr(),value.length());
  3835. }
  3836.  
  3837.  
  3838. void Field_blob::store(longlong nr)
  3839. {
  3840.   value.set(nr);
  3841.   Field_blob::store(value.ptr(),value.length());
  3842. }
  3843.  
  3844.  
  3845. double Field_blob::val_real(void)
  3846. {
  3847.   char *blob;
  3848.  
  3849.   memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
  3850.   if (!blob)
  3851.     return 0.0;
  3852.   ulong length=get_length(ptr);
  3853.  
  3854.   char save=blob[length];            // Ok to patch blob in NISAM
  3855.   blob[length]=0;
  3856.   double nr=atof(blob);
  3857.   blob[length]=save;
  3858.   return nr;
  3859. }
  3860.  
  3861.  
  3862. longlong Field_blob::val_int(void)
  3863. {
  3864.   char *blob;
  3865.   memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
  3866.   if (!blob)
  3867.     return 0;
  3868.   ulong length=get_length(ptr);
  3869.  
  3870.   char save=blob[length];            // Ok to patch blob in NISAM
  3871.   blob[length]=0;
  3872.   longlong nr=strtoll(blob,NULL,10);
  3873.   blob[length]=save;
  3874.   return nr;
  3875. }
  3876.  
  3877.  
  3878. String *Field_blob::val_str(String *val_buffer __attribute__((unused)),
  3879.                 String *val_ptr)
  3880. {
  3881.   char *blob;
  3882.   memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
  3883.   if (!blob)
  3884.     val_ptr->length(0);
  3885.   else
  3886.     val_ptr->set((const char*) blob,get_length(ptr));
  3887.   return val_ptr;
  3888. }
  3889.  
  3890.  
  3891. int Field_blob::cmp(const char *a,ulong a_length, const char *b,
  3892.             ulong b_length)
  3893. {
  3894.   int diff;
  3895.   if (binary_flag)
  3896.     diff=memcmp(a,b,min(a_length,b_length));
  3897.   else
  3898.     diff=my_sortcmp(a,b,min(a_length,b_length));
  3899.   return diff ? diff : (int) (a_length - b_length);
  3900. }
  3901.  
  3902.  
  3903. int Field_blob::cmp(const char *a_ptr, const char *b_ptr)
  3904. {
  3905.   char *blob1,*blob2;
  3906.   memcpy_fixed(&blob1,a_ptr+packlength,sizeof(char*));
  3907.   memcpy_fixed(&blob2,b_ptr+packlength,sizeof(char*));
  3908.   return Field_blob::cmp(blob1,get_length(a_ptr),
  3909.              blob2,get_length(b_ptr));
  3910. }
  3911.  
  3912.  
  3913. int Field_blob::cmp_offset(uint row_offset)
  3914. {
  3915.   return Field_blob::cmp(ptr,ptr+row_offset);
  3916. }
  3917.  
  3918.  
  3919. int Field_blob::cmp_binary_offset(uint row_offset)
  3920. {
  3921.   return cmp_binary(ptr, ptr+row_offset);
  3922. }
  3923.  
  3924.  
  3925. int Field_blob::cmp_binary(const char *a_ptr, const char *b_ptr,
  3926.                ulong max_length)
  3927. {
  3928.   char *a,*b;
  3929.   uint diff;
  3930.   ulong a_length,b_length;
  3931.   memcpy_fixed(&a,a_ptr+packlength,sizeof(char*));
  3932.   memcpy_fixed(&b,b_ptr+packlength,sizeof(char*));
  3933.   a_length=get_length(a_ptr);
  3934.   if (a_length > max_length)
  3935.     a_length=max_length;
  3936.   b_length=get_length(b_ptr);
  3937.   if (b_length > max_length)
  3938.     b_length=max_length;
  3939.   diff=memcmp(a,b,min(a_length,b_length));
  3940.   return diff ? diff : (int) (a_length - b_length);
  3941. }
  3942.  
  3943.  
  3944. /* The following is used only when comparing a key */
  3945.  
  3946. void Field_blob::get_key_image(char *buff,uint length)
  3947. {
  3948.   length-=HA_KEY_BLOB_LENGTH;
  3949.   ulong blob_length=get_length(ptr);
  3950.   char *blob;
  3951.   if ((ulong) length > blob_length)
  3952.     length=(uint) blob_length;
  3953.   int2store(buff,length);
  3954.   get_ptr(&blob);
  3955.   memcpy(buff+2,blob,length);
  3956. }
  3957.  
  3958. void Field_blob::set_key_image(char *buff,uint length)
  3959. {
  3960.   length=uint2korr(buff);
  3961.   Field_blob::store(buff+2,length);
  3962. }
  3963.  
  3964. int Field_blob::key_cmp(const byte *key_ptr, uint max_key_length)
  3965. {
  3966.   char *blob1;
  3967.   uint blob_length=get_length(ptr);
  3968.   max_key_length-=2;
  3969.   memcpy_fixed(&blob1,ptr+packlength,sizeof(char*));
  3970.   return Field_blob::cmp(blob1,min(blob_length, max_key_length),
  3971.              (char*) key_ptr+2,uint2korr(key_ptr));
  3972. }
  3973.  
  3974. int Field_blob::key_cmp(const byte *a,const byte *b)
  3975. {
  3976.   return Field_blob::cmp((char*) a+2,uint2korr(a),
  3977.              (char*) b+2,uint2korr(b));
  3978. }
  3979.  
  3980.  
  3981. void Field_blob::sort_string(char *to,uint length)
  3982. {
  3983.   char *blob;
  3984.   uint blob_length=get_length();
  3985. #ifdef USE_STRCOLL
  3986.   uint blob_org_length=blob_length;
  3987. #endif
  3988.   if (!blob_length)
  3989.     bzero(to,length);
  3990.   else
  3991.   {
  3992.     if (blob_length > length)
  3993.       blob_length=length;
  3994.     memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
  3995.     if (binary_flag)
  3996.     {
  3997.       memcpy(to,blob,blob_length);
  3998.       to+=blob_length;
  3999.     }
  4000.     else
  4001.     {
  4002. #ifdef USE_STRCOLL
  4003.       if (use_strcoll(default_charset_info))
  4004.       {
  4005.         blob_length=my_strnxfrm(default_charset_info,
  4006.                                 (unsigned char *)to,(unsigned char *)blob,
  4007.                                 length,blob_org_length);
  4008.         if (blob_length >= length)
  4009.           return;
  4010.         to+=blob_length;
  4011.       }
  4012.       else
  4013. #endif
  4014.         for (char *end=blob+blob_length ; blob != end ;)
  4015.           *to++=(char) my_sort_order[(uint) (uchar) *blob++];
  4016.     }
  4017.     bzero(to,length-blob_length);
  4018.   }
  4019. }
  4020.  
  4021.  
  4022. void Field_blob::sql_type(String &res) const
  4023. {
  4024.   const char *str;
  4025.   switch (packlength) {
  4026.   default: str="tiny"; break;
  4027.   case 2:  str=""; break;
  4028.   case 3:  str="medium"; break;
  4029.   case 4:  str="long"; break;
  4030.   }
  4031.   res.set(str,(uint) strlen(str));
  4032.   res.append(binary_flag ? "blob" : "text");
  4033. }
  4034.  
  4035.  
  4036. /* Keys for blobs are like keys on varchars */
  4037.  
  4038. int Field_blob::pack_cmp(const char *a, const char *b, uint key_length)
  4039. {
  4040.   uint a_length;
  4041.   uint b_length;
  4042.   if (key_length > 255)
  4043.   {
  4044.     a_length=uint2korr(a); a+=2;
  4045.     b_length=uint2korr(b); b+=2;
  4046.   }
  4047.   else
  4048.   {
  4049.     a_length= (uint) (uchar) *a++;
  4050.     b_length= (uint) (uchar) *b++;
  4051.   }
  4052.   if (binary_flag)
  4053.   {
  4054.     int cmp= memcmp(a,b,min(a_length,b_length));
  4055.     return cmp ? cmp : (int) (a_length - b_length);
  4056.   }
  4057.   return my_sortncmp(a,a_length, b,b_length);
  4058. }
  4059.  
  4060.  
  4061. int Field_blob::pack_cmp(const char *b, uint key_length)
  4062. {
  4063.   char *a;
  4064.   memcpy_fixed(&a,ptr+packlength,sizeof(char*));
  4065.   if (!a)
  4066.     return key_length > 0 ? -1 : 0;
  4067.   uint a_length=get_length(ptr);
  4068.   uint b_length;
  4069.  
  4070.   if (key_length > 255)
  4071.   {
  4072.     b_length=uint2korr(b); b+=2;
  4073.   }
  4074.   else
  4075.   {
  4076.     b_length= (uint) (uchar) *b++;
  4077.   }
  4078.   if (binary_flag)
  4079.   {
  4080.     int cmp= memcmp(a,b,min(a_length,b_length));
  4081.     return cmp ? cmp : (int) (a_length - b_length);
  4082.   }
  4083.   return my_sortncmp(a,a_length, b,b_length);
  4084. }
  4085.  
  4086.  
  4087. char *Field_blob::pack_key(char *to, const char *from, uint max_length)
  4088. {
  4089.   uint length=uint2korr(to);
  4090.   if (length > max_length)
  4091.     length=max_length;
  4092.   *to++= (length & 255);
  4093.   if (max_length > 255)
  4094.     *to++= (uchar) (length >> 8);
  4095.   if (length)
  4096.     memcpy(to, from+2, length);
  4097.   return to+length;
  4098. }
  4099.  
  4100. /****************************************************************************
  4101. ** enum type.
  4102. ** This is a string which only can have a selection of different values.
  4103. ** If one uses this string in a number context one gets the type number.
  4104. ****************************************************************************/
  4105.  
  4106. enum ha_base_keytype Field_enum::key_type() const
  4107. {
  4108.   switch (packlength) {
  4109.   default: return HA_KEYTYPE_BINARY;
  4110.   case 2: return HA_KEYTYPE_USHORT_INT;
  4111.   case 3: return HA_KEYTYPE_UINT24;
  4112.   case 4: return HA_KEYTYPE_ULONG_INT;
  4113.   case 8: return HA_KEYTYPE_ULONGLONG;
  4114.   }
  4115. }
  4116.  
  4117. void Field_enum::store_type(ulonglong value)
  4118. {
  4119.   switch (packlength) {
  4120.   case 1: ptr[0]= (uchar) value;  break;
  4121.   case 2:
  4122. #ifdef WORDS_BIGENDIAN
  4123.   if (table->db_low_byte_first)
  4124.   {
  4125.     int2store(ptr,(unsigned short) value);
  4126.   }
  4127.   else
  4128. #endif
  4129.     shortstore(ptr,(unsigned short) value);
  4130.   break;
  4131.   case 3: int3store(ptr,(long) value); break;
  4132.   case 4:
  4133. #ifdef WORDS_BIGENDIAN
  4134.   if (table->db_low_byte_first)
  4135.   {
  4136.     int4store(ptr,value);
  4137.   }
  4138.   else
  4139. #endif
  4140.     longstore(ptr,(long) value);
  4141.   break;
  4142.   case 8:
  4143. #ifdef WORDS_BIGENDIAN
  4144.   if (table->db_low_byte_first)
  4145.   {
  4146.     int8store(ptr,value);
  4147.   }
  4148.   else
  4149. #endif
  4150.     longlongstore(ptr,value); break;
  4151.   }
  4152. }
  4153.  
  4154.  
  4155. uint find_enum(TYPELIB *lib,const char *x, uint length)
  4156. {
  4157.   const char *end=x+length;
  4158.   while (end > x && isspace(end[-1]))
  4159.     end--;
  4160.  
  4161.   const char *i;
  4162.   const char *j;
  4163.   for (uint pos=0 ; (j=lib->type_names[pos]) ; pos++)
  4164.   {
  4165.     for (i=x ; i != end && toupper(*i) == toupper(*j) ; i++, j++) ;
  4166.     if (i == end && ! *j)
  4167.       return(pos+1);
  4168.   }
  4169.   return(0);
  4170. }
  4171.  
  4172.  
  4173. /*
  4174. ** Note. Storing a empty string in a enum field gives a warning
  4175. ** (if there isn't a empty value in the enum)
  4176. */
  4177.  
  4178. void Field_enum::store(const char *from,uint length)
  4179. {
  4180.   uint tmp=find_enum(typelib,from,length);
  4181.   {
  4182.     if (!tmp)
  4183.     {
  4184.       current_thd->cuted_fields++;
  4185.       Field_enum::store_type((longlong) 0);
  4186.     }
  4187.     else
  4188.       store_type((ulonglong) tmp);
  4189.   }
  4190. }
  4191.  
  4192.  
  4193. void Field_enum::store(double nr)
  4194. {
  4195.   Field_enum::store((longlong) nr);
  4196. }
  4197.  
  4198.  
  4199. void Field_enum::store(longlong nr)
  4200. {
  4201.   if ((uint) nr > typelib->count || nr == 0)
  4202.   {
  4203.     current_thd->cuted_fields++;
  4204.     nr=0;
  4205.   }
  4206.   store_type((ulonglong) (uint) nr);
  4207. }
  4208.  
  4209.  
  4210. double Field_enum::val_real(void)
  4211. {
  4212.   return (double) Field_enum::val_int();
  4213. }
  4214.  
  4215.  
  4216. longlong Field_enum::val_int(void)
  4217. {
  4218.   switch (packlength) {
  4219.   case 1:
  4220.     return (longlong) (uchar) ptr[0];
  4221.   case 2:
  4222.     {
  4223.       uint16 tmp;
  4224. #ifdef WORDS_BIGENDIAN
  4225.       if (table->db_low_byte_first)
  4226.     tmp=sint2korr(ptr);
  4227.       else
  4228. #endif
  4229.     shortget(tmp,ptr);
  4230.       return (longlong) tmp;
  4231.     }
  4232.   case 3:
  4233.     return (longlong) uint3korr(ptr);
  4234.   case 4:
  4235.     {
  4236.       uint32 tmp;
  4237. #ifdef WORDS_BIGENDIAN
  4238.       if (table->db_low_byte_first)
  4239.     tmp=uint4korr(ptr);
  4240.       else
  4241. #endif
  4242.     longget(tmp,ptr);
  4243.       return (longlong) tmp;
  4244.     }
  4245.   case 8:
  4246.     {
  4247.       longlong tmp;
  4248. #ifdef WORDS_BIGENDIAN
  4249.       if (table->db_low_byte_first)
  4250.     tmp=sint8korr(ptr);
  4251.       else
  4252. #endif
  4253.     longlongget(tmp,ptr);
  4254.       return tmp;
  4255.     }
  4256.   }
  4257.   return 0;                    // impossible
  4258. }
  4259.  
  4260.  
  4261. String *Field_enum::val_str(String *val_buffer __attribute__((unused)),
  4262.                 String *val_ptr)
  4263. {
  4264.   uint tmp=(uint) Field_enum::val_int();
  4265.   if (!tmp || tmp > typelib->count)
  4266.     val_ptr->length(0);
  4267.   else
  4268.     val_ptr->set((const char*) typelib->type_names[tmp-1],
  4269.          (uint) strlen(typelib->type_names[tmp-1]));
  4270.   return val_ptr;
  4271. }
  4272.  
  4273. int Field_enum::cmp(const char *a_ptr, const char *b_ptr)
  4274. {
  4275.   char *old=ptr;
  4276.   ptr=(char*) a_ptr;
  4277.   ulonglong a=Field_enum::val_int();
  4278.   ptr=(char*) b_ptr;
  4279.   ulonglong b=Field_enum::val_int();
  4280.   ptr=old;
  4281.   return (a < b) ? -1 : (a > b) ? 1 : 0;
  4282. }
  4283.  
  4284. void Field_enum::sort_string(char *to,uint length __attribute__((unused)))
  4285. {
  4286.   ulonglong value=Field_enum::val_int();
  4287.   to+=packlength-1;
  4288.   for (uint i=0 ; i < packlength ; i++)
  4289.   {
  4290.     *to-- = (uchar) (value & 255);
  4291.     value>>=8;
  4292.   }
  4293. }
  4294.  
  4295.  
  4296. void Field_enum::sql_type(String &res) const
  4297. {
  4298.   res.length(0);
  4299.   res.append("enum(");
  4300.  
  4301.   bool flag=0;
  4302.   for (const char **pos=typelib->type_names; *pos ; pos++)
  4303.   {
  4304.     if (flag)
  4305.       res.append(',');
  4306.     res.append('\'');
  4307.     append_unescaped(&res,*pos);
  4308.     res.append('\'');
  4309.     flag=1;
  4310.   }
  4311.   res.append(')');
  4312. }
  4313.  
  4314.  
  4315. /****************************************************************************
  4316. ** set type.
  4317. ** This is a string which can have a collection of different values.
  4318. ** Each string value is separated with a ','.
  4319. ** For example "One,two,five"
  4320. ** If one uses this string in a number context one gets the bits as a longlong
  4321. ** number.
  4322. ****************************************************************************/
  4323.  
  4324. ulonglong find_set(TYPELIB *lib,const char *x,uint length)
  4325. {
  4326.   const char *end=x+length;
  4327.   while (end > x && isspace(end[-1]))
  4328.     end--;
  4329.  
  4330.   ulonglong found=0;
  4331.   if (x != end)
  4332.   {
  4333.     const char *start=x;
  4334.     bool error=0;
  4335.     for (;;)
  4336.     {
  4337.       const char *pos=start;
  4338.       for ( ; pos != end && *pos != field_separator ; pos++) ;
  4339.       uint find=find_enum(lib,start,(uint) (pos-start));
  4340.       if (!find)
  4341.     error=1;
  4342.       else
  4343.     found|= ((longlong) 1 << (find-1));
  4344.       if (pos == end)
  4345.     break;
  4346.       start=pos+1;
  4347.     }
  4348.     if (error)
  4349.       current_thd->cuted_fields++;
  4350.   }
  4351.   return found;
  4352. }
  4353.  
  4354.  
  4355. void Field_set::store(const char *from,uint length)
  4356. {
  4357.   store_type(find_set(typelib,from,length));
  4358. }
  4359.  
  4360.  
  4361. void Field_set::store(longlong nr)
  4362. {
  4363.   if ((ulonglong) nr > (ulonglong) (((longlong) 1 << typelib->count) -
  4364.                     (longlong) 1))
  4365.   {
  4366.     nr&= (longlong) (((longlong) 1 << typelib->count) - (longlong) 1);
  4367.     current_thd->cuted_fields++;
  4368.   }
  4369.   store_type((ulonglong) nr);
  4370. }
  4371.  
  4372.  
  4373. String *Field_set::val_str(String *val_buffer,
  4374.                String *val_ptr __attribute__((unused)))
  4375. {
  4376.   ulonglong tmp=(ulonglong) Field_enum::val_int();
  4377.   uint bitnr=0;
  4378.  
  4379.   val_buffer->length(0);
  4380.   while (tmp && bitnr < (uint) typelib->count)
  4381.   {
  4382.     if (tmp & 1)
  4383.     {
  4384.       if (val_buffer->length())
  4385.     val_buffer->append(field_separator);
  4386.       String str(typelib->type_names[bitnr],
  4387.          (uint) strlen(typelib->type_names[bitnr]));
  4388.       val_buffer->append(str);
  4389.     }
  4390.     tmp>>=1;
  4391.     bitnr++;
  4392.   }
  4393.   return val_buffer;
  4394. }
  4395.  
  4396.  
  4397. void Field_set::sql_type(String &res) const
  4398. {
  4399.   res.length(0);
  4400.   res.append("set(");
  4401.  
  4402.   bool flag=0;
  4403.   for (const char **pos=typelib->type_names; *pos ; pos++)
  4404.   {
  4405.     if (flag)
  4406.       res.append(',');
  4407.     res.append('\'');
  4408.     append_unescaped(&res,*pos);
  4409.     res.append('\'');
  4410.     flag=1;
  4411.   }
  4412.   res.append(')');
  4413. }
  4414.  
  4415. /* returns 1 if the fields are equally defined */
  4416.  
  4417. bool Field::eq_def(Field *field)
  4418. {
  4419.   if (real_type() != field->real_type() || binary() != field->binary() ||
  4420.       pack_length() != field->pack_length())
  4421.     return 0;
  4422.   return 1;
  4423. }
  4424.  
  4425. bool Field_enum::eq_def(Field *field)
  4426. {
  4427.   if (!Field::eq_def(field))
  4428.     return 0;
  4429.   TYPELIB *from_lib=((Field_enum*) field)->typelib;
  4430.   
  4431.   if (typelib->count < from_lib->count)
  4432.     return 0;
  4433.   for (uint i=0 ; i < from_lib->count ; i++)
  4434.     if (my_strcasecmp(typelib->type_names[i],from_lib->type_names[i]))
  4435.       return 0;
  4436.   return 1;
  4437. }
  4438.  
  4439. bool Field_num::eq_def(Field *field)
  4440. {  
  4441.   if (!Field::eq_def(field))
  4442.     return 0;
  4443.   Field_num *from_num= (Field_num*) field;
  4444.  
  4445.   if (unsigned_flag != from_num->unsigned_flag ||
  4446.       zerofill && !from_num->zerofill && !zero_pack() ||
  4447.       dec != from_num->dec)
  4448.     return 0;
  4449.   return 1;
  4450. }
  4451.  
  4452.  
  4453. /*****************************************************************************
  4454. ** Handling of field and create_field
  4455. *****************************************************************************/
  4456.  
  4457. /*
  4458. ** Make a field from the .frm file info
  4459. */
  4460.  
  4461. uint32 calc_pack_length(enum_field_types type,uint32 length)
  4462. {
  4463.   switch (type) {
  4464.   case FIELD_TYPE_STRING:
  4465.   case FIELD_TYPE_DECIMAL: return (length);
  4466.   case FIELD_TYPE_VAR_STRING: return (length+2);
  4467.   case FIELD_TYPE_YEAR:
  4468.   case FIELD_TYPE_TINY    : return 1;
  4469.   case FIELD_TYPE_SHORT : return 2;
  4470.   case FIELD_TYPE_INT24:
  4471.   case FIELD_TYPE_NEWDATE:
  4472.   case FIELD_TYPE_TIME:   return 3;
  4473.   case FIELD_TYPE_TIMESTAMP:
  4474.   case FIELD_TYPE_DATE:
  4475.   case FIELD_TYPE_LONG    : return 4;
  4476.   case FIELD_TYPE_FLOAT : return sizeof(float);
  4477.   case FIELD_TYPE_DOUBLE: return sizeof(double);
  4478.   case FIELD_TYPE_DATETIME:
  4479.   case FIELD_TYPE_LONGLONG: return 8;    /* Don't crash if no longlong */
  4480.   case FIELD_TYPE_NULL    : return 0;
  4481.   case FIELD_TYPE_TINY_BLOB:    return 1+portable_sizeof_char_ptr;
  4482.   case FIELD_TYPE_BLOB:        return 2+portable_sizeof_char_ptr;
  4483.   case FIELD_TYPE_MEDIUM_BLOB:    return 3+portable_sizeof_char_ptr;
  4484.   case FIELD_TYPE_LONG_BLOB:    return 4+portable_sizeof_char_ptr;
  4485.   case FIELD_TYPE_SET:
  4486.   case FIELD_TYPE_ENUM: abort(); return 0;    // This shouldn't happen
  4487.   }
  4488.   return 0;                    // This shouldn't happen
  4489. }
  4490.  
  4491.  
  4492. uint pack_length_to_packflag(uint type)
  4493. {
  4494.   switch (type) {
  4495.     case 1: return f_settype((uint) FIELD_TYPE_TINY);
  4496.     case 2: return f_settype((uint) FIELD_TYPE_SHORT);
  4497.     case 3: return f_settype((uint) FIELD_TYPE_INT24);
  4498.     case 4: return f_settype((uint) FIELD_TYPE_LONG);
  4499.     case 8: return f_settype((uint) FIELD_TYPE_LONGLONG);
  4500.   }
  4501.   return 0;                    // This shouldn't happen
  4502. }
  4503.  
  4504.  
  4505. Field *make_field(char *ptr, uint32 field_length,
  4506.           uchar *null_pos, uint null_bit,
  4507.           uint pack_flag,
  4508.           Field::utype unireg_check,
  4509.           TYPELIB *interval,
  4510.           const char *field_name,
  4511.           struct st_table *table)
  4512. {
  4513.   if (!f_maybe_null(pack_flag))
  4514.   {
  4515.     null_pos=0;
  4516.     null_bit=0;
  4517.   }
  4518.   if (f_is_alpha(pack_flag))
  4519.   {
  4520.     if (!f_is_packed(pack_flag))
  4521.       return new Field_string(ptr,field_length,null_pos,null_bit,
  4522.                   unireg_check, field_name, table,
  4523.                   f_is_binary(pack_flag) != 0);
  4524.  
  4525.     uint pack_length=calc_pack_length((enum_field_types)
  4526.                       f_packtype(pack_flag),
  4527.                       field_length);
  4528.  
  4529.     if (f_is_blob(pack_flag))
  4530.       return new Field_blob(ptr,null_pos,null_bit,
  4531.                 unireg_check, field_name, table,
  4532.                 pack_length,f_is_binary(pack_flag) != 0);
  4533.     if (interval)
  4534.     {
  4535.       if (f_is_enum(pack_flag))
  4536.     return new Field_enum(ptr,field_length,null_pos,null_bit,
  4537.                   unireg_check, field_name, table,
  4538.                   pack_length, interval);
  4539.       else
  4540.     return new Field_set(ptr,field_length,null_pos,null_bit,
  4541.                  unireg_check, field_name, table,
  4542.                  pack_length, interval);
  4543.     }
  4544.   }
  4545.  
  4546.   switch ((enum enum_field_types) f_packtype(pack_flag)) {
  4547.   case FIELD_TYPE_DECIMAL:
  4548.     return new Field_decimal(ptr,field_length,null_pos,null_bit,
  4549.                  unireg_check, field_name, table,
  4550.                  f_decimals(pack_flag),
  4551.                  f_is_zerofill(pack_flag) != 0,
  4552.                  f_is_dec(pack_flag) == 0);
  4553.   case FIELD_TYPE_FLOAT:
  4554.     return new Field_float(ptr,field_length,null_pos,null_bit,
  4555.                unireg_check, field_name, table,
  4556.                f_decimals(pack_flag),
  4557.                f_is_zerofill(pack_flag) != 0,
  4558.                f_is_dec(pack_flag)== 0);
  4559.   case FIELD_TYPE_DOUBLE:
  4560.     return new Field_double(ptr,field_length,null_pos,null_bit,
  4561.                 unireg_check, field_name, table,
  4562.                 f_decimals(pack_flag),
  4563.                 f_is_zerofill(pack_flag) != 0,
  4564.                 f_is_dec(pack_flag)== 0);
  4565.   case FIELD_TYPE_TINY:
  4566.     return new Field_tiny(ptr,field_length,null_pos,null_bit,
  4567.               unireg_check, field_name, table,
  4568.               f_is_zerofill(pack_flag) != 0,
  4569.               f_is_dec(pack_flag) == 0);
  4570.   case FIELD_TYPE_SHORT:
  4571.     return new Field_short(ptr,field_length,null_pos,null_bit,
  4572.                unireg_check, field_name, table,
  4573.                f_is_zerofill(pack_flag) != 0,
  4574.                f_is_dec(pack_flag) == 0);
  4575.   case FIELD_TYPE_INT24:
  4576.     return new Field_medium(ptr,field_length,null_pos,null_bit,
  4577.                 unireg_check, field_name, table,
  4578.                 f_is_zerofill(pack_flag) != 0,
  4579.                 f_is_dec(pack_flag) == 0);
  4580.   case FIELD_TYPE_LONG:
  4581.     return new Field_long(ptr,field_length,null_pos,null_bit,
  4582.                unireg_check, field_name, table,
  4583.                f_is_zerofill(pack_flag) != 0,
  4584.                f_is_dec(pack_flag) == 0);
  4585.   case FIELD_TYPE_LONGLONG:
  4586.     return new Field_longlong(ptr,field_length,null_pos,null_bit,
  4587.                   unireg_check, field_name, table,
  4588.                   f_is_zerofill(pack_flag) != 0,
  4589.                   f_is_dec(pack_flag) == 0);
  4590.   case FIELD_TYPE_TIMESTAMP:
  4591.     return new Field_timestamp(ptr,field_length,
  4592.                    unireg_check, field_name, table);
  4593.   case FIELD_TYPE_YEAR:
  4594.     return new Field_year(ptr,field_length,null_pos,null_bit,
  4595.               unireg_check, field_name, table);
  4596.   case FIELD_TYPE_DATE:
  4597.     return new Field_date(ptr,null_pos,null_bit,
  4598.               unireg_check, field_name, table);
  4599.   case FIELD_TYPE_NEWDATE:
  4600.     return new Field_newdate(ptr,null_pos,null_bit,
  4601.                  unireg_check, field_name, table);
  4602.   case FIELD_TYPE_TIME:
  4603.     return new Field_time(ptr,null_pos,null_bit,
  4604.               unireg_check, field_name, table);
  4605.   case FIELD_TYPE_DATETIME:
  4606.     return new Field_datetime(ptr,null_pos,null_bit,
  4607.                   unireg_check, field_name, table);
  4608.   case FIELD_TYPE_NULL:
  4609.     default:                    // Impossible (Wrong version)
  4610.     return new Field_null(ptr,field_length,unireg_check,field_name,table);
  4611.   }
  4612.   return 0;                    // Impossible (Wrong version)
  4613. }
  4614.  
  4615.  
  4616. /* Create a field suitable for create of table */
  4617.  
  4618. create_field::create_field(Field *old_field,Field *orig_field)
  4619. {
  4620.   field=      old_field;
  4621.   field_name=change=old_field->field_name;
  4622.   length=     old_field->field_length;
  4623.   flags=      old_field->flags;
  4624.   unireg_check=old_field->unireg_check;
  4625.   pack_length=old_field->pack_length();
  4626.   sql_type=   old_field->real_type();
  4627.  
  4628.   /* Fix if the original table had 4 byte pointer blobs */
  4629.   if (flags & BLOB_FLAG)
  4630.     pack_length= (pack_length- old_field->table->blob_ptr_size +
  4631.           portable_sizeof_char_ptr);
  4632.   decimals= old_field->decimals();
  4633.   if (sql_type == FIELD_TYPE_STRING)
  4634.   {
  4635.     sql_type=old_field->type();
  4636.     decimals=0;
  4637.   }
  4638.   if (flags & (ENUM_FLAG | SET_FLAG))
  4639.     interval= ((Field_enum*) old_field)->typelib;
  4640.   else
  4641.     interval=0;
  4642.   def=0;
  4643.   if (!old_field->is_real_null() && ! (flags & BLOB_FLAG) &&
  4644.       old_field->type() != FIELD_TYPE_TIMESTAMP && old_field->ptr &&
  4645.       orig_field)
  4646.   {
  4647.     char buff[MAX_FIELD_WIDTH],*pos;
  4648.     String tmp(buff,sizeof(buff)),*res;
  4649.  
  4650.     /* Get the value from record[2] (the default value row) */
  4651.     my_ptrdiff_t diff= (my_ptrdiff_t) (orig_field->table->rec_buff_length*2);
  4652.     orig_field->move_field(diff);        // Points now at record[2]
  4653.     bool is_null=orig_field->is_real_null();
  4654.     res=orig_field->val_str(&tmp,&tmp);
  4655.     orig_field->move_field(-diff);        // Back to record[0]
  4656.     if (!is_null)
  4657.     {
  4658.       pos= (char*) sql_memdup(tmp.ptr(),tmp.length()+1);
  4659.       pos[tmp.length()]=0;
  4660.       def=new Item_string(pos,tmp.length());
  4661.     }
  4662.   }
  4663. }
  4664.