~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/string.cc

  • Committer: Monty Taylor
  • Date: 2008-10-07 19:30:18 UTC
  • mfrom: (322.2.8 stdize-code)
  • mto: This revision was merged to the branch mainline in revision 491.
  • Revision ID: monty@inaugust.com-20081007193018-22fhaywc990akeqa
Merged code from Mats that I should have merged a while ago.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems, Inc.
5
 
 *
6
 
 *  This program is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation; version 2 of the License.
9
 
 *
10
 
 *  This program is distributed in the hope that it will be useful,
11
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *  GNU General Public License for more details.
14
 
 *
15
 
 *  You should have received a copy of the GNU General Public License
16
 
 *  along with this program; if not, write to the Free Software
17
 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 
 */
19
 
 
20
 
#include <config.h>
21
 
 
22
 
#include <drizzled/session.h>
23
 
#include <drizzled/error.h>
24
 
#include <drizzled/item/string.h>
25
 
 
26
 
namespace drizzled
27
 
{
28
 
 
29
 
Item *Item_string::safe_charset_converter(const CHARSET_INFO * const tocs)
30
 
{
31
 
  Item_string *conv;
32
 
  size_t conv_errors;
33
 
  char *ptr;
34
 
  String tmp, cstr, *ostr= val_str(&tmp);
35
 
  cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors);
36
 
  if (conv_errors || !(conv= new Item_string(cstr.ptr(), cstr.length(),
37
 
                                             cstr.charset(),
38
 
                                             collation.derivation)))
39
 
  {
40
 
    /*
41
 
      Safe conversion is not possible (or EOM).
42
 
      We could not convert a string into the requested character set
43
 
      without data loss. The target charset does not cover all the
44
 
      characters from the string. Operation cannot be done correctly.
45
 
    */
46
 
    return NULL;
47
 
  }
48
 
 
49
 
  if (!(ptr= getSession().strmake(cstr.ptr(), cstr.length())))
50
 
    return NULL;
51
 
 
52
 
  conv->str_value.set(ptr, cstr.length(), cstr.charset());
53
 
  /* Ensure that no one is going to change the result string */
54
 
  conv->str_value.mark_as_const();
55
 
  return conv;
56
 
}
57
 
 
58
 
 
59
 
Item *Item_static_string_func::safe_charset_converter(const CHARSET_INFO * const tocs)
60
 
{
61
 
  Item_string *conv;
62
 
  size_t conv_errors;
63
 
  String tmp, cstr, *ostr= val_str(&tmp);
64
 
  cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors);
65
 
  if (conv_errors ||
66
 
      !(conv= new Item_static_string_func(func_name,
67
 
                                          cstr.ptr(), cstr.length(),
68
 
                                          cstr.charset(),
69
 
                                          collation.derivation)))
70
 
  {
71
 
    /*
72
 
      Safe conversion is not possible (or EOM).
73
 
      We could not convert a string into the requested character set
74
 
      without data loss. The target charset does not cover all the
75
 
      characters from the string. Operation cannot be done correctly.
76
 
    */
77
 
    return NULL;
78
 
  }
79
 
  conv->str_value.copy();
80
 
  /* Ensure that no one is going to change the result string */
81
 
  conv->str_value.mark_as_const();
82
 
  return conv;
83
 
}
84
 
 
85
 
 
86
 
bool Item_string::eq(const Item *item, bool binary_cmp) const
87
 
{
88
 
  if (type() == item->type() && item->basic_const_item())
89
 
  {
90
 
    if (binary_cmp)
91
 
      return !stringcmp(&str_value, &item->str_value);
92
 
    return (collation.collation == item->collation.collation &&
93
 
            !sortcmp(&str_value, &item->str_value, collation.collation));
94
 
  }
95
 
  return 0;
96
 
}
97
 
 
98
 
void Item_string::print(String *str, enum_query_type query_type)
99
 
{
100
 
  if (query_type == QT_ORDINARY && is_cs_specified())
101
 
  {
102
 
    str->append('_');
103
 
    str->append(collation.collation->csname);
104
 
  }
105
 
 
106
 
  str->append('\'');
107
 
 
108
 
  str_value.print(str);
109
 
 
110
 
  str->append('\'');
111
 
}
112
 
 
113
 
double Item_string::val_real()
114
 
{
115
 
  assert(fixed == 1);
116
 
  int error;
117
 
  char *end, *org_end;
118
 
  double tmp;
119
 
  const CHARSET_INFO * const cs= str_value.charset();
120
 
 
121
 
  org_end= (char*) str_value.ptr() + str_value.length();
122
 
  tmp= my_strntod(cs, (char*) str_value.ptr(), str_value.length(), &end,
123
 
                  &error);
124
 
  if (error || (end != org_end && !check_if_only_end_space(cs, end, org_end)))
125
 
  {
126
 
    /*
127
 
      We can use str_value.ptr() here as Item_string is gurantee to put an
128
 
      end \0 here.
129
 
    */
130
 
    push_warning_printf(&getSession(), DRIZZLE_ERROR::WARN_LEVEL_WARN,
131
 
                        ER_TRUNCATED_WRONG_VALUE,
132
 
                        ER(ER_TRUNCATED_WRONG_VALUE), "DOUBLE",
133
 
                        str_value.ptr());
134
 
  }
135
 
  return tmp;
136
 
}
137
 
 
138
 
/**
139
 
  @todo
140
 
  Give error if we wanted a signed integer and we got an unsigned one
141
 
*/
142
 
int64_t Item_string::val_int()
143
 
{
144
 
  assert(fixed == 1);
145
 
  int err;
146
 
  int64_t tmp;
147
 
  char *end= (char*) str_value.ptr()+ str_value.length();
148
 
  char *org_end= end;
149
 
  const CHARSET_INFO * const cs= str_value.charset();
150
 
 
151
 
  tmp= (*(cs->cset->strtoll10))(cs, str_value.ptr(), &end, &err);
152
 
  /*
153
 
    TODO: Give error if we wanted a signed integer and we got an unsigned
154
 
    one
155
 
  */
156
 
  if (err > 0 ||
157
 
      (end != org_end && !check_if_only_end_space(cs, end, org_end)))
158
 
  {
159
 
    push_warning_printf(&getSession(), DRIZZLE_ERROR::WARN_LEVEL_WARN,
160
 
                        ER_TRUNCATED_WRONG_VALUE,
161
 
                        ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER",
162
 
                        str_value.ptr());
163
 
  }
164
 
  return tmp;
165
 
}
166
 
 
167
 
type::Decimal *Item_string::val_decimal(type::Decimal *decimal_value)
168
 
{
169
 
  return val_decimal_from_string(decimal_value);
170
 
}
171
 
 
172
 
int Item_string::save_in_field(Field *field, bool)
173
 
{
174
 
  String *result;
175
 
  result=val_str(&str_value);
176
 
  return save_str_value_in_field(field, result);
177
 
}
178
 
 
179
 
 
180
 
} /* namespace drizzled */