1 /*
2    Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License, version 2.0,
6    as published by the Free Software Foundation.
7 
8    This program is also distributed with certain software (including
9    but not limited to OpenSSL) that is licensed under separate terms,
10    as designated in a particular file or component or in included license
11    documentation.  The authors of MySQL hereby grant you an additional
12    permission to link the program and your derivative works with the
13    separately licensed software that they have included with MySQL.
14 
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License, version 2.0, for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
23 */
24 
25 #ifndef NDB_SQL_UTIL_HPP
26 #define NDB_SQL_UTIL_HPP
27 
28 #include <ndb_global.h>
29 #include <kernel/ndb_limits.h>
30 
31 struct charset_info_st;
32 typedef struct charset_info_st CHARSET_INFO;
33 
34 /**
35  * Helper class with comparison functions on NDB (column) data types.
36  *
37  * Notes: this Helper class
38  * - is used by kernel code
39  * - provides non-elementary functions
40  * - is not generic, template-based code
41  * - has link/library dependencies upon MySQL code
42  * (in contrast to other type utility classes, like ./NdbTypesUtil).
43  */
44 class NdbSqlUtil {
45 public:
46   /**
47    * Compare attribute values.  Returns negative, zero, positive for
48    * less, equal, greater.  We trust DBTUP to validate all data and
49    * mysql upgrade to not invalidate them.  Bad values (such as NaN)
50    * causing undefined results crash here always (require, not assert)
51    * since they are likely to cause a more obscure crash in DBTUX.
52    * wl4163_todo: API probably should not crash.
53    *
54    * Parameters are pointers to values (no alignment requirements) and
55    * their lengths in bytes.  First parameter is a pointer to type
56    * specific extra info.  Char types receive CHARSET_INFO in it.
57    */
58   typedef int Cmp(const void* info, const void* p1, uint n1, const void* p2, uint n2);
59 
60   /**
61    * Prototype for "like" comparison.  Defined for string types.  First
62    * argument can be fixed or var* type, second argument is fixed.
63    * Returns 0 on match, +1 on no match, and -1 on bad data.
64    *
65    * Uses default special chars ( \ % _ ).
66    */
67   typedef int Like(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2);
68 
69   /**
70    * Prototype for mask comparisons.  Defined for bit type.
71    *
72    * If common portion of data AND Mask is equal to mask
73    * return 0, else return 1.
74    * If cmpZero, compare data AND Mask to zero.
75    */
76   typedef int AndMask(const void* data, unsigned dataLen, const void* mask, unsigned maskLen, bool cmpZero);
77 
78   struct Type {
79     enum Enum {
80       Undefined = NDB_TYPE_UNDEFINED,
81       Tinyint = NDB_TYPE_TINYINT,
82       Tinyunsigned = NDB_TYPE_TINYUNSIGNED,
83       Smallint = NDB_TYPE_SMALLINT,
84       Smallunsigned = NDB_TYPE_SMALLUNSIGNED,
85       Mediumint = NDB_TYPE_MEDIUMINT,
86       Mediumunsigned = NDB_TYPE_MEDIUMUNSIGNED,
87       Int = NDB_TYPE_INT,
88       Unsigned = NDB_TYPE_UNSIGNED,
89       Bigint = NDB_TYPE_BIGINT,
90       Bigunsigned = NDB_TYPE_BIGUNSIGNED,
91       Float = NDB_TYPE_FLOAT,
92       Double = NDB_TYPE_DOUBLE,
93       Olddecimal = NDB_TYPE_OLDDECIMAL,
94       Char = NDB_TYPE_CHAR,
95       Varchar = NDB_TYPE_VARCHAR,
96       Binary = NDB_TYPE_BINARY,
97       Varbinary = NDB_TYPE_VARBINARY,
98       Datetime = NDB_TYPE_DATETIME,
99       Date = NDB_TYPE_DATE,
100       Blob = NDB_TYPE_BLOB,
101       Text = NDB_TYPE_TEXT,
102       Bit = NDB_TYPE_BIT,
103       Longvarchar = NDB_TYPE_LONGVARCHAR,
104       Longvarbinary = NDB_TYPE_LONGVARBINARY,
105       Time = NDB_TYPE_TIME,
106       Year = NDB_TYPE_YEAR,
107       Timestamp = NDB_TYPE_TIMESTAMP,
108       Olddecimalunsigned = NDB_TYPE_OLDDECIMALUNSIGNED,
109       Decimal = NDB_TYPE_DECIMAL,
110       Decimalunsigned = NDB_TYPE_DECIMALUNSIGNED
111     };
112     Enum m_typeId;      // redundant
113     Cmp* m_cmp;         // comparison method
114     Like* m_like;       // "like" comparison method
115     AndMask* m_mask;    // Mask comparison method
116   };
117 
118   /**
119    * Get type by id.  Can return the Undefined type.
120    */
121   static const Type& getType(Uint32 typeId);
122 
123   /**
124    * Check character set.
125    */
126   static uint check_column_for_pk(Uint32 typeId, const void* info);
127   static uint check_column_for_hash_index(Uint32 typeId, const void* info);
128   static uint check_column_for_ordered_index(Uint32 typeId, const void* info);
129 
130   /**
131    * Get number of length bytes and length from variable length string.
132    * Returns false on error (invalid data).  For other types returns
133    * zero length bytes and the fixed attribute length.
134    */
135   static bool get_var_length(Uint32 typeId, const void* p, unsigned attrlen, Uint32& lb, Uint32& len);
136 
137   /**
138    * Temporary workaround for bug#7284.
139    */
140   static int strnxfrm_bug7284(CHARSET_INFO* cs, unsigned char* dst, unsigned dstLen, const unsigned char*src, unsigned srcLen);
141 
142   /**
143    * Wrapper for 'strnxfrm' who change prototype in 5.6
144    */
145   static size_t ndb_strnxfrm(struct charset_info_st * cs,
146                              uchar *dst, size_t dstlen,
147                              const uchar *src, size_t srclen);
148 
149   /**
150    * Convert attribute data to/from network byte order
151    * This method converts the passed data of the passed type
152    * between host and network byte order.
153    * On little-endian (network order) hosts, it has no effect.
154    */
155   static void convertByteOrder(Uint32 typeId,
156                                Uint32 typeLog2Size,
157                                Uint32 arrayType,
158                                Uint32 arraySize,
159                                uchar* data,
160                                Uint32 dataByteSize);
161 
162 private:
163   friend class NdbPack;
164   /**
165    * List of all types.  Must match Type::Enum.
166    */
167   static const Type m_typeList[];
168   /**
169    * Comparison methods.
170    */
171   static Cmp cmpTinyint;
172   static Cmp cmpTinyunsigned;
173   static Cmp cmpSmallint;
174   static Cmp cmpSmallunsigned;
175   static Cmp cmpMediumint;
176   static Cmp cmpMediumunsigned;
177   static Cmp cmpInt;
178   static Cmp cmpUnsigned;
179   static Cmp cmpBigint;
180   static Cmp cmpBigunsigned;
181   static Cmp cmpFloat;
182   static Cmp cmpDouble;
183   static Cmp cmpOlddecimal;
184   static Cmp cmpChar;
185   static Cmp cmpVarchar;
186   static Cmp cmpBinary;
187   static Cmp cmpVarbinary;
188   static Cmp cmpDatetime;
189   static Cmp cmpDate;
190   static Cmp cmpBlob;
191   static Cmp cmpText;
192   static Cmp cmpBit;
193   static Cmp cmpLongvarchar;
194   static Cmp cmpLongvarbinary;
195   static Cmp cmpTime;
196   static Cmp cmpYear;
197   static Cmp cmpTimestamp;
198   static Cmp cmpOlddecimalunsigned;
199   static Cmp cmpDecimal;
200   static Cmp cmpDecimalunsigned;
201   //
202   static Like likeChar;
203   static Like likeBinary;
204   static Like likeVarchar;
205   static Like likeVarbinary;
206   static Like likeLongvarchar;
207   static Like likeLongvarbinary;
208   //
209   static AndMask maskBit;
210 };
211 
212 #endif
213