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; } }