/****************************************************** Data types (c) 1996 Innobase Oy Created 1/16/1996 Heikki Tuuri *******************************************************/ #include "mach0data.h" /************************************************************************* Sets a data type structure. */ UNIV_INLINE void dtype_set( /*======*/ dtype_t* type, /* in: type struct to init */ ulint mtype, /* in: main data type */ ulint prtype, /* in: precise type */ ulint len, /* in: length of type */ ulint prec) /* in: precision of type */ { ut_ad(type); ut_ad(mtype <= DATA_MTYPE_MAX); type->mtype = mtype; type->prtype = prtype; type->len = len; type->prec = prec; ut_ad(dtype_validate(type)); } /************************************************************************* Copies a data type structure. */ UNIV_INLINE void dtype_copy( /*=======*/ dtype_t* type1, /* in: type struct to copy to */ dtype_t* type2) /* in: type struct to copy from */ { *type1 = *type2; ut_ad(dtype_validate(type1)); } /************************************************************************* Gets the SQL main data type. */ UNIV_INLINE ulint dtype_get_mtype( /*============*/ dtype_t* type) { ut_ad(type); return(type->mtype); } /************************************************************************* Gets the precise data type. */ UNIV_INLINE ulint dtype_get_prtype( /*=============*/ dtype_t* type) { ut_ad(type); return(type->prtype); } /************************************************************************* Gets the MySQL charset-collation code for MySQL string types. */ UNIV_INLINE ulint dtype_get_charset_coll( /*===================*/ ulint prtype) /* in: precise data type */ { return((prtype >> 16) & 0xFFUL); } /************************************************************************* Gets the type length. */ UNIV_INLINE ulint dtype_get_len( /*==========*/ dtype_t* type) { ut_ad(type); return(type->len); } /************************************************************************* Gets the type precision. */ UNIV_INLINE ulint dtype_get_prec( /*===========*/ dtype_t* type) { ut_ad(type); return(type->prec); } /************************************************************************* Gets the padding character code for the type. */ UNIV_INLINE ulint dtype_get_pad_char( /*===============*/ /* out: padding character code, or ULINT_UNDEFINED if no padding specified */ dtype_t* type) /* in: type */ { if (type->mtype == DATA_CHAR || type->mtype == DATA_VARCHAR || type->mtype == DATA_BINARY || type->mtype == DATA_FIXBINARY || type->mtype == DATA_MYSQL || type->mtype == DATA_VARMYSQL) { /* Space is the padding character for all char and binary strings */ return((ulint)' '); } /* No padding specified */ return(ULINT_UNDEFINED); } /************************************************************************** Stores for a type the information which determines its alphabetical ordering and the storage size of an SQL NULL value. This is the >= 4.1.x storage format. */ UNIV_INLINE void dtype_new_store_for_order_and_null_size( /*====================================*/ byte* buf, /* in: buffer for DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE bytes where we store the info */ dtype_t* type) /* in: type struct */ { ut_ad(6 == DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE); buf[0] = (byte)(type->mtype & 0xFFUL); if (type->prtype & DATA_BINARY_TYPE) { buf[0] = buf[0] | 128; } /* In versions < 4.1.2 we had: if (type->prtype & DATA_NONLATIN1) { buf[0] = buf[0] | 64; } */ buf[1] = (byte)(type->prtype & 0xFFUL); mach_write_to_2(buf + 2, type->len & 0xFFFFUL); mach_write_to_2(buf + 4, dtype_get_charset_coll(type->prtype)); /* Note that the second last byte is left unused, because the charset-collation code is always < 256 */ } /************************************************************************** Reads to a type the stored information which determines its alphabetical ordering and the storage size of an SQL NULL value. This is the < 4.1.x storage format. */ UNIV_INLINE void dtype_read_for_order_and_null_size( /*===============================*/ dtype_t* type, /* in: type struct */ byte* buf) /* in: buffer for stored type order info */ { ut_ad(4 == DATA_ORDER_NULL_TYPE_BUF_SIZE); type->mtype = buf[0] & 63; type->prtype = buf[1]; if (buf[0] & 128) { type->prtype = type->prtype | DATA_BINARY_TYPE; } type->len = mach_read_from_2(buf + 2); type->prtype = dtype_form_prtype(type->prtype, data_mysql_default_charset_coll); } /************************************************************************** Reads to a type the stored information which determines its alphabetical ordering and the storage size of an SQL NULL value. This is the >= 4.1.x storage format. */ UNIV_INLINE void dtype_new_read_for_order_and_null_size( /*===================================*/ dtype_t* type, /* in: type struct */ byte* buf) /* in: buffer for stored type order info */ { ulint charset_coll; ut_ad(6 == DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE); type->mtype = buf[0] & 63; type->prtype = buf[1]; if (buf[0] & 128) { type->prtype = type->prtype | DATA_BINARY_TYPE; } type->len = mach_read_from_2(buf + 2); mach_read_from_2(buf + 4); charset_coll = mach_read_from_2(buf + 4); if (dtype_is_string_type(type->mtype)) { ut_a(charset_coll < 256); if (charset_coll == 0) { /* This insert buffer record was inserted with MySQL version < 4.1.2, and the charset-collation code was not explicitly stored to dtype->prtype at that time. It must be the default charset-collation of this MySQL installation. */ charset_coll = data_mysql_default_charset_coll; } type->prtype = dtype_form_prtype(type->prtype, charset_coll); } } /*************************************************************************** Returns the size of a fixed size data type, 0 if not a fixed size type. */ UNIV_INLINE ulint dtype_get_fixed_size( /*=================*/ /* out: fixed size, or 0 */ dtype_t* type) /* in: type */ { ulint mtype; mtype = dtype_get_mtype(type); switch (mtype) { case DATA_CHAR: case DATA_FIXBINARY: case DATA_INT: case DATA_FLOAT: case DATA_DOUBLE: case DATA_MYSQL: return(dtype_get_len(type)); case DATA_SYS: if (type->prtype == DATA_ROW_ID) { return(DATA_ROW_ID_LEN); } else if (type->prtype == DATA_TRX_ID) { return(DATA_TRX_ID_LEN); } else if (type->prtype == DATA_ROLL_PTR) { return(DATA_ROLL_PTR_LEN); } else { return(0); } case DATA_VARCHAR: case DATA_BINARY: case DATA_DECIMAL: case DATA_VARMYSQL: case DATA_BLOB: return(0); default: ut_error; } return(0); } /*************************************************************************** Returns a stored SQL NULL size for a type. For fixed length types it is the fixed length of the type, otherwise 0. */ UNIV_INLINE ulint dtype_get_sql_null_size( /*====================*/ /* out: SQL null storage size */ dtype_t* type) /* in: type */ { return(dtype_get_fixed_size(type)); } /*************************************************************************** Returns TRUE if a type is of a fixed size. */ UNIV_INLINE ibool dtype_is_fixed_size( /*================*/ /* out: TRUE if fixed size */ dtype_t* type) /* in: type */ { ulint size; size = dtype_get_fixed_size(type); if (size) { return(TRUE); } return(FALSE); }