1 /*****************************************************************************
2 
3 Copyright (c) 1996, 2019, Oracle and/or its affiliates. All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License, version 2.0, as published by the
7 Free Software Foundation.
8 
9 This program is also distributed with certain software (including but not
10 limited to OpenSSL) that is licensed under separate terms, as designated in a
11 particular file or component or in included license documentation. The authors
12 of MySQL hereby grant you an additional permission to link the program and
13 your derivative works with the separately licensed software that they have
14 included with MySQL.
15 
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
19 for more details.
20 
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
24 
25 *****************************************************************************/
26 
27 /** @file include/data0type.h
28  Data types
29 
30  Created 1/16/1996 Heikki Tuuri
31  *******************************************************/
32 
33 #ifndef data0type_h
34 #define data0type_h
35 
36 #include "univ.i"
37 
38 extern ulint data_mysql_default_charset_coll;
39 #define DATA_MYSQL_BINARY_CHARSET_COLL 63
40 
41 /* SQL data type struct */
42 struct dtype_t;
43 
44 /** SQL Like operator comparison types */
45 enum ib_like_t {
46   IB_LIKE_EXACT, /**< e.g.  STRING */
47   IB_LIKE_PREFIX /**< e.g., STRING% */
48 };
49 
50 /*-------------------------------------------*/
51 /* The 'MAIN TYPE' of a column */
52 #define DATA_MISSING 0 /* missing column */
53 #define DATA_VARCHAR                               \
54   1 /* character varying of the                    \
55     latin1_swedish_ci charset-collation; note      \
56     that the MySQL format for this, DATA_BINARY,   \
57     DATA_VARMYSQL, is also affected by whether the \
58     'precise type' contains                        \
59     DATA_MYSQL_TRUE_VARCHAR */
60 #define DATA_CHAR                                         \
61   2                      /* fixed length character of the \
62                          latin1_swedish_ci charset-collation */
63 #define DATA_FIXBINARY 3 /* binary string of fixed length */
64 #define DATA_BINARY 4    /* binary string */
65 #define DATA_BLOB                                                        \
66   5                      /* binary large object, or a TEXT type;         \
67                          if prtype & DATA_BINARY_TYPE == 0, then this is \
68                          actually a TEXT column (or a BLOB created       \
69                          with < 4.0.14; since column prefix indexes      \
70                          came only in 4.0.14, the missing flag in BLOBs  \
71                          created before that does not cause any harm) */
72 #define DATA_INT 6       /* integer: can be any size 1 - 8 bytes */
73 #define DATA_SYS_CHILD 7 /* address of the child page in node pointer */
74 #define DATA_SYS 8       /* system column */
75 
76 /* Data types >= DATA_FLOAT must be compared using the whole field, not as
77 binary strings */
78 
79 #define DATA_FLOAT 9
80 #define DATA_DOUBLE 10
81 #define DATA_DECIMAL 11  /* decimal number stored as an ASCII string */
82 #define DATA_VARMYSQL 12 /* any charset varying length char */
83 #define DATA_MYSQL 13    /* any charset fixed length char */
84                          /* NOTE that 4.1.1 used DATA_MYSQL and
85                          DATA_VARMYSQL for all character sets, and the
86                          charset-collation for tables created with it
87                          can also be latin1_swedish_ci */
88 
89 /* DATA_POINT&DATA_VAR_POINT are for standard geometry datatype 'point' and
90 DATA_GEOMETRY include all other standard geometry datatypes as described in
91 OGC standard(line_string, polygon, multi_point, multi_polygon,
92 multi_line_string, geometry_collection, geometry).
93 Currently, geometry data is stored in the standard Well-Known Binary(WKB)
94 format (http://www.opengeospatial.org/standards/sfa).
95 We use BLOB as underlying datatype for DATA_GEOMETRY and DATA_VAR_POINT
96 while CHAR for DATA_POINT */
97 #define DATA_GEOMETRY 14 /* geometry datatype of variable length */
98 /* The following two are disabled temporarily, we won't create them in
99 get_innobase_type_from_mysql_type().
100 TODO: We will enable DATA_POINT/them when we come to the fixed-length POINT
101 again. */
102 #define DATA_POINT 15 /* geometry datatype of fixed length POINT */
103 #define DATA_VAR_POINT                       \
104   16 /* geometry datatype of variable length \
105      POINT, used when we want to store POINT \
106      as BLOB internally */
107 #define DATA_MTYPE_MAX                        \
108   63 /* dtype_store_for_order_and_null_size() \
109      requires the values are <= 63 */
110 
111 #define DATA_MTYPE_CURRENT_MIN DATA_VARCHAR   /* minimum value of mtype */
112 #define DATA_MTYPE_CURRENT_MAX DATA_VAR_POINT /* maximum value of mtype */
113 /*-------------------------------------------*/
114 /* The 'PRECISE TYPE' of a column */
115 /*
116 Tables created by a MySQL user have the following convention:
117 
118 - In the least significant byte in the precise type we store the MySQL type
119 code (not applicable for system columns).
120 
121 - In the second least significant byte we OR flags DATA_NOT_NULL,
122 DATA_UNSIGNED, DATA_BINARY_TYPE.
123 
124 - In the third least significant byte of the precise type of string types we
125 store the MySQL charset-collation code. In DATA_BLOB columns created with
126 < 4.0.14 we do not actually know if it is a BLOB or a TEXT column. Since there
127 are no indexes on prefixes of BLOB or TEXT columns in < 4.0.14, this is no
128 problem, though.
129 
130 Note that versions < 4.1.2 or < 5.0.1 did not store the charset code to the
131 precise type, since the charset was always the default charset of the MySQL
132 installation. If the stored charset code is 0 in the system table SYS_COLUMNS
133 of InnoDB, that means that the default charset of this MySQL installation
134 should be used.
135 
136 When loading a table definition from the system tables to the InnoDB data
137 dictionary cache in main memory, InnoDB versions >= 4.1.2 and >= 5.0.1 check
138 if the stored charset-collation is 0, and if that is the case and the type is
139 a non-binary string, replace that 0 by the default charset-collation code of
140 this MySQL installation. In short, in old tables, the charset-collation code
141 in the system tables on disk can be 0, but in in-memory data structures
142 (dtype_t), the charset-collation code is always != 0 for non-binary string
143 types.
144 
145 In new tables, in binary string types, the charset-collation code is the
146 MySQL code for the 'binary charset', that is, != 0.
147 
148 For binary string types and for DATA_CHAR, DATA_VARCHAR, and for those
149 DATA_BLOB which are binary or have the charset-collation latin1_swedish_ci,
150 InnoDB performs all comparisons internally, without resorting to the MySQL
151 comparison functions. This is to save CPU time.
152 
153 InnoDB's own internal system tables have different precise types for their
154 columns, and for them the precise type is usually not used at all.
155 */
156 
157 #define DATA_ENGLISH                                                \
158   4                    /* English language character string: this   \
159                        is a relic from pre-MySQL time and only used \
160                        for InnoDB's own system tables */
161 #define DATA_ERROR 111 /* another relic from pre-MySQL time */
162 
163 #define DATA_MYSQL_TYPE_MASK                     \
164   255 /* AND with this mask to extract the MySQL \
165       type from the precise type */
166 #define DATA_MYSQL_TRUE_VARCHAR          \
167   15 /* MySQL type code for the >= 5.0.3 \
168      format true VARCHAR */
169 
170 /* Precise data types for system columns and the length of those columns;
171 NOTE: the values must run from 0 up in the order given! All codes must
172 be less than 256 */
173 #define DATA_ROW_ID 0     /* row id: a 48-bit integer */
174 #define DATA_ROW_ID_LEN 6 /* stored length for row id */
175 
176 /** Transaction id: 6 bytes */
177 constexpr size_t DATA_TRX_ID = 1;
178 
179 /** Transaction ID type size in bytes. */
180 constexpr size_t DATA_TRX_ID_LEN = 6;
181 
182 /** Rollback data pointer: 7 bytes */
183 constexpr size_t DATA_ROLL_PTR = 2;
184 
185 /** Rollback data pointer type size in bytes. */
186 constexpr size_t DATA_ROLL_PTR_LEN = 7;
187 
188 #define DATA_N_SYS_COLS 3 /* number of system columns defined above */
189 
190 #define DATA_ITT_N_SYS_COLS 2
191 /* number of system columns for intrinsic
192 temporary table */
193 
194 #define DATA_FTS_DOC_ID 3 /* Used as FTS DOC ID column */
195 
196 #define DATA_SYS_PRTYPE_MASK 0xF /* mask to extract the above from prtype */
197 
198 /* Flags ORed to the precise data type */
199 #define DATA_NOT_NULL                          \
200   256 /* this is ORed to the precise type when \
201       the column is declared as NOT NULL */
202 #define DATA_UNSIGNED                          \
203   512 /* this id ORed to the precise type when \
204       we have an unsigned integer type */
205 #define DATA_BINARY_TYPE                         \
206   1024 /* if the data type is a binary character \
207        string, this is ORed to the precise type: \
208        this only holds for tables created with   \
209        >= MySQL-4.0.14 */
210 /* #define	DATA_NONLATIN1	2048 This is a relic from < 4.1.2 and < 5.0.1.
211                                 In earlier versions this was set for some
212                                 BLOB columns.
213 */
214 #define DATA_GIS_MBR 2048                        /* Used as GIS MBR column */
215 #define DATA_MBR_LEN SPDIMS * 2 * sizeof(double) /* GIS MBR length*/
216 
217 #define DATA_LONG_TRUE_VARCHAR                                     \
218   4096                         /* this is ORed to the precise data \
219                        type when the column is true VARCHAR where \
220                        MySQL uses 2 bytes to store the data len;  \
221                        for shorter VARCHARs MySQL uses only 1 byte */
222 #define DATA_VIRTUAL 8192      /* Virtual column */
223 #define DATA_MULTI_VALUE 16384 /* Multi-value Virtual column */
224 
225 /*-------------------------------------------*/
226 
227 /* This many bytes we need to store the type information affecting the
228 alphabetical order for a single field and decide the storage size of an
229 SQL null*/
230 #define DATA_ORDER_NULL_TYPE_BUF_SIZE 4
231 /* In the >= 4.1.x storage format we add 2 bytes more so that we can also
232 store the charset-collation number; one byte is left unused, though */
233 #define DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE 6
234 
235 /* Maximum multi-byte character length in bytes, plus 1 */
236 #define DATA_MBMAX 5
237 
238 /* For DATA_POINT of dimension 2, the length of value in btree is always 25,
239 which is the summary of:
240 SRID_SIZE(4) + WKB_HEADER_SIZE(1+4) + POINT_DATA_SIZE(8*2).
241 So the length of physical record or POINT KEYs on btree are 25.
242 GIS_TODO: When we support multi-dimensions DATA_POINT, we should get the
243 length from corresponding column or index definition, instead of this MACRO
244 */
245 #define DATA_POINT_LEN 25
246 
247 /* Pack mbminlen, mbmaxlen to mbminmaxlen. */
248 #define DATA_MBMINMAXLEN(mbminlen, mbmaxlen) \
249   ((mbmaxlen)*DATA_MBMAX + (mbminlen))
250 /* Get mbminlen from mbminmaxlen. Cast the result of UNIV_EXPECT to ulint
251 because in GCC it returns a long. */
252 #define DATA_MBMINLEN(mbminmaxlen) \
253   ((ulint)UNIV_EXPECT(((mbminmaxlen) % DATA_MBMAX), 1))
254 /* Get mbmaxlen from mbminmaxlen. */
255 #define DATA_MBMAXLEN(mbminmaxlen) ((ulint)((mbminmaxlen) / DATA_MBMAX))
256 
257 /* For checking if a geom_type is POINT */
258 #define DATA_POINT_MTYPE(mtype) \
259   ((mtype) == DATA_POINT || (mtype) == DATA_VAR_POINT)
260 
261 /* For checking if mtype is GEOMETRY datatype */
262 #define DATA_GEOMETRY_MTYPE(mtype) \
263   (DATA_POINT_MTYPE(mtype) || (mtype) == DATA_GEOMETRY)
264 
265 /* For checking if mtype is BLOB or GEOMETRY, since we use BLOB as
266 the underling datatype of GEOMETRY(not DATA_POINT) data. */
267 #define DATA_LARGE_MTYPE(mtype)                         \
268   ((mtype) == DATA_BLOB || (mtype) == DATA_VAR_POINT || \
269    (mtype) == DATA_GEOMETRY)
270 
271 /* For checking if data type is big length data type. */
272 #define DATA_BIG_LEN_MTYPE(len, mtype) ((len) > 255 || DATA_LARGE_MTYPE(mtype))
273 
274 /* For checking if the column is a big length column. */
275 #define DATA_BIG_COL(col) DATA_BIG_LEN_MTYPE((col)->len, (col)->mtype)
276 
277 /* For checking if data type is large binary data type. */
278 #define DATA_LARGE_BINARY(mtype, prtype) \
279   ((mtype) == DATA_GEOMETRY ||           \
280    ((mtype) == DATA_BLOB && !((prtype)&DATA_BINARY_TYPE)))
281 
282 /* We now support 15 bits (up to 32767) collation number */
283 #define MAX_CHAR_COLL_NUM 32767
284 
285 /* Mask to get the Charset Collation number (0x7fff) */
286 #define CHAR_COLL_MASK MAX_CHAR_COLL_NUM
287 
288 #ifndef UNIV_HOTBACKUP
289 /** Gets the MySQL type code from a dtype.
290  @return MySQL type code; this is NOT an InnoDB type code! */
291 UNIV_INLINE
292 ulint dtype_get_mysql_type(const dtype_t *type); /*!< in: type struct */
293 /** Determine how many bytes the first n characters of the given string occupy.
294  If the string is shorter than n characters, returns the number of bytes
295  the characters in the string occupy.
296  @return length of the prefix, in bytes */
297 ulint dtype_get_at_most_n_mbchars(
298     ulint prtype,      /*!< in: precise type */
299     ulint mbminmaxlen, /*!< in: minimum and maximum length of
300                        a multi-byte character */
301     ulint prefix_len,  /*!< in: length of the requested
302                        prefix, in characters, multiplied by
303                        dtype_get_mbmaxlen(dtype) */
304     ulint data_len,    /*!< in: length of str (in bytes) */
305     const char *str);  /*!< in: the string whose prefix
306                        length is being determined */
307 #endif                 /* !UNIV_HOTBACKUP */
308 /** Checks if a data main type is a string type. Also a BLOB is considered a
309  string type.
310  @return true if string type */
311 ibool dtype_is_string_type(
312     ulint mtype); /*!< in: InnoDB main data type code: DATA_CHAR, ... */
313 /** Checks if a type is a binary string type. Note that for tables created with
314  < 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column. For
315  those DATA_BLOB columns this function currently returns FALSE.
316  @return true if binary string type */
317 ibool dtype_is_binary_string_type(ulint mtype,   /*!< in: main data type */
318                                   ulint prtype); /*!< in: precise type */
319 /** Checks if a type is a non-binary string type. That is, dtype_is_string_type
320  is TRUE and dtype_is_binary_string_type is FALSE. Note that for tables created
321  with < 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column.
322  For those DATA_BLOB columns this function currently returns TRUE.
323  @return true if non-binary string type */
324 ibool dtype_is_non_binary_string_type(ulint mtype,   /*!< in: main data type */
325                                       ulint prtype); /*!< in: precise type */
326 
327 /** Sets a data type structure.
328 @param[in]	type	type struct to init
329 @param[in]	mtype	main data type
330 @param[in]	prtype	precise type
331 @param[in]	len	precision of type */
332 UNIV_INLINE
333 void dtype_set(dtype_t *type, ulint mtype, ulint prtype, ulint len);
334 
335 /** Copies a data type structure.
336 @param[in]	type1	type struct to copy to
337 @param[in]	type2	type struct to copy from */
338 UNIV_INLINE
339 void dtype_copy(dtype_t *type1, const dtype_t *type2);
340 
341 /** Gets the SQL main data type.
342  @return SQL main data type */
343 UNIV_INLINE
344 ulint dtype_get_mtype(const dtype_t *type); /*!< in: data type */
345 /** Gets the precise data type.
346  @return precise data type */
347 UNIV_INLINE
348 ulint dtype_get_prtype(const dtype_t *type); /*!< in: data type */
349 
350 /** Compute the mbminlen and mbmaxlen members of a data type structure.
351 @param[in]	mtype		main type
352 @param[in]	prtype		precise type (and collation)
353 @param[out]	mbminlen	minimum length of a multi-byte character
354 @param[out]	mbmaxlen	maximum length of a multi-byte character */
355 UNIV_INLINE
356 void dtype_get_mblen(ulint mtype, ulint prtype, ulint *mbminlen,
357                      ulint *mbmaxlen);
358 
359 /** Gets the MySQL charset-collation code for MySQL string types.
360  @return MySQL charset-collation code */
361 UNIV_INLINE
362 ulint dtype_get_charset_coll(ulint prtype); /*!< in: precise data type */
363 /** Forms a precise type from the < 4.1.2 format precise type plus the
364  charset-collation code.
365  @return precise type, including the charset-collation code */
366 ulint dtype_form_prtype(
367     ulint old_prtype,    /*!< in: the MySQL type code and the flags
368                          DATA_BINARY_TYPE etc. */
369     ulint charset_coll); /*!< in: MySQL charset-collation code */
370 /** Determines if a MySQL string type is a subset of UTF-8.  This function
371  may return false negatives, in case further character-set collation
372  codes are introduced in MySQL later.
373  @return true if a subset of UTF-8 */
374 UNIV_INLINE
375 ibool dtype_is_utf8(ulint prtype); /*!< in: precise data type */
376 /** Gets the type length.
377  @return fixed length of the type, in bytes, or 0 if variable-length */
378 UNIV_INLINE
379 ulint dtype_get_len(const dtype_t *type); /*!< in: data type */
380 #ifndef UNIV_HOTBACKUP
381 /** Gets the minimum length of a character, in bytes.
382  @return minimum length of a char, in bytes, or 0 if this is not a
383  character type */
384 UNIV_INLINE
385 ulint dtype_get_mbminlen(const dtype_t *type); /*!< in: type */
386 /** Gets the maximum length of a character, in bytes.
387  @return maximum length of a char, in bytes, or 0 if this is not a
388  character type */
389 UNIV_INLINE
390 ulint dtype_get_mbmaxlen(const dtype_t *type); /*!< in: type */
391 
392 /** Sets the minimum and maximum length of a character, in bytes.
393 @param[in,out]	type		type
394 @param[in]	mbminlen	minimum length of a char, in bytes, or 0 if
395                                 this is not a character type
396 @param[in]	mbmaxlen	maximum length of a char, in bytes, or 0 if
397                                 this is not a character type */
398 UNIV_INLINE
399 void dtype_set_mbminmaxlen(dtype_t *type, ulint mbminlen, ulint mbmaxlen);
400 #endif /* !UNIV_HOTBACKUP */
401 
402 /** Returns the size of a fixed size data type, 0 if not a fixed size type.
403 @param[in]	mtype		main type
404 @param[in]	prtype		precise type
405 @param[in]	len		length
406 @param[in]	mbminmaxlen	minimum and maximum length of a multibyte
407                                 character, in bytes
408 @param[in]	comp		nonzero=ROW_FORMAT=COMPACT
409 @return fixed size, or 0 */
410 UNIV_INLINE
411 ulint dtype_get_fixed_size_low(ulint mtype, ulint prtype, ulint len,
412                                ulint mbminmaxlen, ulint comp);
413 
414 /** Returns the minimum size of a data type.
415 @param[in]	mtype		main type
416 @param[in]	prtype		precise type
417 @param[in]	len		length
418 @param[in]	mbminmaxlen	minimum and maximum length of a multibyte
419                                 character, in bytes
420 @return minimum size */
421 UNIV_INLINE
422 ulint dtype_get_min_size_low(ulint mtype, ulint prtype, ulint len,
423                              ulint mbminmaxlen);
424 
425 /** Returns the maximum size of a data type. Note: types in system tables may be
426 incomplete and return incorrect information.
427 @param[in]	mtype	main type
428 @param[in]	len	length
429 @return maximum size */
430 UNIV_INLINE
431 ulint dtype_get_max_size_low(ulint mtype, ulint len);
432 
433 /** Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a type.
434 For fixed length types it is the fixed length of the type, otherwise 0.
435 @param[in]	type	type struct
436 @param[in]	comp	nonzero=ROW_FORMAT=COMPACT
437 @return SQL null storage size in ROW_FORMAT=REDUNDANT */
438 UNIV_INLINE
439 ulint dtype_get_sql_null_size(const dtype_t *type, ulint comp);
440 
441 #ifndef UNIV_HOTBACKUP
442 /** Reads to a type the stored information which determines its alphabetical
443 ordering and the storage size of an SQL NULL value.
444 @param[in]	type	type struct
445 @param[in]	buf	buffer for the stored order info */
446 UNIV_INLINE
447 void dtype_read_for_order_and_null_size(dtype_t *type, const byte *buf);
448 
449 /** Stores for a type the information which determines its alphabetical
450 ordering and the storage size of an SQL NULL value. This is the >= 4.1.x
451 storage format.
452 @param[in]	buf		buffer for DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
453                                 bytes where we store the info
454 @param[in]	type		type struct
455 @param[in]	prefix_len	prefix length to replace type->len, or 0 */
456 UNIV_INLINE
457 void dtype_new_store_for_order_and_null_size(byte *buf, const dtype_t *type,
458                                              ulint prefix_len);
459 
460 /** Reads to a type the stored information which determines its alphabetical
461 ordering and the storage size of an SQL NULL value. This is the 4.1.x storage
462 format.
463 @param[in]	type	type struct
464 @param[in]	buf	buffer for stored type order info */
465 UNIV_INLINE
466 void dtype_new_read_for_order_and_null_size(dtype_t *type, const byte *buf);
467 
468 /** Returns the type's SQL name (e.g. BIGINT UNSIGNED) from mtype,prtype,len
469 @param[in]	mtype	main type
470 @param[in]	prtype	precise type
471 @param[in]	len	length
472 @param[out]	name	SQL name
473 @param[in]	name_sz	size of the name buffer
474 @return the SQL type name */
475 UNIV_INLINE
476 char *dtype_sql_name(unsigned mtype, unsigned prtype, unsigned len, char *name,
477                      unsigned name_sz);
478 #endif /* !UNIV_HOTBACKUP */
479 
480 /** Validates a data type structure.
481  @return true if ok */
482 ibool dtype_validate(const dtype_t *type); /*!< in: type struct to validate */
483 #ifdef UNIV_DEBUG
484 /** Print a data type structure.
485 @param[in]	type	data type */
486 void dtype_print(const dtype_t *type);
487 #endif /* UNIV_DEBUG */
488 
489 /* Structure for an SQL data type.
490 If you add fields to this structure, be sure to initialize them everywhere.
491 This structure is initialized in the following functions:
492 dtype_set()
493 dtype_read_for_order_and_null_size()
494 dtype_new_read_for_order_and_null_size()
495 sym_tab_add_null_lit() */
496 
497 struct dtype_t {
498   unsigned prtype : 32; /*!< precise type; MySQL data
499                         type, charset code, flags to
500                         indicate nullability,
501                         signedness, whether this is a
502                         binary string, whether this is
503                         a true VARCHAR where MySQL
504                         uses 2 bytes to store the length */
505   unsigned mtype : 8;   /*!< main data type */
506 
507   /* the remaining fields do not affect alphabetical ordering: */
508 
509   unsigned len : 16;        /*!< length; for MySQL data this
510                             is field->pack_length(),
511                             except that for a >= 5.0.3
512                             type true VARCHAR this is the
513                             maximum byte length of the
514                             string data (in addition to
515                             the string, MySQL uses 1 or 2
516                             bytes to store the string length) */
517   unsigned mbminmaxlen : 5; /*!< minimum and maximum length of a
518                             character, in bytes;
519                             DATA_MBMINMAXLEN(mbminlen,mbmaxlen);
520                             mbminlen=DATA_MBMINLEN(mbminmaxlen);
521                             mbmaxlen=DATA_MBMINLEN(mbminmaxlen) */
522 
is_virtualdtype_t523   bool is_virtual() const { return ((prtype & DATA_VIRTUAL) == DATA_VIRTUAL); }
524 
525   std::ostream &print(std::ostream &out) const;
526 };
527 
528 inline std::ostream &operator<<(std::ostream &out, const dtype_t &obj) {
529   return (obj.print(out));
530 }
531 
532 static_assert(TRUE == 1, "TRUE != 1");
533 
534 static_assert(DATA_TRX_ID_LEN == 6, "DATA_TRX_ID_LEN != 6!");
535 
536 static_assert(DATA_ROLL_PTR_LEN == 7, "DATA_PTR_LEN != 7!");
537 
538 static_assert(DATA_TRX_ID + 1 == DATA_ROLL_PTR, "DATA_TRX_ID value invalid!");
539 
540 #include "data0type.ic"
541 
542 #endif
543