1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Bit type support for non-MyISAM tables.

This commit is contained in:
ramil@mysql.com
2005-04-12 12:27:43 +05:00
parent 4caef066c7
commit c4376b2bc6
12 changed files with 682 additions and 23 deletions

View File

@ -7945,6 +7945,58 @@ const char *Field_bit::unpack(char *to, const char *from)
}
/*
Bit field support for non-MyISAM tables.
*/
Field_bit_as_char::Field_bit_as_char(char *ptr_arg, uint32 len_arg,
uchar *null_ptr_arg, uchar null_bit_arg,
uchar *bit_ptr_arg, uchar bit_ofs_arg,
enum utype unireg_check_arg,
const char *field_name_arg,
struct st_table *table_arg)
: Field_bit(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, bit_ptr_arg,
bit_ofs_arg, unireg_check_arg, field_name_arg, table_arg),
create_length(len_arg)
{
bit_ptr= 0;
bit_ofs= 0;
bit_len= 0;
field_length= ((len_arg + 7) & ~7) / 8;
}
int Field_bit_as_char::store(const char *from, uint length, CHARSET_INFO *cs)
{
int delta;
uchar bits= create_length & 7;
for (; !*from && length; from++, length--); // skip left 0's
delta= field_length - length;
if (delta < 0 ||
(delta == 0 && bits && (uint) (uchar) *from >= (uint) (1 << bits)))
{
memset(ptr, 0xff, field_length);
*ptr&= ((1 << bits) - 1); /* set first byte */
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
return 1;
}
bzero(ptr, delta);
memcpy(ptr + delta, from, length);
return 0;
}
void Field_bit_as_char::sql_type(String &res) const
{
CHARSET_INFO *cs= res.charset();
ulong length= cs->cset->snprintf(cs, (char*) res.ptr(), res.alloced_length(),
"bit(%d)", (int) create_length);
res.length((uint) length);
}
/*****************************************************************************
Handling of field and create_field
*****************************************************************************/
@ -7970,9 +8022,16 @@ void create_field::create_length_to_internal_length(void)
key_length= pack_length;
break;
case MYSQL_TYPE_BIT:
pack_length= calc_pack_length(sql_type, length);
/* We need one extra byte to store the bits we save among the null bits */
key_length= pack_length+ test(length & 7);
if (f_bit_as_char(pack_flag))
{
key_length= pack_length= ((length + 7) & ~7) / 8;
}
else
{
pack_length= length / 8;
/* We need one extra byte to store the bits we save among the null bits */
key_length= pack_length + test(length & 7);
}
break;
case MYSQL_TYPE_NEWDECIMAL:
key_length= pack_length= my_decimal_get_binary_size(length, decimals);
@ -8086,7 +8145,7 @@ Field *make_field(char *ptr, uint32 field_length,
uchar bit_offset;
LINT_INIT(bit_ptr);
LINT_INIT(bit_offset);
if (field_type == FIELD_TYPE_BIT)
if (field_type == FIELD_TYPE_BIT && !f_bit_as_char(pack_flag))
{
bit_ptr= null_pos;
bit_offset= null_bit;
@ -8236,7 +8295,10 @@ Field *make_field(char *ptr, uint32 field_length,
case FIELD_TYPE_NULL:
return new Field_null(ptr,field_length,unireg_check,field_name,table, field_charset);
case FIELD_TYPE_BIT:
return new Field_bit(ptr, field_length, null_pos, null_bit, bit_ptr,
return f_bit_as_char(pack_flag) ?
new Field_bit_as_char(ptr, field_length, null_pos, null_bit, bit_ptr,
bit_offset, unireg_check, field_name, table) :
new Field_bit(ptr, field_length, null_pos, null_bit, bit_ptr,
bit_offset, unireg_check, field_name, table);
default: // Impossible (Wrong version)
break;