~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/str.cc

  • Committer: Monty Taylor
  • Date: 2009-03-03 07:39:39 UTC
  • mto: This revision was merged to the branch mainline in revision 910.
  • Revision ID: mordred@inaugust.com-20090303073939-rfswfdo68klfcp1o
Updated comment version indicators to handle drizzle versions.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 */
20
20
 
21
21
 
22
 
#include <config.h>
 
22
#include <drizzled/server_includes.h>
23
23
#include <drizzled/field/str.h>
24
24
#include <drizzled/error.h>
25
25
#include <drizzled/table.h>
26
26
#include <drizzled/session.h>
27
 
#include <drizzled/internal/m_string.h>
28
 
 
29
 
namespace drizzled
30
 
{
31
 
 
32
 
namespace internal
33
 
{
34
 
extern char _dig_vec_upper[];
35
 
}
36
 
 
37
 
Field_str::Field_str(unsigned char *ptr_arg,
38
 
                     uint32_t len_arg,
 
27
 
 
28
 
 
29
Field_str::Field_str(unsigned char *ptr_arg,uint32_t len_arg,
39
30
                     unsigned char *null_ptr_arg,
40
 
                     unsigned char null_bit_arg,
 
31
                     unsigned char null_bit_arg, utype unireg_check_arg,
41
32
                     const char *field_name_arg,
42
33
                     const CHARSET_INFO * const charset_arg)
43
 
  :Field(ptr_arg, len_arg,
44
 
         null_ptr_arg,
45
 
         null_bit_arg,
46
 
         Field::NONE,
47
 
         field_name_arg)
 
34
  :Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
 
35
         unireg_check_arg, field_name_arg)
48
36
{
49
37
  field_charset= charset_arg;
50
38
  if (charset_arg->state & MY_CS_BINSORT)
51
 
    flags|= BINARY_FLAG;
 
39
    flags|=BINARY_FLAG;
52
40
  field_derivation= DERIVATION_IMPLICIT;
53
41
}
54
42
 
55
 
/*
56
 
  Check if we lost any important data and send a truncation error/warning
57
 
 
58
 
  SYNOPSIS
59
 
    Field_str::report_if_important_data()
60
 
    ptr                      - Truncated rest of string
61
 
    end                      - End of truncated string
62
 
 
63
 
  RETURN VALUES
64
 
    0   - None was truncated (or we don't count cut fields)
65
 
    2   - Some bytes was truncated
66
 
 
67
 
  NOTE
68
 
    Check if we lost any important data (anything in a binary string,
69
 
    or any non-space in others). If only trailing spaces was lost,
70
 
    send a truncation note, otherwise send a truncation error.
71
 
*/
72
 
 
73
 
int
74
 
Field_str::report_if_important_data(const char *field_ptr, const char *end)
75
 
{
76
 
  if ((field_ptr < end) && getTable()->in_use->count_cuted_fields)
77
 
  {
78
 
    set_warning(DRIZZLE_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1);
79
 
 
80
 
    return 2;
81
 
  }
82
 
  return 0;
83
 
}
84
 
 
85
43
/**
86
44
  Decimal representation of Field_str.
87
45
 
102
60
    !=0  error
103
61
*/
104
62
 
105
 
int Field_str::store_decimal(const type::Decimal *d)
 
63
int Field_str::store_decimal(const my_decimal *d)
106
64
{
107
 
  char buff[DECIMAL_MAX_STR_LENGTH+1];
108
 
  String str(buff, sizeof(buff), &my_charset_bin);
109
 
  class_decimal2string(d, 0, &str);
110
 
  return store(str.ptr(), str.length(), str.charset());
 
65
  double val;
 
66
  /* TODO: use decimal2string? */
 
67
  int err= warn_if_overflow(my_decimal2double(E_DEC_FATAL_ERROR &
 
68
                                            ~E_DEC_OVERFLOW, d, &val));
 
69
  return err | store(val);
111
70
}
112
71
 
113
 
type::Decimal *Field_str::val_decimal(type::Decimal *decimal_value) const
 
72
my_decimal *Field_str::val_decimal(my_decimal *decimal_value)
114
73
{
115
74
  int64_t nr= val_int();
116
 
  int2_class_decimal(E_DEC_FATAL_ERROR, nr, 0, decimal_value);
 
75
  int2my_decimal(E_DEC_FATAL_ERROR, nr, 0, decimal_value);
117
76
  return decimal_value;
118
77
}
119
78
 
132
91
  size_t length;
133
92
  bool error;
134
93
 
135
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
136
 
 
137
 
  length= internal::my_gcvt(nr, internal::MY_GCVT_ARG_DOUBLE, local_char_length, buff, &error);
 
94
  length= my_gcvt(nr, MY_GCVT_ARG_DOUBLE, local_char_length, buff, &error);
138
95
  if (error)
139
96
  {
140
 
    if (getTable()->getSession()->abortOnWarning())
141
 
    {
 
97
    if (table->in_use->abort_on_warning)
142
98
      set_warning(DRIZZLE_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1);
143
 
    }
144
99
    else
145
 
    {
146
100
      set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
147
 
    }
148
101
  }
149
102
  return store(buff, length, charset());
150
103
}
151
104
 
 
105
/* If one of the fields is binary and the other one isn't return 1 else 0 */
 
106
 
 
107
bool Field_str::compare_str_field_flags(Create_field *new_field_ptr,
 
108
                                        uint32_t flag_arg)
 
109
{
 
110
  return (((new_field_ptr->flags & (BINCMP_FLAG | BINARY_FLAG)) &&
 
111
          !(flag_arg & (BINCMP_FLAG | BINARY_FLAG))) ||
 
112
         (!(new_field_ptr->flags & (BINCMP_FLAG | BINARY_FLAG)) &&
 
113
          (flag_arg & (BINCMP_FLAG | BINARY_FLAG))));
 
114
}
 
115
 
 
116
 
 
117
uint32_t Field_str::is_equal(Create_field *new_field_ptr)
 
118
{
 
119
  if (compare_str_field_flags(new_field_ptr, flags))
 
120
    return 0;
 
121
 
 
122
  return ((new_field_ptr->sql_type == real_type()) &&
 
123
          new_field_ptr->charset == field_charset &&
 
124
          new_field_ptr->length == max_display_length());
 
125
}
 
126
 
152
127
 
153
128
bool check_string_copy_error(Field_str *field,
154
129
                             const char *well_formed_error_pos,
187
162
    {
188
163
      *t++= '\\';
189
164
      *t++= 'x';
190
 
      *t++= internal::_dig_vec_upper[((unsigned char) *pos) >> 4];
191
 
      *t++= internal::_dig_vec_upper[((unsigned char) *pos) & 15];
 
165
      *t++= _dig_vec_upper[((unsigned char) *pos) >> 4];
 
166
      *t++= _dig_vec_upper[((unsigned char) *pos) & 15];
192
167
    }
193
168
  }
194
169
  if (end_orig > end)
198
173
    *t++= '.';
199
174
  }
200
175
  *t= '\0';
201
 
  push_warning_printf(field->getTable()->in_use,
202
 
                      field->getTable()->in_use->abortOnWarning() ?
 
176
  push_warning_printf(field->table->in_use,
 
177
                      field->table->in_use->abort_on_warning ?
203
178
                      DRIZZLE_ERROR::WARN_LEVEL_ERROR :
204
179
                      DRIZZLE_ERROR::WARN_LEVEL_WARN,
205
180
                      ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
206
181
                      ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
207
182
                      "string", tmp, field->field_name,
208
 
                      (uint32_t) field->getTable()->in_use->row_count);
 
183
                      (uint32_t) field->table->in_use->row_count);
209
184
  return true;
210
185
}
211
186
 
212
 
uint32_t Field_str::max_data_length() const
213
 
{
214
 
  return field_length + (field_length > 255 ? 2 : 1);
215
 
}
216
 
 
217
 
} /* namespace drizzled */