mariadb/innobase/include/row0mysql.ic
unknown f9a394dbdd InnoDB: Fix Bug #7350 without hard-coding charset-collation numbers.
innobase/data/data0type.c:
  Add mbminlen and mbmaxlen to dtype_t
innobase/include/data0type.h:
  Add mbminlen and mbmaxlen to dtype_t
  Add dtype_get_mbminlen() and dtype_get_mbmaxlen()
innobase/include/data0type.ic:
  Add dtype_set_mblen()
  Add dtype_get_mbminlen() and dtype_get_mbmaxlen()
  Replace innobase_is_mb_cset() with innobase_get_mb_cset()
innobase/include/row0mysql.h:
  Add mbminlen and mbmaxlen
innobase/include/row0mysql.ic:
  Detect UCS2 collations based on mbminlen
innobase/row/row0sel.c:
  Detect UCS2 collations based on mbminlen
sql/ha_innodb.cc:
  Replace innobase_is_mb_cset() with innobase_get_mb_cset()
  build_template(): Initialize templ->mbminlen and templ->mbmaxlen
2005-02-08 16:41:34 +02:00

121 lines
3.1 KiB
Text

/******************************************************
MySQL interface for Innobase
(C) 2001 Innobase Oy
Created 1/23/2001 Heikki Tuuri
*******************************************************/
/***********************************************************************
Stores a variable-length field (like VARCHAR) length to dest, in the
MySQL format. No real var implemented in MySQL yet! */
UNIV_INLINE
byte*
row_mysql_store_var_len(
/*====================*/
/* out: dest + 2 */
byte* dest, /* in: where to store */
ulint len __attribute__((unused))) /* in: length, must fit in two
bytes */
{
ut_ad(len < 256 * 256);
/*
mach_write_to_2_little_endian(dest, len);
return(dest + 2);
*/
return(dest); /* No real var implemented in MySQL yet! */
}
/***********************************************************************
Reads a MySQL format variable-length field (like VARCHAR) length and
returns pointer to the field data. No real var implemented in MySQL yet! */
UNIV_INLINE
byte*
row_mysql_read_var_ref(
/*===================*/
/* out: field + 2 */
ulint* len, /* out: variable-length field length; does not work
yet! */
byte* field) /* in: field */
{
/*
*len = mach_read_from_2_little_endian(field);
return(field + 2);
*/
UT_NOT_USED(len);
return(field); /* No real var implemented in MySQL yet! */
}
/******************************************************************
Stores a non-SQL-NULL field given in the MySQL format in the Innobase
format. */
UNIV_INLINE
void
row_mysql_store_col_in_innobase_format(
/*===================================*/
dfield_t* dfield, /* in/out: dfield */
byte* buf, /* in/out: buffer for the converted
value; this must be at least col_len
long! */
byte* mysql_data, /* in: MySQL column value, not
SQL NULL; NOTE that dfield may also
get a pointer to mysql_data,
therefore do not discard this as long
as dfield is used! */
ulint col_len, /* in: MySQL column length */
ulint type, /* in: data type */
ulint is_unsigned) /* in: != 0 if unsigned integer type */
{
byte* ptr = mysql_data;
if (type == DATA_INT) {
/* Store integer data in Innobase in a big-endian format,
sign bit negated */
ptr = buf + col_len;
for (;;) {
ptr--;
*ptr = *mysql_data;
if (ptr == buf) {
break;
}
mysql_data++;
}
if (!is_unsigned) {
*ptr = (byte) (*ptr ^ 128);
}
} else if (type == DATA_VARCHAR || type == DATA_VARMYSQL
|| type == DATA_BINARY) {
/* Remove trailing spaces. */
/* Handle UCS2 strings differently. */
ulint mbminlen = dtype_get_mbminlen(
dfield_get_type(dfield));
ptr = row_mysql_read_var_ref(&col_len, mysql_data);
if (mbminlen == 2) {
/* space=0x0020 */
/* Trim "half-chars", just in case. */
col_len &= ~1;
while (col_len >= 2 && ptr[col_len - 2] == 0x00
&& ptr[col_len - 1] == 0x20) {
col_len -= 2;
}
} else {
ut_a(mbminlen == 1);
/* space=0x20 */
while (col_len > 0 && ptr[col_len - 1] == 0x20) {
col_len--;
}
}
} else if (type == DATA_BLOB) {
ptr = row_mysql_read_blob_ref(&col_len, mysql_data, col_len);
}
dfield_set_data(dfield, ptr, col_len);
}