mariadb/include/data0type.ic
marko 8f18616ef0 Reindent the code base (except for ha_innodb.{cc,h} and generated parser
and lexer files).  From now on, the following Emacs cc-mode settings apply
when indenting C function bodies in InnoDB:

(setq c-basic-offset 8)
(setq c-label-minimum-indentation 0)
(add-to-list 'c-offsets-alist '(c . 0))
(add-to-list 'c-offsets-alist '(label . [0]))

The indentation rules for function declarations still have not been
formalized, and they must be formatted manually.

Try to limit all lines to at most 79 characters (assuming TAB stops every
8 characters) by splitting lines before opening parenthesis, or at
string constants.

Fix some grammar mistakes in diagnostic output:
 match to, match with -> match
 found from -> found in
 trying rename -> trying to rename

Fix an error in page_check_dir(): it said "supremum not pointed to"
when the infimum was not pointed to.

Enclose commented-out code snippets in #if 0 ... #endif instead of /* ... */.
Add (void*) casts to some %p parameters in fprintf() calls.  Try to
split lines before a binary operator, not after one.  (These three fixes
were not made everywhere.)
2006-08-28 17:42:45 +00:00

540 lines
13 KiB
Text

/******************************************************
Data types
(c) 1996 Innobase Oy
Created 1/16/1996 Heikki Tuuri
*******************************************************/
#include "mach0data.h"
#ifndef UNIV_HOTBACKUP
/**********************************************************************
Get the variable length bounds of the given character set.
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
this function, you MUST change also the prototype here! */
extern
void
innobase_get_cset_width(
/*====================*/
ulint cset, /* in: MySQL charset-collation code */
ulint* mbminlen, /* out: minimum length of a char (in bytes) */
ulint* mbmaxlen); /* out: maximum length of a char (in bytes) */
#endif /* !UNIV_HOTBACKUP */
/*************************************************************************
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 MySQL type code from a dtype. */
UNIV_INLINE
ulint
dtype_get_mysql_type(
/*=================*/
/* out: MySQL type code; this is NOT an InnoDB
type code! */
dtype_t* type) /* in: type struct */
{
return(type->prtype & 0xFFUL);
}
/*************************************************************************
Sets the mbminlen and mbmaxlen members of a data type structure. */
UNIV_INLINE
void
dtype_set_mblen(
/*============*/
dtype_t* type) /* in/out: type struct */
{
ut_ad(type);
if (dtype_is_string_type(type->mtype)) {
#ifndef UNIV_HOTBACKUP
innobase_get_cset_width(dtype_get_charset_coll(type->prtype),
&type->mbminlen, &type->mbmaxlen);
ut_ad(type->mbminlen <= type->mbmaxlen);
#else /* !UNIV_HOTBACKUP */
#ifdef notdefined
printf("ibbackup: DEBUG: type->mtype=%lu, type->prtype=%lu\n",
type->mtype, type->prtype);
#endif
ut_a(type->mtype <= DATA_BINARY);
#ifdef notdefined
ut_a(type->prtype == (DATA_BINARY | DATA_NOT_NULL));
#endif
type->mbminlen = type->mbmaxlen = 1;
#endif /* !UNIV_HOTBACKUP */
} else {
type->mbminlen = type->mbmaxlen = 0;
}
}
/*************************************************************************
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;
dtype_set_mblen(type);
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 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 minimum length of a character, in bytes. */
UNIV_INLINE
ulint
dtype_get_mbminlen(
/*===============*/
/* out: minimum length of a char, in bytes,
or 0 if this is not a character type */
const dtype_t* type) /* in: type */
{
ut_ad(type);
return(type->mbminlen);
}
/*************************************************************************
Gets the maximum length of a character, in bytes. */
UNIV_INLINE
ulint
dtype_get_mbmaxlen(
/*===============*/
/* out: maximum length of a char, in bytes,
or 0 if this is not a character type */
const dtype_t* type) /* in: type */
{
ut_ad(type);
return(type->mbmaxlen);
}
/*************************************************************************
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 */
const dtype_t* type) /* in: type */
{
switch (type->mtype) {
case DATA_FIXBINARY:
case DATA_BINARY:
if (UNIV_UNLIKELY(dtype_get_charset_coll(type->prtype)
== DATA_MYSQL_BINARY_CHARSET_COLL)) {
/* Starting from 5.0.18, do not pad
VARBINARY or BINARY columns. */
return(ULINT_UNDEFINED);
}
/* Fall through */
case DATA_CHAR:
case DATA_VARCHAR:
case DATA_MYSQL:
case DATA_VARMYSQL:
/* Space is the padding character for all char and binary
strings, and starting from 5.0.3, also for TEXT strings. */
return(0x20);
case DATA_BLOB:
if ((type->prtype & DATA_BINARY_TYPE) == 0) {
return(0x20);
}
/* Fall through */
default:
/* 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 */
{
#if 6 != DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
#error "6 != DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE"
#endif
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);
ut_ad(dtype_get_charset_coll(type->prtype) < 256);
mach_write_to_2(buf + 4, dtype_get_charset_coll(type->prtype));
if (type->prtype & DATA_NOT_NULL) {
buf[4] |= 128;
}
}
/**************************************************************************
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);
dtype_set_mblen(type);
}
/**************************************************************************
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;
#if 6 != DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
#error "6 != DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE"
#endif
type->mtype = buf[0] & 63;
type->prtype = buf[1];
if (buf[0] & 128) {
type->prtype |= DATA_BINARY_TYPE;
}
if (buf[4] & 128) {
type->prtype |= DATA_NOT_NULL;
}
type->len = mach_read_from_2(buf + 2);
mach_read_from_2(buf + 4);
charset_coll = mach_read_from_2(buf + 4) & 0x7fff;
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);
}
dtype_set_mblen(type);
}
/***************************************************************************
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_SYS:
#ifdef UNIV_DEBUG
switch (type->prtype & DATA_MYSQL_TYPE_MASK) {
default:
ut_ad(0);
return(0);
case DATA_ROW_ID:
ut_ad(type->len == DATA_ROW_ID_LEN);
break;
case DATA_TRX_ID:
ut_ad(type->len == DATA_TRX_ID_LEN);
break;
case DATA_ROLL_PTR:
ut_ad(type->len == DATA_ROLL_PTR_LEN);
break;
case DATA_MIX_ID:
ut_ad(type->len == DATA_MIX_ID_LEN);
break;
}
#endif /* UNIV_DEBUG */
case DATA_CHAR:
case DATA_FIXBINARY:
case DATA_INT:
case DATA_FLOAT:
case DATA_DOUBLE:
return(dtype_get_len(type));
case DATA_MYSQL:
if (type->prtype & DATA_BINARY_TYPE) {
return(dtype_get_len(type));
} else {
#ifdef UNIV_HOTBACKUP
if (type->mbminlen == type->mbmaxlen) {
return(dtype_get_len(type));
}
#else /* UNIV_HOTBACKUP */
/* We play it safe here and ask MySQL for
mbminlen and mbmaxlen. Although
type->mbminlen and type->mbmaxlen are
initialized if and only if type->prtype
is (in one of the 3 functions in this file),
it could be that none of these functions
has been called. */
ulint mbminlen, mbmaxlen;
innobase_get_cset_width
(dtype_get_charset_coll(type->prtype),
&mbminlen, &mbmaxlen);
if (UNIV_UNLIKELY(type->mbminlen != mbminlen)
|| UNIV_UNLIKELY(type->mbmaxlen != mbmaxlen)) {
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: "
"mbminlen=%lu, "
"mbmaxlen=%lu, "
"type->mbminlen=%lu, "
"type->mbmaxlen=%lu\n",
(ulong) mbminlen,
(ulong) mbmaxlen,
(ulong) type->mbminlen,
(ulong) type->mbmaxlen);
}
if (mbminlen == mbmaxlen) {
return(dtype_get_len(type));
}
#endif /* !UNIV_HOTBACKUP */
}
/* fall through for variable-length charsets */
case DATA_VARCHAR:
case DATA_BINARY:
case DATA_DECIMAL:
case DATA_VARMYSQL:
case DATA_BLOB:
return(0);
default:
ut_error;
}
return(0);
}
/***************************************************************************
Returns the minimum size of a data type. */
UNIV_INLINE
ulint
dtype_get_min_size(
/*===============*/
/* out: minimum size */
const dtype_t* type) /* in: type */
{
switch (type->mtype) {
case DATA_SYS:
#ifdef UNIV_DEBUG
switch (type->prtype & DATA_MYSQL_TYPE_MASK) {
default:
ut_ad(0);
return(0);
case DATA_ROW_ID:
ut_ad(type->len == DATA_ROW_ID_LEN);
break;
case DATA_TRX_ID:
ut_ad(type->len == DATA_TRX_ID_LEN);
break;
case DATA_ROLL_PTR:
ut_ad(type->len == DATA_ROLL_PTR_LEN);
break;
case DATA_MIX_ID:
ut_ad(type->len == DATA_MIX_ID_LEN);
break;
}
#endif /* UNIV_DEBUG */
case DATA_CHAR:
case DATA_FIXBINARY:
case DATA_INT:
case DATA_FLOAT:
case DATA_DOUBLE:
return(type->len);
case DATA_MYSQL:
if ((type->prtype & DATA_BINARY_TYPE)
|| type->mbminlen == type->mbmaxlen) {
return(type->len);
}
/* this is a variable-length character set */
ut_a(type->mbminlen > 0);
ut_a(type->mbmaxlen > type->mbminlen);
ut_a(type->len % type->mbmaxlen == 0);
return(type->len * type->mbminlen / type->mbmaxlen);
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);
}