/******************************************************
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 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) {
		/* space is the padding character for all char strings */

		return((ulint)' ');
	}

	ut_ad((type->mtype == DATA_BINARY) || (type->mtype == DATA_VARCHAR));

	/* No padding specified */

	return(ULINT_UNDEFINED);
}

/**************************************************************************
Stores to a type the information which determines its alphabetical
ordering. */
UNIV_INLINE
void
dtype_store_for_order_and_null_size(
/*================================*/
	byte*		buf,	/* in: buffer for DATA_ORDER_NULL_TYPE_BUF_SIZE
				bytes */
	dtype_t*	type)	/* in: type struct */
{
	ut_ad(4 == DATA_ORDER_NULL_TYPE_BUF_SIZE);
	
	buf[0] = (byte)(type->mtype & 0xFF);
	buf[1] = (byte)(type->prtype & 0xFF);

	mach_write_to_2(buf + 2, type->len & 0xFFFF);
}

/**************************************************************************
Reads of a type the stored information which determines its alphabetical
ordering. */
UNIV_INLINE
void
dtype_read_for_order_and_null_size(
/*===============================*/
	dtype_t*	type,	/* in: type struct */
	byte*		buf)	/* in: buffer for type order info */
{
	ut_ad(4 == DATA_ORDER_NULL_TYPE_BUF_SIZE);
	
	type->mtype = buf[0];
	type->prtype = buf[1];

	type->len = mach_read_from_2(buf + 2);
}	

/***************************************************************************
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_a(0);
	}

	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);
}