~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/double.cc

  • Committer: Jay Pipes
  • Date: 2009-01-30 04:01:12 UTC
  • mto: This revision was merged to the branch mainline in revision 830.
  • Revision ID: jpipes@serialcoder-20090130040112-svbn774guj98pwi4
To remain in compatibility with MySQL, added ability to interpret
decimal arguments as datetime strings for temporal functions.

Fixed YEAR(), MONTH(), DAYOFMONTH(), DAYOFYEAR(), HOUR(), MINUTE(), SECOND(), and MICROSECOND()
to accept decimal parameters and interpret them the same way as MySQL.

Fixed an issue with the TemporalFormat::matches() method which was 
incorrectly assuming all microsecond arguments were specified as 6 digits.
Added power of 10 multiplier to usecond calculation. This fixes issues with
failures in type_date and func_sapdb test cases.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 */
20
20
 
21
21
 
22
 
#include "config.h"
23
 
 
24
 
#include <float.h>
25
 
#include <math.h>
26
 
 
27
 
#include <algorithm>
28
 
 
 
22
#include <drizzled/server_includes.h>
29
23
#include <drizzled/field/double.h>
30
24
#include <drizzled/error.h>
31
25
#include <drizzled/table.h>
32
26
#include <drizzled/session.h>
33
 
#include "drizzled/internal/m_string.h"
34
 
 
35
 
using namespace std;
36
 
 
37
 
namespace drizzled
38
 
{
 
27
#include <drizzled/protocol.h>
 
28
 
 
29
#include CMATH_H
 
30
 
 
31
#if defined(CMATH_NAMESPACE)
 
32
using namespace CMATH_NAMESPACE;
 
33
#endif
39
34
 
40
35
/****************************************************************************
41
36
  double precision floating point numbers
46
41
  int error;
47
42
  char *end;
48
43
  double nr= my_strntod(cs,(char*) from, len, &end, &error);
49
 
 
50
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
51
 
  if (error || (!len || (((uint32_t) (end-from) != len) && getTable()->in_use->count_cuted_fields)))
 
44
  if (error || (!len || (((uint) (end-from) != len) && table->in_use->count_cuted_fields)))
52
45
  {
53
46
    set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
54
47
                (error ? ER_WARN_DATA_OUT_OF_RANGE : ER_WARN_DATA_TRUNCATED), 1);
63
56
{
64
57
  int error= truncate(&nr, DBL_MAX);
65
58
 
66
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
67
 
 
68
59
#ifdef WORDS_BIGENDIAN
69
 
  if (getTable()->getShare()->db_low_byte_first)
 
60
  if (table->s->db_low_byte_first)
70
61
  {
71
62
    float8store(ptr,nr);
72
63
  }
86
77
double Field_double::val_real(void)
87
78
{
88
79
  double j;
89
 
 
90
 
  ASSERT_COLUMN_MARKED_FOR_READ;
91
 
 
92
80
#ifdef WORDS_BIGENDIAN
93
 
  if (getTable()->getShare()->db_low_byte_first)
 
81
  if (table->s->db_low_byte_first)
94
82
  {
95
83
    float8get(j,ptr);
96
84
  }
104
92
{
105
93
  double j;
106
94
  int64_t res;
107
 
 
108
 
  ASSERT_COLUMN_MARKED_FOR_READ;
109
 
 
110
95
#ifdef WORDS_BIGENDIAN
111
 
  if (getTable()->getShare()->db_low_byte_first)
 
96
  if (table->s->db_low_byte_first)
112
97
  {
113
98
    float8get(j,ptr);
114
99
  }
132
117
  {
133
118
    char buf[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE];
134
119
    String tmp(buf, sizeof(buf), &my_charset_utf8_general_ci), *str;
135
 
    str= val_str(&tmp, &tmp);
 
120
    str= val_str(&tmp, 0);
136
121
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
137
122
                        ER_TRUNCATED_WRONG_VALUE,
138
123
                        ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER",
146
131
                              String *)
147
132
{
148
133
  double nr;
149
 
 
150
 
  ASSERT_COLUMN_MARKED_FOR_READ;
151
 
 
152
134
#ifdef WORDS_BIGENDIAN
153
 
  if (getTable()->getShare()->db_low_byte_first)
 
135
  if (table->s->db_low_byte_first)
154
136
  {
155
137
    float8get(nr,ptr);
156
138
  }
158
140
#endif
159
141
    doubleget(nr,ptr);
160
142
 
161
 
  uint32_t to_length= max(field_length, (uint32_t)DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE);
 
143
  uint32_t to_length=cmax(field_length, (uint32_t)DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE);
162
144
  val_buffer->alloc(to_length);
163
145
  char *to=(char*) val_buffer->ptr();
164
146
  size_t len;
165
147
 
166
148
  if (dec >= NOT_FIXED_DEC)
167
 
    len= internal::my_gcvt(nr, internal::MY_GCVT_ARG_DOUBLE, to_length - 1, to, NULL);
 
149
    len= my_gcvt(nr, MY_GCVT_ARG_DOUBLE, to_length - 1, to, NULL);
168
150
  else
169
 
    len= internal::my_fcvt(nr, dec, to, NULL);
 
151
    len= my_fcvt(nr, dec, to, NULL);
170
152
 
171
 
  val_buffer->length((uint32_t) len);
 
153
  val_buffer->length((uint) len);
172
154
 
173
155
  return val_buffer;
174
156
}
175
157
 
 
158
bool Field_double::send_binary(Protocol *protocol)
 
159
{
 
160
  return protocol->store((double) Field_double::val_real(), dec, (String*) 0);
 
161
}
 
162
 
 
163
 
176
164
int Field_double::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
177
165
{
178
166
  double a,b;
179
167
#ifdef WORDS_BIGENDIAN
180
 
  if (getTable()->getShare()->db_low_byte_first)
 
168
  if (table->s->db_low_byte_first)
181
169
  {
182
170
    float8get(a,a_ptr);
183
171
    float8get(b,b_ptr);
198
186
{
199
187
  double nr;
200
188
#ifdef WORDS_BIGENDIAN
201
 
  if (getTable()->getShare()->db_low_byte_first)
 
189
  if (table->s->db_low_byte_first)
202
190
  {
203
191
    float8get(nr,ptr);
204
192
  }
209
197
}
210
198
 
211
199
 
 
200
/**
 
201
   Save the field metadata for double fields.
 
202
 
 
203
   Saves the pack length in the first byte of the field metadata array
 
204
   at index of *metadata_ptr.
 
205
 
 
206
   @param   metadata_ptr   First byte of field metadata
 
207
 
 
208
   @returns number of bytes written to metadata_ptr
 
209
*/
 
210
int Field_double::do_save_field_metadata(unsigned char *metadata_ptr)
 
211
{
 
212
  *metadata_ptr= pack_length();
 
213
  return 1;
 
214
}
 
215
 
 
216
 
212
217
void Field_double::sql_type(String &res) const
213
218
{
214
219
  const CHARSET_INFO * const cs=res.charset();
223
228
  }
224
229
}
225
230
 
226
 
} /* namespace drizzled */