Drizzled Public API Documentation

dtcollation.cc
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 #include <drizzled/dtcollation.h>
22 
23 #include <drizzled/definitions.h>
24 #include <drizzled/internal/my_sys.h>
25 #include <drizzled/error.h>
26 #include <drizzled/function/str/conv_charset.h>
27 #include <drizzled/session.h>
28 #include <drizzled/charset.h>
29 
30 namespace drizzled {
31 
32 DTCollation::DTCollation()
33 {
34  collation= &my_charset_bin;
35  derivation= DERIVATION_NONE;
36 }
37 
38 
39 DTCollation::DTCollation(const charset_info_st * const collation_arg,
40  Derivation derivation_arg)
41 {
42  collation= collation_arg;
43  derivation= derivation_arg;
44 }
45 
46 
47 void DTCollation::set(DTCollation &dt)
48 {
49  collation= dt.collation;
50  derivation= dt.derivation;
51 }
52 
53 
54 void DTCollation::set(const charset_info_st * const collation_arg,
55  Derivation derivation_arg)
56 {
57  collation= collation_arg;
58  derivation= derivation_arg;
59 }
60 
61 
62 void DTCollation::set(const charset_info_st * const collation_arg)
63 {
64  collation= collation_arg;
65 }
66 
67 
68 void DTCollation::set(Derivation derivation_arg)
69 {
70  derivation= derivation_arg;
71 }
72 
73 
74 bool DTCollation::aggregate(DTCollation &dt, uint32_t flags)
75 {
76  if (!my_charset_same(collation, dt.collation))
77  {
78  /*
79  We do allow to use binary strings (like BLOBS)
80  together with character strings.
81  Binaries have more precedence than a character
82  string of the same derivation.
83  */
84  if (collation == &my_charset_bin)
85  {
86  if (derivation <= dt.derivation)
87  ; // Do nothing
88  else
89  {
90  set(dt);
91  }
92  }
93  else if (dt.collation == &my_charset_bin)
94  {
95  if (dt.derivation <= derivation)
96  {
97  set(dt);
98  }
99  else
100  {
101  // Do nothing
102  }
103  }
104  else if ((flags & MY_COLL_ALLOW_SUPERSET_CONV) &&
105  collation->state & MY_CS_UNICODE &&
106  (derivation < dt.derivation ||
107  (derivation == dt.derivation &&
108  !(dt.collation->state & MY_CS_UNICODE))))
109  {
110  // Do nothing
111  }
112  else if ((flags & MY_COLL_ALLOW_SUPERSET_CONV) &&
113  dt.collation->state & MY_CS_UNICODE &&
114  (dt.derivation < derivation ||
115  (dt.derivation == derivation &&
116  !(collation->state & MY_CS_UNICODE))))
117  {
118  set(dt);
119  }
120  else if ((flags & MY_COLL_ALLOW_COERCIBLE_CONV) &&
121  derivation < dt.derivation &&
122  dt.derivation >= DERIVATION_SYSCONST)
123  {
124  // Do nothing;
125  }
126  else if ((flags & MY_COLL_ALLOW_COERCIBLE_CONV) &&
127  dt.derivation < derivation &&
128  derivation >= DERIVATION_SYSCONST)
129  {
130  set(dt);
131  }
132  else
133  {
134  // Cannot apply conversion
135  set(0, DERIVATION_NONE);
136  return true;
137  }
138  }
139  else if (derivation < dt.derivation)
140  {
141  // Do nothing
142  }
143  else if (dt.derivation < derivation)
144  {
145  set(dt);
146  }
147  else
148  {
149  if (collation == dt.collation)
150  {
151  // Do nothing
152  }
153  else
154  {
155  if (derivation == DERIVATION_EXPLICIT)
156  {
157  set(0, DERIVATION_NONE);
158  return true;
159  }
160  if (collation->state & MY_CS_BINSORT)
161  return false;
162  if (dt.collation->state & MY_CS_BINSORT)
163  {
164  set(dt);
165  return false;
166  }
167  const charset_info_st * const bin= get_charset_by_csname(collation->csname, MY_CS_BINSORT);
168  set(bin, DERIVATION_NONE);
169  }
170  }
171 
172  return false;
173 }
174 
175 
176 bool DTCollation::set(DTCollation &dt1, DTCollation &dt2, uint32_t flags)
177 { set(dt1); return aggregate(dt2, flags); }
178 
179 
180 const char *DTCollation::derivation_name() const
181 {
182  switch(derivation)
183  {
184  case DERIVATION_IGNORABLE: return "IGNORABLE";
185  case DERIVATION_COERCIBLE: return "COERCIBLE";
186  case DERIVATION_IMPLICIT: return "IMPLICIT";
187  case DERIVATION_SYSCONST: return "SYSCONST";
188  case DERIVATION_EXPLICIT: return "EXPLICIT";
189  case DERIVATION_NONE: return "NONE";
190  default: return "UNKNOWN";
191  }
192 }
193 
194 
195 bool agg_item_collations(DTCollation &c, const char *fname,
196  Item **av, uint32_t count,
197  uint32_t flags, int item_sep)
198 {
199  uint32_t i;
200  Item **arg;
201  c.set(av[0]->collation);
202  for (i= 1, arg= &av[item_sep]; i < count; i++, arg++)
203  {
204  if (c.aggregate((*arg)->collation, flags))
205  {
206  my_coll_agg_error(av, count, fname, item_sep);
207  return true;
208  }
209  }
210  if ((flags & MY_COLL_DISALLOW_NONE) &&
211  c.derivation == DERIVATION_NONE)
212  {
213  my_coll_agg_error(av, count, fname, item_sep);
214  return true;
215  }
216  return false;
217 }
218 
219 
220 bool agg_item_collations_for_comparison(DTCollation &c, const char *fname,
221  Item **av, uint32_t count,
222  uint32_t flags)
223 {
224  return (agg_item_collations(c, fname, av, count,
225  flags | MY_COLL_DISALLOW_NONE, 1));
226 }
227 
228 
229 bool agg_item_charsets(DTCollation &coll, const char *fname,
230  Item **args, uint32_t nargs, uint32_t flags,
231  int item_sep)
232 {
233  if (agg_item_collations(coll, fname, args, nargs, flags, item_sep))
234  return true;
235 
236  return false;
237 }
238 
239 
240 void my_coll_agg_error(DTCollation &c1,
241  DTCollation &c2, const char *fname)
242 {
243  my_error(ER_CANT_AGGREGATE_2COLLATIONS,MYF(0),
244  c1.collation->name,c1.derivation_name(),
245  c2.collation->name,c2.derivation_name(),
246  fname);
247 }
248 
249 
250 void my_coll_agg_error(DTCollation &c1,
251  DTCollation &c2,
252  DTCollation &c3,
253  const char *fname)
254 {
255  my_error(ER_CANT_AGGREGATE_3COLLATIONS,MYF(0),
256  c1.collation->name,c1.derivation_name(),
257  c2.collation->name,c2.derivation_name(),
258  c3.collation->name,c3.derivation_name(),
259  fname);
260 }
261 
262 
263 void my_coll_agg_error(Item** args, uint32_t count, const char *fname,
264  int item_sep)
265 {
266  if (count == 2)
267  my_coll_agg_error(args[0]->collation, args[item_sep]->collation, fname);
268  else if (count == 3)
269  my_coll_agg_error(args[0]->collation, args[item_sep]->collation,
270  args[2*item_sep]->collation, fname);
271  else
272  my_error(ER_CANT_AGGREGATE_NCOLLATIONS,MYF(0),fname);
273 }
274 
275 } /* namespace drizzled */
TODO: Rename this file - func.h is stupid.
DRIZZLED_LOCAL bool aggregate(DTCollation &dt, uint32_t flags=0)
Definition: dtcollation.cc:74
Derivation
Definition: enum.h:38