diff --git a/sql/field.cc b/sql/field.cc index 5b1bea4b803..5ce4ef89996 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -10531,20 +10531,17 @@ uint pack_length_to_packflag(uint type) Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root, - uchar *ptr, uint32 field_length, - uchar *null_pos, uchar null_bit, - uint pack_flag, - const Type_handler *handler, - CHARSET_INFO *field_charset, - Field::geometry_type geom_type, uint srid, - Field::utype unireg_check, - TYPELIB *interval, - const LEX_CSTRING *field_name, - uint32 flags) + const Record_addr *rec, + uint32 field_length, + uint pack_flag, + const Type_handler *handler, + CHARSET_INFO *field_charset, + Field::geometry_type geom_type, uint srid, + Field::utype unireg_check, + TYPELIB *interval, + const LEX_CSTRING *field_name, + uint32 flags) { - uchar *UNINIT_VAR(bit_ptr); - uchar UNINIT_VAR(bit_offset); - DBUG_PRINT("debug", ("field_type: %s, field_length: %u, interval: %p, pack_flag: %s%s%s%s%s", handler->name().ptr(), field_length, interval, FLAGSTR(pack_flag, FIELDFLAG_BINARY), @@ -10553,35 +10550,16 @@ Field *make_field(TABLE_SHARE *share, FLAGSTR(pack_flag, FIELDFLAG_PACK), FLAGSTR(pack_flag, FIELDFLAG_BLOB))); + Record_addr addr(rec->ptr(), f_maybe_null(pack_flag) ? rec->null() : + Bit_addr()); + if (handler == &type_handler_row) { DBUG_ASSERT(field_length == 0); DBUG_ASSERT(f_maybe_null(pack_flag)); - return new (mem_root) Field_row(ptr, field_name); + return new (mem_root) Field_row(addr.ptr(), field_name); } - if (handler->real_field_type() == MYSQL_TYPE_BIT && !f_bit_as_char(pack_flag)) - { - bit_ptr= null_pos; - bit_offset= null_bit; - if (f_maybe_null(pack_flag)) // if null field - { - bit_ptr+= (null_bit == 7); // shift bit_ptr and bit_offset - bit_offset= (bit_offset + 1) & 7; - } - } - - if (!f_maybe_null(pack_flag)) - { - null_pos=0; - null_bit=0; - } - else - { - null_bit= ((uchar) 1) << null_bit; - } - - if (f_is_alpha(pack_flag)) { if (!f_is_packed(pack_flag)) @@ -10591,7 +10569,8 @@ Field *make_field(TABLE_SHARE *share, field_type == MYSQL_TYPE_DECIMAL || // 3.23 or 4.0 string field_type == MYSQL_TYPE_VAR_STRING) return new (mem_root) - Field_string(ptr,field_length,null_pos,null_bit, + Field_string(addr.ptr(), field_length, + addr.null_ptr(), addr.null_bit(), unireg_check, field_name, field_charset); if (field_type == MYSQL_TYPE_VARCHAR) @@ -10599,16 +10578,16 @@ Field *make_field(TABLE_SHARE *share, if (unireg_check == Field::TMYSQL_COMPRESSED) return new (mem_root) Field_varstring_compressed( - ptr, field_length, + addr.ptr(), field_length, HA_VARCHAR_PACKLENGTH(field_length), - null_pos, null_bit, + addr.null_ptr(), addr.null_bit(), unireg_check, field_name, share, field_charset, zlib_compression_method); return new (mem_root) - Field_varstring(ptr,field_length, + Field_varstring(addr.ptr(), field_length, HA_VARCHAR_PACKLENGTH(field_length), - null_pos,null_bit, + addr.null_ptr(), addr.null_bit(), unireg_check, field_name, share, field_charset); @@ -10628,7 +10607,7 @@ Field *make_field(TABLE_SHARE *share, { status_var_increment(current_thd->status_var.feature_gis); return new (mem_root) - Field_geom(ptr,null_pos,null_bit, + Field_geom(addr.ptr(), addr.null_ptr(), addr.null_bit(), unireg_check, field_name, share, pack_length, geom_type, srid); } @@ -10637,25 +10616,25 @@ Field *make_field(TABLE_SHARE *share, { if (unireg_check == Field::TMYSQL_COMPRESSED) return new (mem_root) - Field_blob_compressed(ptr, null_pos, null_bit, + Field_blob_compressed(addr.ptr(), addr.null_ptr(), addr.null_bit(), unireg_check, field_name, share, pack_length, field_charset, zlib_compression_method); return new (mem_root) - Field_blob(ptr,null_pos,null_bit, + Field_blob(addr.ptr(), addr.null_ptr(), addr.null_bit(), unireg_check, field_name, share, pack_length, field_charset); } if (interval) { if (f_is_enum(pack_flag)) - return new (mem_root) - Field_enum(ptr,field_length,null_pos,null_bit, + return new (mem_root) + Field_enum(addr.ptr(), field_length, addr.null_ptr(), addr.null_bit(), unireg_check, field_name, pack_length, interval, field_charset); else - return new (mem_root) - Field_set(ptr,field_length,null_pos,null_bit, + return new (mem_root) + Field_set(addr.ptr(), field_length, addr.null_ptr(), addr.null_bit(), unireg_check, field_name, pack_length, interval, field_charset); } @@ -10664,14 +10643,15 @@ Field *make_field(TABLE_SHARE *share, switch (handler->real_field_type()) { case MYSQL_TYPE_DECIMAL: return new (mem_root) - Field_decimal(ptr,field_length,null_pos,null_bit, + Field_decimal(addr.ptr(), field_length, addr.null_ptr(), addr.null_bit(), unireg_check, field_name, f_decimals(pack_flag), f_is_zerofill(pack_flag) != 0, f_is_dec(pack_flag) == 0); case MYSQL_TYPE_NEWDECIMAL: return new (mem_root) - Field_new_decimal(ptr,field_length,null_pos,null_bit, + Field_new_decimal(addr.ptr(), field_length, + addr.null_ptr(), addr.null_bit(), unireg_check, field_name, f_decimals(pack_flag), f_is_zerofill(pack_flag) != 0, @@ -10682,7 +10662,7 @@ Field *make_field(TABLE_SHARE *share, if (decimals == FLOATING_POINT_DECIMALS) decimals= NOT_FIXED_DEC; return new (mem_root) - Field_float(ptr,field_length,null_pos,null_bit, + Field_float(addr.ptr(), field_length, addr.null_ptr(), addr.null_bit(), unireg_check, field_name, decimals, f_is_zerofill(pack_flag) != 0, @@ -10694,7 +10674,7 @@ Field *make_field(TABLE_SHARE *share, if (decimals == FLOATING_POINT_DECIMALS) decimals= NOT_FIXED_DEC; return new (mem_root) - Field_double(ptr,field_length,null_pos,null_bit, + Field_double(addr.ptr(), field_length, addr.null_ptr(), addr.null_bit(), unireg_check, field_name, decimals, f_is_zerofill(pack_flag) != 0, @@ -10702,25 +10682,25 @@ Field *make_field(TABLE_SHARE *share, } case MYSQL_TYPE_TINY: return new (mem_root) - Field_tiny(ptr,field_length,null_pos,null_bit, + Field_tiny(addr.ptr(), field_length, addr.null_ptr(), addr.null_bit(), unireg_check, field_name, f_is_zerofill(pack_flag) != 0, f_is_dec(pack_flag) == 0); case MYSQL_TYPE_SHORT: return new (mem_root) - Field_short(ptr,field_length,null_pos,null_bit, + Field_short(addr.ptr(), field_length, addr.null_ptr(), addr.null_bit(), unireg_check, field_name, f_is_zerofill(pack_flag) != 0, f_is_dec(pack_flag) == 0); case MYSQL_TYPE_INT24: return new (mem_root) - Field_medium(ptr,field_length,null_pos,null_bit, + Field_medium(addr.ptr(), field_length, addr.null_ptr(), addr.null_bit(), unireg_check, field_name, f_is_zerofill(pack_flag) != 0, f_is_dec(pack_flag) == 0); case MYSQL_TYPE_LONG: return new (mem_root) - Field_long(ptr,field_length,null_pos,null_bit, + Field_long(addr.ptr(), field_length, addr.null_ptr(), addr.null_bit(), unireg_check, field_name, f_is_zerofill(pack_flag) != 0, f_is_dec(pack_flag) == 0); @@ -10728,7 +10708,8 @@ Field *make_field(TABLE_SHARE *share, if (flags & (VERS_SYS_START_FLAG|VERS_SYS_END_FLAG)) { return new (mem_root) - Field_vers_trx_id(ptr, field_length, null_pos, null_bit, + Field_vers_trx_id(addr.ptr(), field_length, + addr.null_ptr(), addr.null_bit(), unireg_check, field_name, f_is_zerofill(pack_flag) != 0, f_is_dec(pack_flag) == 0); @@ -10736,82 +10717,93 @@ Field *make_field(TABLE_SHARE *share, else { return new (mem_root) - Field_longlong(ptr,field_length,null_pos,null_bit, - unireg_check, field_name, - f_is_zerofill(pack_flag) != 0, - f_is_dec(pack_flag) == 0); + Field_longlong(addr.ptr(), field_length, + addr.null_ptr(), addr.null_bit(), + unireg_check, field_name, + f_is_zerofill(pack_flag) != 0, + f_is_dec(pack_flag) == 0); } case MYSQL_TYPE_TIMESTAMP: { uint dec= field_length > MAX_DATETIME_WIDTH ? field_length - MAX_DATETIME_WIDTH - 1: 0; - return new_Field_timestamp(mem_root, ptr, null_pos, null_bit, unireg_check, - field_name, share, dec); + return new_Field_timestamp(mem_root, addr.ptr(), + addr.null_ptr(), addr.null_bit(), + unireg_check, field_name, share, dec); } case MYSQL_TYPE_TIMESTAMP2: { uint dec= field_length > MAX_DATETIME_WIDTH ? field_length - MAX_DATETIME_WIDTH - 1: 0; return new (mem_root) - Field_timestampf(ptr, null_pos, null_bit, unireg_check, - field_name, share, dec); + Field_timestampf(addr.ptr(), addr.null_ptr(), addr.null_bit(), + unireg_check, field_name, share, dec); } case MYSQL_TYPE_YEAR: return new (mem_root) - Field_year(ptr,field_length,null_pos,null_bit, + Field_year(addr.ptr(), field_length, addr.null_ptr(), addr.null_bit(), unireg_check, field_name); case MYSQL_TYPE_DATE: return new (mem_root) - Field_date(ptr,null_pos,null_bit, + Field_date(addr.ptr(), addr.null_ptr(), addr.null_bit(), unireg_check, field_name); case MYSQL_TYPE_NEWDATE: return new (mem_root) - Field_newdate(ptr,null_pos,null_bit, + Field_newdate(addr.ptr(), addr.null_ptr(), addr.null_bit(), unireg_check, field_name); case MYSQL_TYPE_TIME: { uint dec= field_length > MIN_TIME_WIDTH ? field_length - MIN_TIME_WIDTH - 1: 0; - return new_Field_time(mem_root, ptr, null_pos, null_bit, unireg_check, - field_name, dec); + return new_Field_time(mem_root, addr.ptr(), + addr.null_ptr(), addr.null_bit(), + unireg_check, field_name, dec); } case MYSQL_TYPE_TIME2: { uint dec= field_length > MIN_TIME_WIDTH ? field_length - MIN_TIME_WIDTH - 1: 0; return new (mem_root) - Field_timef(ptr, null_pos, null_bit, unireg_check, + Field_timef(addr.ptr(), addr.null_ptr(), addr.null_bit(), unireg_check, field_name, dec); } case MYSQL_TYPE_DATETIME: { uint dec= field_length > MAX_DATETIME_WIDTH ? field_length - MAX_DATETIME_WIDTH - 1: 0; - return new_Field_datetime(mem_root, ptr, null_pos, null_bit, unireg_check, - field_name, dec); + return new_Field_datetime(mem_root, addr.ptr(), + addr.null_ptr(), addr.null_bit(), + unireg_check, field_name, dec); } case MYSQL_TYPE_DATETIME2: { uint dec= field_length > MAX_DATETIME_WIDTH ? field_length - MAX_DATETIME_WIDTH - 1: 0; return new (mem_root) - Field_datetimef(ptr, null_pos, null_bit, unireg_check, - field_name, dec); + Field_datetimef(addr.ptr(), addr.null_ptr(), addr.null_bit(), + unireg_check, field_name, dec); } case MYSQL_TYPE_NULL: return new (mem_root) - Field_null(ptr, field_length, unireg_check, field_name, + Field_null(addr.ptr(), field_length, unireg_check, field_name, field_charset); case MYSQL_TYPE_BIT: + { + Bit_addr bit(rec->null()); + if (!f_bit_as_char(pack_flag) && f_maybe_null(pack_flag)) + bit.inc(); return (f_bit_as_char(pack_flag) ? new (mem_root) - Field_bit_as_char(ptr, field_length, null_pos, null_bit, + Field_bit_as_char(addr.ptr(), field_length, + addr.null_ptr(), addr.null_bit(), unireg_check, field_name) : new (mem_root) - Field_bit(ptr, field_length, null_pos, null_bit, bit_ptr, - bit_offset, unireg_check, field_name)); + Field_bit(addr.ptr(), field_length, + addr.null_ptr(), addr.null_bit(), + bit.ptr(), bit.offs(), unireg_check, field_name)); - default: // Impossible (Wrong version) + } + default: // Impossible (Wrong version) break; } return 0; diff --git a/sql/field.h b/sql/field.h index 7bd79630265..be6befb6904 100644 --- a/sql/field.h +++ b/sql/field.h @@ -4073,8 +4073,8 @@ public: extern const LEX_CSTRING null_clex_str; Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root, - uchar *ptr, uint32 field_length, - uchar *null_pos, uchar null_bit, + const Record_addr *rec, + uint32 field_length, uint pack_flag, const Type_handler *handler, CHARSET_INFO *cs, Field::geometry_type geom_type, uint srid, @@ -4313,11 +4313,10 @@ public: } Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root, - uchar *ptr, uchar *null_pos, uchar null_bit, + const Record_addr *addr, const LEX_CSTRING *field_name_arg) const { - return ::make_field(share, mem_root, ptr, - (uint32)length, null_pos, null_bit, + return ::make_field(share, mem_root, addr, (uint32) length, pack_flag, type_handler(), charset, geom_type, srid, unireg_check, interval, field_name_arg, flags); @@ -4325,8 +4324,8 @@ public: Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root, const LEX_CSTRING *field_name_arg) const { - return make_field(share, mem_root, (uchar *) 0, (uchar *) "", 0, - field_name_arg); + Record_addr addr(true); + return make_field(share, mem_root, &addr, field_name_arg); } /* Return true if default is an expression that must be saved explicitely */ bool has_default_expression(); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 9672180080e..f1df24ee110 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -17862,12 +17862,10 @@ bool Virtual_tmp_table::add(List &field_list) while ((cdef= it++)) { Field *tmp; - if (!(tmp= cdef->make_field(s, in_use->mem_root, 0, - (uchar*) (f_maybe_null(cdef->pack_flag) ? "" : 0), - f_maybe_null(cdef->pack_flag) ? 1 : 0, - &cdef->field_name))) + Record_addr addr(f_maybe_null(cdef->pack_flag)); + if (!(tmp= cdef->make_field(s, in_use->mem_root, &addr, &cdef->field_name))) DBUG_RETURN(true); - add(tmp); + add(tmp); } DBUG_RETURN(false); } diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 421ff0ed0f1..95dc931e435 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -2004,8 +2004,8 @@ Field *Type_handler_tiny::make_table_field(const LEX_CSTRING *name, TABLE *table) const { return new (table->in_use->mem_root) - Field_tiny(addr.ptr, attr.max_char_length(), - addr.null_ptr, addr.null_bit, + Field_tiny(addr.ptr(), attr.max_char_length(), + addr.null_ptr(), addr.null_bit(), Field::NONE, name, 0/*zerofill*/, attr.unsigned_flag); } @@ -2017,8 +2017,8 @@ Field *Type_handler_short::make_table_field(const LEX_CSTRING *name, { return new (table->in_use->mem_root) - Field_short(addr.ptr, attr.max_char_length(), - addr.null_ptr, addr.null_bit, + Field_short(addr.ptr(), attr.max_char_length(), + addr.null_ptr(), addr.null_bit(), Field::NONE, name, 0/*zerofill*/, attr.unsigned_flag); } @@ -2029,8 +2029,8 @@ Field *Type_handler_int24::make_table_field(const LEX_CSTRING *name, TABLE *table) const { return new (table->in_use->mem_root) - Field_medium(addr.ptr, attr.max_char_length(), - addr.null_ptr, addr.null_bit, + Field_medium(addr.ptr(), attr.max_char_length(), + addr.null_ptr(), addr.null_bit(), Field::NONE, name, 0/*zerofill*/, attr.unsigned_flag); } @@ -2042,8 +2042,8 @@ Field *Type_handler_long::make_table_field(const LEX_CSTRING *name, TABLE *table) const { return new (table->in_use->mem_root) - Field_long(addr.ptr, attr.max_char_length(), - addr.null_ptr, addr.null_bit, + Field_long(addr.ptr(), attr.max_char_length(), + addr.null_ptr(), addr.null_bit(), Field::NONE, name, 0/*zerofill*/, attr.unsigned_flag); } @@ -2054,8 +2054,8 @@ Field *Type_handler_longlong::make_table_field(const LEX_CSTRING *name, TABLE *table) const { return new (table->in_use->mem_root) - Field_longlong(addr.ptr, attr.max_char_length(), - addr.null_ptr, addr.null_bit, + Field_longlong(addr.ptr(), attr.max_char_length(), + addr.null_ptr(), addr.null_bit(), Field::NONE, name, 0/*zerofill*/, attr.unsigned_flag); } @@ -2067,8 +2067,8 @@ Field *Type_handler_vers_trx_id::make_table_field(const LEX_CSTRING *name, TABLE *table) const { return new (table->in_use->mem_root) - Field_vers_trx_id(addr.ptr, attr.max_char_length(), - addr.null_ptr, addr.null_bit, + Field_vers_trx_id(addr.ptr(), attr.max_char_length(), + addr.null_ptr(), addr.null_bit(), Field::NONE, name, 0/*zerofill*/, attr.unsigned_flag); } @@ -2080,8 +2080,8 @@ Field *Type_handler_float::make_table_field(const LEX_CSTRING *name, TABLE *table) const { return new (table->in_use->mem_root) - Field_float(addr.ptr, attr.max_char_length(), - addr.null_ptr, addr.null_bit, + Field_float(addr.ptr(), attr.max_char_length(), + addr.null_ptr(), addr.null_bit(), Field::NONE, name, (uint8) attr.decimals, 0/*zerofill*/, attr.unsigned_flag); } @@ -2093,8 +2093,8 @@ Field *Type_handler_double::make_table_field(const LEX_CSTRING *name, TABLE *table) const { return new (table->in_use->mem_root) - Field_double(addr.ptr, attr.max_char_length(), - addr.null_ptr, addr.null_bit, + Field_double(addr.ptr(), attr.max_char_length(), + addr.null_ptr(), addr.null_bit(), Field::NONE, name, (uint8) attr.decimals, 0/*zerofill*/, attr.unsigned_flag); } @@ -2115,7 +2115,8 @@ Type_handler_olddecimal::make_table_field(const LEX_CSTRING *name, */ DBUG_ASSERT(0); return new (table->in_use->mem_root) - Field_decimal(addr.ptr, attr.max_length, addr.null_ptr, addr.null_bit, + Field_decimal(addr.ptr(), attr.max_length, + addr.null_ptr(), addr.null_bit(), Field::NONE, name, (uint8) attr.decimals, 0/*zerofill*/,attr.unsigned_flag); } @@ -2162,7 +2163,7 @@ Type_handler_newdecimal::make_table_field(const LEX_CSTRING *name, len= required_length; } return new (table->in_use->mem_root) - Field_new_decimal(addr.ptr, len, addr.null_ptr, addr.null_bit, + Field_new_decimal(addr.ptr(), len, addr.null_ptr(), addr.null_bit(), Field::NONE, name, dec, 0/*zerofill*/, attr.unsigned_flag); } @@ -2174,7 +2175,8 @@ Field *Type_handler_year::make_table_field(const LEX_CSTRING *name, TABLE *table) const { return new (table->in_use->mem_root) - Field_year(addr.ptr, attr.max_length, addr.null_ptr, addr.null_bit, + Field_year(addr.ptr(), attr.max_length, + addr.null_ptr(), addr.null_bit(), Field::NONE, name); } @@ -2186,7 +2188,7 @@ Field *Type_handler_null::make_table_field(const LEX_CSTRING *name, { return new (table->in_use->mem_root) - Field_null(addr.ptr, attr.max_length, + Field_null(addr.ptr(), attr.max_length, Field::NONE, name, attr.collation.collation); } @@ -2198,7 +2200,7 @@ Field *Type_handler_timestamp::make_table_field(const LEX_CSTRING *name, { return new_Field_timestamp(table->in_use->mem_root, - addr.ptr, addr.null_ptr, addr.null_bit, + addr.ptr(), addr.null_ptr(), addr.null_bit(), Field::NONE, name, table->s, attr.decimals); } @@ -2214,7 +2216,7 @@ Field *Type_handler_timestamp2::make_table_field(const LEX_CSTRING *name, make_table_field() for make_field() purposes in field.cc. */ return new_Field_timestamp(table->in_use->mem_root, - addr.ptr, addr.null_ptr, addr.null_bit, + addr.ptr(), addr.null_ptr(), addr.null_bit(), Field::NONE, name, table->s, attr.decimals); } @@ -2226,7 +2228,7 @@ Field *Type_handler_newdate::make_table_field(const LEX_CSTRING *name, { return new (table->in_use->mem_root) - Field_newdate(addr.ptr, addr.null_ptr, addr.null_bit, + Field_newdate(addr.ptr(), addr.null_ptr(), addr.null_bit(), Field::NONE, name); } @@ -2243,7 +2245,7 @@ Field *Type_handler_date::make_table_field(const LEX_CSTRING *name, */ DBUG_ASSERT(0); return new (table->in_use->mem_root) - Field_date(addr.ptr, addr.null_ptr, addr.null_bit, + Field_date(addr.ptr(), addr.null_ptr(), addr.null_bit(), Field::NONE, name); } @@ -2255,7 +2257,7 @@ Field *Type_handler_time::make_table_field(const LEX_CSTRING *name, { return new_Field_time(table->in_use->mem_root, - addr.ptr, addr.null_ptr, addr.null_bit, + addr.ptr(), addr.null_ptr(), addr.null_bit(), Field::NONE, name, attr.decimals); } @@ -2272,7 +2274,7 @@ Field *Type_handler_time2::make_table_field(const LEX_CSTRING *name, make_table_field() for make_field() purposes in field.cc. */ return new_Field_time(table->in_use->mem_root, - addr.ptr, addr.null_ptr, addr.null_bit, + addr.ptr(), addr.null_ptr(), addr.null_bit(), Field::NONE, name, attr.decimals); } @@ -2284,7 +2286,7 @@ Field *Type_handler_datetime::make_table_field(const LEX_CSTRING *name, { return new_Field_datetime(table->in_use->mem_root, - addr.ptr, addr.null_ptr, addr.null_bit, + addr.ptr(), addr.null_ptr(), addr.null_bit(), Field::NONE, name, attr.decimals); } @@ -2299,7 +2301,7 @@ Field *Type_handler_datetime2::make_table_field(const LEX_CSTRING *name, make_table_field() for make_field() purposes in field.cc. */ return new_Field_datetime(table->in_use->mem_root, - addr.ptr, addr.null_ptr, addr.null_bit, + addr.ptr(), addr.null_ptr(), addr.null_bit(), Field::NONE, name, attr.decimals); } @@ -2311,8 +2313,8 @@ Field *Type_handler_bit::make_table_field(const LEX_CSTRING *name, { return new (table->in_use->mem_root) - Field_bit_as_char(addr.ptr, attr.max_length, - addr.null_ptr, addr.null_bit, + Field_bit_as_char(addr.ptr(), attr.max_length, + addr.null_ptr(), addr.null_bit(), Field::NONE, name); } @@ -2324,7 +2326,8 @@ Field *Type_handler_string::make_table_field(const LEX_CSTRING *name, { return new (table->in_use->mem_root) - Field_string(addr.ptr, attr.max_length, addr.null_ptr, addr.null_bit, + Field_string(addr.ptr(), attr.max_length, + addr.null_ptr(), addr.null_bit(), Field::NONE, name, attr.collation); } @@ -2336,9 +2339,9 @@ Field *Type_handler_varchar::make_table_field(const LEX_CSTRING *name, { return new (table->in_use->mem_root) - Field_varstring(addr.ptr, attr.max_length, + Field_varstring(addr.ptr(), attr.max_length, HA_VARCHAR_PACKLENGTH(attr.max_length), - addr.null_ptr, addr.null_bit, + addr.null_ptr(), addr.null_bit(), Field::NONE, name, table->s, attr.collation); } @@ -2351,7 +2354,7 @@ Field *Type_handler_tiny_blob::make_table_field(const LEX_CSTRING *name, { return new (table->in_use->mem_root) - Field_blob(addr.ptr, addr.null_ptr, addr.null_bit, + Field_blob(addr.ptr(), addr.null_ptr(), addr.null_bit(), Field::NONE, name, table->s, 1, attr.collation); } @@ -2364,7 +2367,7 @@ Field *Type_handler_blob::make_table_field(const LEX_CSTRING *name, { return new (table->in_use->mem_root) - Field_blob(addr.ptr, addr.null_ptr, addr.null_bit, + Field_blob(addr.ptr(), addr.null_ptr(), addr.null_bit(), Field::NONE, name, table->s, 2, attr.collation); } @@ -2378,7 +2381,7 @@ Type_handler_medium_blob::make_table_field(const LEX_CSTRING *name, { return new (table->in_use->mem_root) - Field_blob(addr.ptr, addr.null_ptr, addr.null_bit, + Field_blob(addr.ptr(), addr.null_ptr(), addr.null_bit(), Field::NONE, name, table->s, 3, attr.collation); } @@ -2391,7 +2394,7 @@ Field *Type_handler_long_blob::make_table_field(const LEX_CSTRING *name, { return new (table->in_use->mem_root) - Field_blob(addr.ptr, addr.null_ptr, addr.null_bit, + Field_blob(addr.ptr(), addr.null_ptr(), addr.null_bit(), Field::NONE, name, table->s, 4, attr.collation); } @@ -2405,7 +2408,7 @@ Field *Type_handler_geometry::make_table_field(const LEX_CSTRING *name, TABLE *table) const { return new (table->in_use->mem_root) - Field_geom(addr.ptr, addr.null_ptr, addr.null_bit, + Field_geom(addr.ptr(), addr.null_ptr(), addr.null_bit(), Field::NONE, name, table->s, 4, (Field::geometry_type) attr.uint_geometry_type(), 0); @@ -2421,7 +2424,8 @@ Field *Type_handler_enum::make_table_field(const LEX_CSTRING *name, TYPELIB *typelib= attr.get_typelib(); DBUG_ASSERT(typelib); return new (table->in_use->mem_root) - Field_enum(addr.ptr, attr.max_length, addr.null_ptr, addr.null_bit, + Field_enum(addr.ptr(), attr.max_length, + addr.null_ptr(), addr.null_bit(), Field::NONE, name, get_enum_pack_length(typelib->count), typelib, attr.collation); @@ -2437,7 +2441,8 @@ Field *Type_handler_set::make_table_field(const LEX_CSTRING *name, TYPELIB *typelib= attr.get_typelib(); DBUG_ASSERT(typelib); return new (table->in_use->mem_root) - Field_set(addr.ptr, attr.max_length, addr.null_ptr, addr.null_bit, + Field_set(addr.ptr(), attr.max_length, + addr.null_ptr(), addr.null_bit(), Field::NONE, name, get_enum_pack_length(typelib->count), typelib, attr.collation); diff --git a/sql/sql_type.h b/sql/sql_type.h index dd37e2ba96c..b02ea4b2824 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -886,28 +886,67 @@ public: }; +class Bit_addr +{ + /** + Byte where the bit is stored inside a record. + If the corresponding Field is a NOT NULL field, this member is NULL. + */ + uchar *m_ptr; + /** + Offset of the bit inside m_ptr[0], in the range 0..7. + */ + uchar m_offs; +public: + Bit_addr() + :m_ptr(NULL), + m_offs(0) + { } + Bit_addr(uchar *ptr, uchar offs) + :m_ptr(ptr), m_offs(offs) + { + DBUG_ASSERT(ptr || offs == 0); + DBUG_ASSERT(offs < 8); + } + Bit_addr(bool maybe_null) + :m_ptr(maybe_null ? (uchar *) "" : NULL), + m_offs(0) + { } + uchar *ptr() const { return m_ptr; } + uchar offs() const { return m_offs; } + uchar bit() const { return m_ptr ? ((uchar) 1) << m_offs : 0; } + void inc() + { + DBUG_ASSERT(m_ptr); + m_ptr+= (m_offs == 7); + m_offs= (m_offs + 1) & 7; + } +}; + + class Record_addr { + uchar *m_ptr; // Position of the field in the record + Bit_addr m_null; // Position and offset of the null bit public: - uchar *ptr; // Position to field in record - /** - Byte where the @c NULL bit is stored inside a record. If this Field is a - @c NOT @c NULL field, this member is @c NULL. - */ - uchar *null_ptr; - uchar null_bit; // Bit used to test null bit Record_addr(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg) - :ptr(ptr_arg), - null_ptr(null_ptr_arg), - null_bit(null_bit_arg) + :m_ptr(ptr_arg), + m_null(null_ptr_arg, null_bit_arg) + { } + Record_addr(uchar *ptr, const Bit_addr &null) + :m_ptr(ptr), + m_null(null) { } Record_addr(bool maybe_null) - :ptr(NULL), - null_ptr(maybe_null ? (uchar*) "" : 0), - null_bit(0) + :m_ptr(NULL), + m_null(maybe_null) { } + uchar *ptr() const { return m_ptr; } + const Bit_addr &null() const { return m_null; } + uchar *null_ptr() const { return m_null.ptr(); } + uchar null_bit() const { return m_null.bit(); } }; diff --git a/sql/table.cc b/sql/table.cc index cb3eb068e68..37f759a5325 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2039,12 +2039,13 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, name.length= strlen(name.str); if (!(handler= Type_handler::get_handler_by_real_type(field_type))) goto err; // Not supported field type + Record_addr addr(record + recpos, null_pos, null_bit_pos); *field_ptr= reg_field= - make_field(share, &share->mem_root, record+recpos, (uint32) field_length, - null_pos, null_bit_pos, pack_flag, handler, charset, - geom_type, srid, unireg_check, - (interval_nr ? share->intervals+interval_nr-1 : NULL), - &name, flags); + make_field(share, &share->mem_root, &addr, + (uint32) field_length, pack_flag, handler, charset, + geom_type, srid, unireg_check, + (interval_nr ? share->intervals + interval_nr - 1 : NULL), + &name, flags); if (!reg_field) // Not supported field type goto err; diff --git a/sql/unireg.cc b/sql/unireg.cc index 496a41e4544..dee856ae01f 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -1043,12 +1043,11 @@ static bool make_empty_rec(THD *thd, uchar *buff, uint table_options, thd->count_cuted_fields= CHECK_FIELD_WARN; // To find wrong default values while ((field=it++)) { + Record_addr addr(buff + field->offset + data_offset, + null_pos + null_count / 8, null_count & 7); /* regfield don't have to be deleted as it's allocated on THD::mem_root */ - Field *regfield= make_field(&share, thd->mem_root, - buff+field->offset + data_offset, - (uint32)field->length, - null_pos + null_count / 8, - null_count & 7, + Field *regfield= make_field(&share, thd->mem_root, &addr, + (uint32) field->length, field->pack_flag, field->type_handler(), field->charset,