static void convert_from_long(MYSQL_BIND *r_param, const MYSQL_FIELD *field, longlong val, my_bool is_unsigned)
{
  switch (r_param->buffer_type) {
    case MYSQL_TYPE_TINY:
      *(uchar *)r_param->buffer= (uchar)val;
      *r_param->error= r_param->is_unsigned ? NUMERIC_TRUNCATION(val, 0, UINT_MAX8) : NUMERIC_TRUNCATION(val, INT_MIN8, INT_MAX8);
      r_param->buffer_length= 1;
      break;
    case MYSQL_TYPE_SHORT:
    case MYSQL_TYPE_YEAR:
      shortstore(r_param->buffer, (short)val);
      *r_param->error= r_param->is_unsigned ? NUMERIC_TRUNCATION(val, 0, UINT_MAX16) : NUMERIC_TRUNCATION(val, INT_MIN16, INT_MAX16);
      r_param->buffer_length= 2;
      break;
    case MYSQL_TYPE_LONG:
      longstore(r_param->buffer, (int32)val);
      *r_param->error= r_param->is_unsigned ? NUMERIC_TRUNCATION(val, 0, UINT_MAX32) : NUMERIC_TRUNCATION(val, INT_MIN32, INT_MAX32);
      r_param->buffer_length= 4;
      break;
    case MYSQL_TYPE_LONGLONG:
      *r_param->error= (val < 0 && r_param->is_unsigned != is_unsigned);
      longlongstore(r_param->buffer, val);
      r_param->buffer_length= 8;
      break;
    case MYSQL_TYPE_DOUBLE:
    {
      volatile double dbl;

      dbl= (is_unsigned) ? ulonglong2double((ulonglong)val) : (double)val;
      doublestore(r_param->buffer, dbl);
      *r_param->error= is_unsigned ? (ulonglong )dbl != (ulonglong)val : (longlong)dbl != (longlong)val;
      r_param->buffer_length= 8;
      break;
    }
    case MYSQL_TYPE_FLOAT:
    {
      float fval;
      fval= is_unsigned ? (float)(ulonglong)(val) : (float)val;
      float4store(r_param->buffer, fval);
      *r_param->error= is_unsigned ? (ulonglong)fval != (ulonglong)val : (longlong)fval != val;
      r_param->buffer_length= 4;
    }
    break;
    default:
    {
      char buffer[22];
      char *endptr;
      uint len;

      endptr= ma_ll2str(val, buffer, is_unsigned ? 10 : -10);
      len= (uint)(endptr - buffer);

      /* check if field flag is zerofill */
      
      convert_froma_string(r_param, buffer, len);
    }  
    break;
  }
}
/* {{{ ps_fetch_string */
static
void ps_fetch_string(MYSQL_BIND *r_param, const MYSQL_FIELD *field,
             unsigned char **row)
{
  /* C-API differs from PHP. While PHP just converts string to string,
     C-API needs to convert the string to the defined type with in 
     the result bind buffer.
   */
  ulong field_length= net_field_length(row);

  convert_froma_string(r_param, (char *)*row, field_length);
  (*row) += field_length;
}
/* {{{ ps_fetch_datetime */
static
void ps_fetch_datetime(MYSQL_BIND *r_param, const MYSQL_FIELD * field,
                       unsigned char **row)
{
  MYSQL_TIME *t= (MYSQL_TIME *)r_param->buffer;
  unsigned int len= net_field_length(row);

  switch (r_param->buffer_type) {
  case MYSQL_TYPE_DATETIME:
  case MYSQL_TYPE_TIMESTAMP:
    convert_to_datetime(t, row, len, field->type);
    break;
  case MYSQL_TYPE_DATE:
    convert_to_datetime(t, row, len, field->type);
    break;
  case MYSQL_TYPE_TIME:
    convert_to_datetime(t, row, len, field->type);
    t->year= t->day= t->month= 0;
    break;
  case MYSQL_TYPE_YEAR:
  {
    MYSQL_TIME tm;
    convert_to_datetime(&tm, row, len, field->type);
    shortstore(r_param->buffer, tm.year);
    break;
  }
  default: 
  {
    char dtbuffer[60];
    MYSQL_TIME tm;
    unsigned int length;
    convert_to_datetime(&tm, row, len, field->type);
 /*   
    if (tm.time_type== MYSQL_TIMESTAMP_TIME && tm.day)
    {
      tm.hour+= tm.day * 24;
      tm.day=0;
    }
*/
    switch(field->type) {
    case MYSQL_TYPE_DATE:
      length= sprintf(dtbuffer, "%04u-%02u-%02u", tm.year, tm.month, tm.day);
      break;
    case MYSQL_TYPE_TIME:
      length= sprintf(dtbuffer, "%s%02u:%02u:%02u", (tm.neg ? "-" : ""), tm.hour, tm.minute, tm.second);
      if (field->decimals)
      {
        char ms[8];
        sprintf(ms, ".%06u", tm.second_part);
        if (field->decimals < 6)
          ms[field->decimals + 1]= 0;
        length+= strlen(ms);
        strcat(dtbuffer, ms);
      }
      break;
    case MYSQL_TYPE_DATETIME:
    case MYSQL_TYPE_TIMESTAMP:
      length= sprintf(dtbuffer, "%04u-%02u-%02u %02u:%02u:%02u", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second);
      if (field->decimals)
      {
        char ms[8];
        sprintf(ms, ".%06u", tm.second_part);
        if (field->decimals < 6)
          ms[field->decimals + 1]= 0;
        length+= strlen(ms);
        strcat(dtbuffer, ms);
      }
      break;
    default:
      dtbuffer[0]= 0;
      length= 0;
    break;
    }
    convert_froma_string(r_param, dtbuffer, length);
    break;
  }
  }
  (*row) += len;
}
static void convert_from_double(MYSQL_BIND *r_param, const MYSQL_FIELD *field, double val, int size)
{
  double check_trunc_val= (val > 0) ? floor(val) : -floor(-val);
  char *buf= (char *)r_param->buffer;
  switch (r_param->buffer_type)
  {
    case MYSQL_TYPE_TINY:
      *buf= (r_param->is_unsigned) ? (uint8)val : (int8)val;
      *r_param->error= check_trunc_val != (r_param->is_unsigned ? (double)((uint8)*buf) :
                                          (double)((int8)*buf));
      r_param->buffer_length= 1;
    break;
    case MYSQL_TYPE_SHORT:
    case MYSQL_TYPE_YEAR:
    {
      if (r_param->is_unsigned)
      {
        ushort sval= (ushort)val;
        shortstore(buf, sval);
        *r_param->error= check_trunc_val != (double)sval;
      } else { 
        short sval= (short)val;
        shortstore(buf, sval);
        *r_param->error= check_trunc_val != (double)sval;
      } 
      r_param->buffer_length= 2;
    }
    break; 
    case MYSQL_TYPE_LONG:
    {
      if (r_param->is_unsigned)
      {
        uint32 lval= (uint32)val;
        longstore(buf, lval);
        *r_param->error= (check_trunc_val != (double)lval);
      } else {
        int32 lval= (int32)val;
        longstore(buf, lval);
        *r_param->error= (check_trunc_val != (double)lval);
      }
      r_param->buffer_length= 4;
    }
    break; 
    case MYSQL_TYPE_LONGLONG:
    {
      if (r_param->is_unsigned)
      {
        ulonglong llval= (ulonglong)val;
        longlongstore(buf, llval);
        *r_param->error= (check_trunc_val != (double)llval);
      } else {
        longlong llval= (longlong)val;
        longlongstore(buf, llval);
        *r_param->error= (check_trunc_val != (double)llval);
      }
      r_param->buffer_length= 8;
    }
    break; 
    case MYSQL_TYPE_FLOAT:
    {
      float fval= (float)val;
      memcpy(buf, &fval, sizeof(float));
      *r_param->error= (*(float*)buf != fval);
      r_param->buffer_length= 4;
    }
    break;
    default:
    {
     char buff[MAX_DOUBLE_STRING_REP_LENGTH];
     size_t length;

     length= MIN(MAX_DOUBLE_STRING_REP_LENGTH - 1, r_param->buffer_length);

     if (field->decimals >= NOT_FIXED_DEC)
     {
       length= ma_gcvt(val, MY_GCVT_ARG_DOUBLE, length, buff, NULL);
     }
     else
     {
       length= ma_fcvt(val, field->decimals, buff, NULL);
     }

     /* check if ZEROFILL flag is active */
     if (field->flags & ZEROFILL_FLAG)
     {
       /* enough space available ? */
       if (field->length < length || field->length > MAX_DOUBLE_STRING_REP_LENGTH - 1)
         break;
       ma_bmove_upp(buff + field->length, buff + length, length);
       memset((char*) buff, 0, field->length - length);
     }
     convert_froma_string(r_param, buff, strlen(buff));
    }  
    break;
  } 
}
static void convert_from_double(MYSQL_BIND *r_param, const MYSQL_FIELD *field, double val, int size)
{
  double check_trunc_val= (val > 0) ? floor(val) : -floor(-val);
  char *buf= (char *)r_param->buffer;
  switch (r_param->buffer_type)
  {
    case MYSQL_TYPE_TINY:
      *buf= (r_param->is_unsigned) ? (uint8)val : (int8)val;
      *r_param->error= check_trunc_val != (r_param->is_unsigned ? (double)((uint8)*buf) :
                                          (double)((int8)*buf));
      r_param->buffer_length= 1;
    break;
    case MYSQL_TYPE_SHORT:
    case MYSQL_TYPE_YEAR:
    {
      if (r_param->is_unsigned)
      {
        ushort sval= (ushort)val;
        shortstore(buf, sval);
        *r_param->error= check_trunc_val != (double)sval;
      } else { 
        short sval= (short)val;
        shortstore(buf, sval);
        *r_param->error= check_trunc_val != (double)sval;
      } 
      r_param->buffer_length= 2;
    }
    break; 
    case MYSQL_TYPE_LONG:
    {
      if (r_param->is_unsigned)
      {
        uint32 lval= (uint32)val;
        longstore(buf, lval);
        *r_param->error= (check_trunc_val != (double)lval);
      } else {
        int32 lval= (int32)val;
        longstore(buf, lval);
        *r_param->error= (check_trunc_val != (double)lval);
      }
      r_param->buffer_length= 4;
    }
    break; 
    case MYSQL_TYPE_LONGLONG:
    {
      if (r_param->is_unsigned)
      {
        ulonglong llval= (ulonglong)val;
        longlongstore(buf, llval);
        *r_param->error= (check_trunc_val != (double)llval);
      } else {
        longlong llval= (longlong)val;
        longlongstore(buf, llval);
        *r_param->error= (check_trunc_val != (double)llval);
      }
      r_param->buffer_length= 8;
    }
    break; 
    case MYSQL_TYPE_FLOAT:
    {
      float fval= (float)val;
      memcpy(buf, &fval, sizeof(float));
      *r_param->error= (*(float*)buf != fval);
      r_param->buffer_length= 4;
    }
    break;
    default:
    {
 #define MAX_DOUBLE_STRING_REP_LENGTH 300
     char buff[MAX_DOUBLE_STRING_REP_LENGTH];
     size_t length;
     char *end;

     length= MIN(MAX_DOUBLE_STRING_REP_LENGTH - 1, r_param->buffer_length);

     if (field->decimals >= NOT_FIXED_DEC)
     {
       sprintf(buff, "%-*.*g", (int) length-1, DBL_DIG, val);
       length= strlen(buff);
     }
     else
     {
#ifdef _WIN32
#else
       gcvt(val, field->decimals, buff);
#endif
//       sprintf(buff, "%.*f", field->decimals, val);
       length= strlen(buff);
     }

     /* remove trailing blanks */
     end= strchr(buff, '\0') - 1;
     while (end > buff && *end == ' ')
       *end--= '\0';

     /* check if ZEROFILL flag is active */
     if (field->flags & ZEROFILL_FLAG)
     {
       /* enough space available ? */
       if (field->length < length || field->length > MAX_DOUBLE_STRING_REP_LENGTH - 1)
         break;
       ma_bmove_upp(buff + field->length, buff + length, length);
       memset((char*) buff, 0, field->length - length);
     }
     convert_froma_string(r_param, buff, strlen(buff));
    }  
    break;
  } 
}