~drizzle-trunk/drizzle/development

642.1.6 by Lee
move functions from item.cc/item.h to item directory
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
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 <drizzled/server_includes.h>
21
#include CSTDINT_H
22
#include <drizzled/session.h>
23
#include <drizzled/error.h>
670.4.1 by Monty Taylor
Removed recursive subdirs in drizzled/, which allowed the renaming of ifloat and istring. It's also faster.
24
#include <drizzled/item/string.h>
642.1.6 by Lee
move functions from item.cc/item.h to item directory
25
26
Item *Item_string::safe_charset_converter(const CHARSET_INFO * const tocs)
27
{
28
  Item_string *conv;
29
  uint32_t conv_errors;
30
  char *ptr;
31
  String tmp, cstr, *ostr= val_str(&tmp);
32
  cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors);
33
  if (conv_errors || !(conv= new Item_string(cstr.ptr(), cstr.length(),
34
                                             cstr.charset(),
35
                                             collation.derivation)))
36
  {
37
    /*
38
      Safe conversion is not possible (or EOM).
39
      We could not convert a string into the requested character set
40
      without data loss. The target charset does not cover all the
41
      characters from the string. Operation cannot be done correctly.
42
    */
43
    return NULL;
44
  }
45
  if (!(ptr= current_session->strmake(cstr.ptr(), cstr.length())))
46
    return NULL;
47
  conv->str_value.set(ptr, cstr.length(), cstr.charset());
48
  /* Ensure that no one is going to change the result string */
49
  conv->str_value.mark_as_const();
50
  return conv;
51
}
52
53
54
Item *Item_static_string_func::safe_charset_converter(const CHARSET_INFO * const tocs)
55
{
56
  Item_string *conv;
57
  uint32_t conv_errors;
58
  String tmp, cstr, *ostr= val_str(&tmp);
59
  cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors);
60
  if (conv_errors ||
61
      !(conv= new Item_static_string_func(func_name,
62
                                          cstr.ptr(), cstr.length(),
63
                                          cstr.charset(),
64
                                          collation.derivation)))
65
  {
66
    /*
67
      Safe conversion is not possible (or EOM).
68
      We could not convert a string into the requested character set
69
      without data loss. The target charset does not cover all the
70
      characters from the string. Operation cannot be done correctly.
71
    */
72
    return NULL;
73
  }
74
  conv->str_value.copy();
75
  /* Ensure that no one is going to change the result string */
76
  conv->str_value.mark_as_const();
77
  return conv;
78
}
79
80
81
bool Item_string::eq(const Item *item, bool binary_cmp) const
82
{
83
  if (type() == item->type() && item->basic_const_item())
84
  {
85
    if (binary_cmp)
86
      return !stringcmp(&str_value, &item->str_value);
87
    return (collation.collation == item->collation.collation &&
88
            !sortcmp(&str_value, &item->str_value, collation.collation));
89
  }
90
  return 0;
91
}
92
93
void Item_string::print(String *str, enum_query_type query_type)
94
{
95
  if (query_type == QT_ORDINARY && is_cs_specified())
96
  {
97
    str->append('_');
98
    str->append(collation.collation->csname);
99
  }
100
101
  str->append('\'');
102
1054.2.11 by Monty Taylor
Removed copy_and_convert.
103
  str_value.print(str);
642.1.6 by Lee
move functions from item.cc/item.h to item directory
104
105
  str->append('\'');
106
}
107
108
double Item_string::val_real()
109
{
110
  assert(fixed == 1);
111
  int error;
112
  char *end, *org_end;
113
  double tmp;
114
  const CHARSET_INFO * const cs= str_value.charset();
115
116
  org_end= (char*) str_value.ptr() + str_value.length();
117
  tmp= my_strntod(cs, (char*) str_value.ptr(), str_value.length(), &end,
118
                  &error);
119
  if (error || (end != org_end && !check_if_only_end_space(cs, end, org_end)))
120
  {
121
    /*
122
      We can use str_value.ptr() here as Item_string is gurantee to put an
123
      end \0 here.
124
    */
125
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
126
                        ER_TRUNCATED_WRONG_VALUE,
127
                        ER(ER_TRUNCATED_WRONG_VALUE), "DOUBLE",
128
                        str_value.ptr());
129
  }
130
  return tmp;
131
}
132
133
/**
134
  @todo
135
  Give error if we wanted a signed integer and we got an unsigned one
136
*/
137
int64_t Item_string::val_int()
138
{
139
  assert(fixed == 1);
140
  int err;
141
  int64_t tmp;
142
  char *end= (char*) str_value.ptr()+ str_value.length();
143
  char *org_end= end;
144
  const CHARSET_INFO * const cs= str_value.charset();
145
146
  tmp= (*(cs->cset->strtoll10))(cs, str_value.ptr(), &end, &err);
147
  /*
148
    TODO: Give error if we wanted a signed integer and we got an unsigned
149
    one
150
  */
151
  if (err > 0 ||
152
      (end != org_end && !check_if_only_end_space(cs, end, org_end)))
153
  {
154
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
155
                        ER_TRUNCATED_WRONG_VALUE,
156
                        ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER",
157
                        str_value.ptr());
158
  }
159
  return tmp;
160
}
161
162
my_decimal *Item_string::val_decimal(my_decimal *decimal_value)
163
{
164
  return val_decimal_from_string(decimal_value);
165
}
166
167
int Item_string::save_in_field(Field *field, bool)
168
{
169
  String *result;
170
  result=val_str(&str_value);
171
  return save_str_value_in_field(field, result);
172
}
173
174
175