584.4.1
by Monty Taylor
Split out DTCollation. |
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 |
#ifndef DRIZZLED_DTCOLLATION_H
|
|
21 |
#define DRIZZLED_DTCOLLATION_H
|
|
22 |
||
23 |
#include <stdint.h> |
|
24 |
||
25 |
#include <drizzled/definitions.h> |
|
26 |
||
27 |
class Item; |
|
28 |
typedef struct charset_info_st CHARSET_INFO; |
|
29 |
||
30 |
||
31 |
class DTCollation { |
|
32 |
public: |
|
33 |
const CHARSET_INFO *collation; |
|
34 |
enum Derivation derivation; |
|
35 |
uint32_t repertoire; |
|
36 |
||
37 |
void set_repertoire_from_charset(const CHARSET_INFO * const cs); |
|
38 |
||
39 |
DTCollation(); |
|
40 |
DTCollation(const CHARSET_INFO * const collation_arg, |
|
41 |
Derivation derivation_arg); |
|
42 |
void set(DTCollation &dt); |
|
43 |
void set(const CHARSET_INFO * const collation_arg, |
|
44 |
Derivation derivation_arg); |
|
45 |
void set(const CHARSET_INFO * const collation_arg, |
|
46 |
Derivation derivation_arg, |
|
47 |
uint32_t repertoire_arg); |
|
48 |
void set(const CHARSET_INFO * const collation_arg); |
|
49 |
void set(Derivation derivation_arg); |
|
50 |
bool set(DTCollation &dt1, DTCollation &dt2, uint32_t flags= 0); |
|
51 |
||
52 |
/**
|
|
53 |
Aggregate two collations together taking
|
|
54 |
into account their coercibility (aka derivation):.
|
|
55 |
||
56 |
0 == DERIVATION_EXPLICIT - an explicitly written COLLATE clause @n
|
|
57 |
1 == DERIVATION_NONE - a mix of two different collations @n
|
|
58 |
2 == DERIVATION_IMPLICIT - a column @n
|
|
59 |
3 == DERIVATION_COERCIBLE - a string constant.
|
|
60 |
||
61 |
The most important rules are:
|
|
62 |
-# If collations are the same:
|
|
63 |
chose this collation, and the strongest derivation.
|
|
64 |
-# If collations are different:
|
|
65 |
- Character sets may differ, but only if conversion without
|
|
66 |
data loss is possible. The caller provides flags whether
|
|
67 |
character set conversion attempts should be done. If no
|
|
68 |
flags are substituted, then the character sets must be the same.
|
|
69 |
Currently processed flags are:
|
|
70 |
MY_COLL_ALLOW_SUPERSET_CONV - allow conversion to a superset
|
|
71 |
MY_COLL_ALLOW_COERCIBLE_CONV - allow conversion of a coercible value
|
|
72 |
- two EXPLICIT collations produce an error, e.g. this is wrong:
|
|
73 |
CONCAT(expr1 collate latin1_swedish_ci, expr2 collate latin1_german_ci)
|
|
74 |
- the side with smaller derivation value wins,
|
|
75 |
i.e. a column is stronger than a string constant,
|
|
76 |
an explicit COLLATE clause is stronger than a column.
|
|
77 |
- if derivations are the same, we have DERIVATION_NONE,
|
|
78 |
we'll wait for an explicit COLLATE clause which possibly can
|
|
79 |
come from another argument later: for example, this is valid,
|
|
80 |
but we don't know yet when collecting the first two arguments:
|
|
81 |
@code
|
|
82 |
CONCAT(latin1_swedish_ci_column,
|
|
83 |
latin1_german1_ci_column,
|
|
84 |
expr COLLATE latin1_german2_ci)
|
|
85 |
@endcode
|
|
86 |
*/
|
|
87 |
||
88 |
bool aggregate(DTCollation &dt, uint32_t flags= 0); |
|
89 |
||
90 |
const char *derivation_name() const; |
|
91 |
||
92 |
};
|
|
93 |
||
94 |
||
95 |
bool agg_item_collations(DTCollation &c, const char *name, |
|
96 |
Item **items, uint32_t nitems, |
|
97 |
uint32_t flags, int item_sep); |
|
98 |
bool agg_item_collations_for_comparison(DTCollation &c, const char *name, |
|
99 |
Item **items, uint32_t nitems, |
|
100 |
uint32_t flags); |
|
101 |
||
102 |
/**
|
|
103 |
Collect arguments' character sets together.
|
|
104 |
||
105 |
We allow to apply automatic character set conversion in some cases.
|
|
106 |
The conditions when conversion is possible are:
|
|
107 |
- arguments A and B have different charsets
|
|
108 |
- A wins according to coercibility rules
|
|
109 |
(i.e. a column is stronger than a string constant,
|
|
110 |
an explicit COLLATE clause is stronger than a column)
|
|
111 |
- character set of A is either superset for character set of B,
|
|
112 |
or B is a string constant which can be converted into the
|
|
113 |
character set of A without data loss.
|
|
114 |
||
115 |
If all of the above is true, then it's possible to convert
|
|
116 |
B into the character set of A, and then compare according
|
|
117 |
to the collation of A.
|
|
118 |
||
119 |
For functions with more than two arguments:
|
|
120 |
@code
|
|
121 |
collect(A,B,C) ::= collect(collect(A,B),C)
|
|
122 |
@endcode
|
|
123 |
Since this function calls Session::change_item_tree() on the passed Item **
|
|
124 |
pointers, it is necessary to pass the original Item **'s, not copies.
|
|
125 |
Otherwise their values will not be properly restored (see BUG#20769).
|
|
126 |
If the items are not consecutive (eg. args[2] and args[5]), use the
|
|
127 |
item_sep argument, ie.
|
|
128 |
@code
|
|
129 |
agg_item_charsets(coll, fname, &args[2], 2, flags, 3)
|
|
130 |
@endcode
|
|
131 |
*/
|
|
132 |
bool agg_item_charsets(DTCollation &c, const char *name, |
|
133 |
Item **items, uint32_t nitems, uint32_t flags, |
|
134 |
int item_sep); |
|
135 |
||
136 |
||
137 |
void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname); |
|
138 |
void my_coll_agg_error(DTCollation &c1, DTCollation &c2, DTCollation &c3, |
|
139 |
const char *fname); |
|
140 |
void my_coll_agg_error(Item** args, uint32_t count, const char *fname, |
|
141 |
int item_sep); |
|
142 |
||
143 |
#endif /* DRIZZLED_DTCOLLATION_H */ |