Below is the list of changes that have just been committed into a local
5.0 repository of psergey. When psergey does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.1839 05/05/17 23:23:19 sergefp@stripped +7 -0
Do not assume that handler doesn't touch parts of row buffer
that are used by fields that are not covered by currently used index:
* Remove reliance on this assumption in QUICK_ROR_INTERSECT_SELECT
* Remove HA_EXTRA_KEYREAD_PRESERVE_FIELDS (constant and its handling in InnoDB) since
it is no longer needed.
sql/opt_range.h
1.55 05/05/17 23:21:17 sergefp@stripped +24 -7
Added comments
sql/opt_range.cc
1.158 05/05/17 23:21:17 sergefp@stripped +38 -4
Do not assume that handler doesn't touch parts of row buffer
that are used by fields that are not covered by currently used index:
In QUICK_ROR_INTERSECT_SELECT, introduce additional row buffer and manually 'combine' row buffers
that contain values for fields covered by different indexes.
The removes the need for HA_EXTRA_KEYREAD_PRESERVE_FIELDS.
sql/ha_ndbcluster.cc
1.178 05/05/17 23:21:17 sergefp@stripped +0 -4
Remove HA_EXTRA_KEYREAD_PRESERVE_FIELDS
sql/ha_innodb.cc
1.208 05/05/17 23:21:17 sergefp@stripped +0 -10
Remove support for extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS). opt_range code no longer uses this call.
innobase/row/row0sel.c
1.88 05/05/17 23:21:17 sergefp@stripped +2 -32
In row_sel_pop_cached_row_for_mysql, always do memcpy for entire record. mysqld no longer assumes that
handler doesn't touch unused parts of row buffer.
innobase/include/row0mysql.h
1.40 05/05/17 23:21:17 sergefp@stripped +0 -4
remove keep_other_fields_on_keyread from row_prebuilt_struct as it is no longer used.
include/my_base.h
1.70 05/05/17 23:21:17 sergefp@stripped +0 -6
Remove HA_EXTRA_KEYREAD_PRESERVE_FIELDS
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: sergefp
# Host: newbox.mylan
# Root: /home/psergey/mysql-5.0-ha_extra_preserve_fields
--- 1.69/include/my_base.h 2005-04-07 18:17:33 +00:00
+++ 1.70/include/my_base.h 2005-05-17 23:21:17 +00:00
@@ -147,12 +147,6 @@
*/
HA_EXTRA_CHANGE_KEY_TO_UNIQUE,
HA_EXTRA_CHANGE_KEY_TO_DUP,
- /*
- When using HA_EXTRA_KEYREAD, overwrite only key member fields and keep
- other fields intact. When this is off (by default) InnoDB will use memcpy
- to overwrite entire row.
- */
- HA_EXTRA_KEYREAD_PRESERVE_FIELDS
};
/* The following is parameter to ha_panic() */
--- 1.157/sql/opt_range.cc 2005-05-09 06:43:47 +00:00
+++ 1.158/sql/opt_range.cc 2005-05-17 23:21:17 +00:00
@@ -863,7 +863,8 @@
else
bzero(&alloc, sizeof(MEM_ROOT));
last_rowid= (byte*)alloc_root(parent_alloc? parent_alloc : &alloc,
- head->file->ref_length);
+ head->file->ref_length + head->s->reclength);
+ rowbuf= last_rowid + head->file->ref_length;
}
@@ -988,14 +989,11 @@
*/
if (quick->init_ror_merged_scan(TRUE))
DBUG_RETURN(1);
- quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
}
while((quick= quick_it++))
{
if (quick->init_ror_merged_scan(FALSE))
DBUG_RETURN(1);
- quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
- /* All merged scans share the same record buffer in intersection. */
quick->record= head->record[0];
}
@@ -5752,6 +5750,36 @@
/*
+ Copy fields covered by given index from table->record[0] to dst_buf row
+ buffer, preserving bytes/bits of dst buffer used by other fields.
+*/
+
+static void copy_key_fields(TABLE *table, uint index, char *dst_buf)
+{
+ KEY *key_info= table->key_info+index;
+ KEY_PART_INFO *key_part= key_info->key_part,
+ *end= key_part+key_info->key_parts;
+ const char *record= table->record[0];
+ uint field_offset;
+
+ for (; key_part != end; key_part++)
+ {
+ if (key_part->null_bit)
+ {
+ if (record[key_part->null_offset] & key_part->null_bit)
+ {
+ dst_buf[key_part->null_offset]|=key_part->null_bit;
+ continue;
+ }
+ dst_buf[key_part->null_offset]&= ~key_part->null_bit;
+ }
+ field_offset= key_part->field->offset();
+ memcpy(dst_buf + field_offset, record + field_offset, key_part->length);
+ }
+}
+
+
+/*
Retrieve next record.
SYNOPSIS
QUICK_ROR_INTERSECT_SELECT::get_next()
@@ -5795,6 +5823,8 @@
quick->file->position(quick->record);
memcpy(last_rowid, quick->file->ref, head->file->ref_length);
+ /* Save record buffer with key tuple. */
+ memcpy(rowbuf, quick->record, head->s->reclength);
last_rowid_count= 1;
while (last_rowid_count < quick_selects.elements)
@@ -5825,11 +5855,13 @@
}
}
memcpy(last_rowid, quick->file->ref, head->file->ref_length);
+ memcpy(rowbuf, quick->record, head->s->reclength);
last_rowid_count= 1;
}
else
{
/* current 'candidate' row confirmed by this select */
+ copy_key_fields(head, quick->index, rowbuf);
last_rowid_count++;
}
}
@@ -5837,6 +5869,8 @@
/* We get here iff we got the same row ref in all scans. */
if (need_to_fetch_row)
error= head->file->rnd_pos(head->record[0], last_rowid);
+ else
+ memcpy(head->record[0], rowbuf, head->s->reclength);
DBUG_RETURN(error);
}
--- 1.54/sql/opt_range.h 2005-05-09 09:26:47 +00:00
+++ 1.55/sql/opt_range.h 2005-05-17 23:21:17 +00:00
@@ -456,14 +456,29 @@
All merged QUICK_RANGE_SELECTs must return rowids in rowid order.
QUICK_ROR_INTERSECT_SELECT will return rows in rowid order, too.
- All merged quick selects retrieve {rowid, covered_fields} tuples (not full
- table records).
- QUICK_ROR_INTERSECT_SELECT retrieves full records if it is not being used
- by QUICK_ROR_INTERSECT_SELECT and all merged quick selects together don't
- cover needed all fields.
+ All merged quick selects are set to retrieve index tuple and clustered PK
+ fields only.
+ If one of the merged quick selects uses clustered PK, it used to filter
+ rowid sequences produced by other merged quick selects, and is not used
+ for row retrieval itself.
+
+ There are two modes of operation:
+ 1) need_to_fetch_row == TRUE
+ Each of merged quick selects uses its own handler object (created in
+ init_ror_merged_scan). The 'primary' handler object from table->file
+ is used to retrieve full table records with handler::rnd_pos().
+ 2) need_to_fetch_row == FALSE
+ One of merged quick selects uses the 'primary' instance of handler object,
+ while other quick selects create separate instances.
+ Since none of the used indexes covers all needed fields (but together they
+ do), the result record is assembled manually in rowbuf.
+ We need a separate buffer because the handler may overwrite contents of
+ the entire row buffer when performing a scan.
+
+ Mode #1 is used if this QUICK_ROR_INTERSECT_SELECT is not being used by
+ QUICK_ROR_INTERSECT_SELECT and all merged quick selects together don't cover
+ all needed fields.
- If one of the merged quick selects is a Clustered PK range scan, it is
- used only to filter rowid sequence produced by other merged quick selects.
*/
class QUICK_ROR_INTERSECT_SELECT : public QUICK_SELECT_I
@@ -504,6 +519,8 @@
MEM_ROOT alloc; /* Memory pool for this and merged quick selects data. */
THD *thd; /* current thread */
bool need_to_fetch_row; /* if true, do retrieve full table records. */
+ /* Additional row buffer. Used iff need_to_fetch_row==FALSE */
+ byte *rowbuf;
/* in top-level quick select, true if merged scans where initialized */
bool scans_inited;
};
--- 1.177/sql/ha_ndbcluster.cc 2005-05-09 19:13:23 +00:00
+++ 1.178/sql/ha_ndbcluster.cc 2005-05-17 23:21:17 +00:00
@@ -3021,10 +3021,6 @@
break;
case HA_EXTRA_CHANGE_KEY_TO_DUP:
DBUG_PRINT("info", ("HA_EXTRA_CHANGE_KEY_TO_DUP"));
- case HA_EXTRA_KEYREAD_PRESERVE_FIELDS:
- DBUG_PRINT("info", ("HA_EXTRA_KEYREAD_PRESERVE_FIELDS"));
- break;
-
}
DBUG_RETURN(0);
--- 1.39/innobase/include/row0mysql.h 2005-03-15 22:00:02 +00:00
+++ 1.40/innobase/include/row0mysql.h 2005-05-17 23:21:17 +00:00
@@ -614,10 +614,6 @@
allocated mem buf start, because
there is a 4 byte magic number at the
start and at the end */
- ibool keep_other_fields_on_keyread; /* when using fetch
- cache with HA_EXTRA_KEYREAD, don't
- overwrite other fields in mysql row
- row buffer.*/
ulint fetch_cache_first;/* position of the first not yet
fetched row in fetch_cache */
ulint n_fetch_cached; /* number of not yet fetched rows
--- 1.87/innobase/row/row0sel.c 2005-04-14 07:56:17 +00:00
+++ 1.88/innobase/row/row0sel.c 2005-05-17 23:21:17 +00:00
@@ -2845,40 +2845,10 @@
row */
row_prebuilt_t* prebuilt) /* in: prebuilt struct */
{
- ulint i;
- mysql_row_templ_t* templ;
- byte* cached_rec;
ut_ad(prebuilt->n_fetch_cached > 0);
- if (prebuilt->keep_other_fields_on_keyread)
- {
- /* Copy cache record field by field, don't touch fields that
- are not covered by current key */
- cached_rec =
- prebuilt->fetch_cache[prebuilt->fetch_cache_first];
-
- for (i = 0; i < prebuilt->n_template; i++) {
- templ = prebuilt->mysql_template + i;
- ut_memcpy(
- buf + templ->mysql_col_offset,
- cached_rec + templ->mysql_col_offset,
- templ->mysql_col_len);
- /* Copy NULL bit of the current field from cached_rec
- to buf */
- if (templ->mysql_null_bit_mask)
- {
- buf[templ->mysql_null_byte_offset] ^=
- (buf[templ->mysql_null_byte_offset] ^
- cached_rec[templ->mysql_null_byte_offset]) &
- (byte)templ->mysql_null_bit_mask;
- }
- }
- }
- else
- {
- ut_memcpy(buf, prebuilt->fetch_cache[prebuilt->fetch_cache_first],
- prebuilt->mysql_row_len);
- }
+ ut_memcpy(buf, prebuilt->fetch_cache[prebuilt->fetch_cache_first],
+ prebuilt->mysql_row_len);
prebuilt->n_fetch_cached--;
prebuilt->fetch_cache_first++;
--- 1.207/sql/ha_innodb.cc 2005-05-06 13:33:58 +00:00
+++ 1.208/sql/ha_innodb.cc 2005-05-17 23:21:17 +00:00
@@ -1121,8 +1121,6 @@
prebuilt->read_just_key = FALSE;
prebuilt->used_in_HANDLER = TRUE;
-
- prebuilt->keep_other_fields_on_keyread = FALSE;
}
/*************************************************************************
@@ -5725,11 +5723,9 @@
if (prebuilt->blob_heap) {
row_mysql_prebuilt_free_blob_heap(prebuilt);
}
- prebuilt->keep_other_fields_on_keyread = 0;
prebuilt->read_just_key = 0;
break;
case HA_EXTRA_RESET_STATE:
- prebuilt->keep_other_fields_on_keyread = 0;
prebuilt->read_just_key = 0;
break;
case HA_EXTRA_NO_KEYREAD:
@@ -5748,9 +5744,6 @@
case HA_EXTRA_KEYREAD:
prebuilt->read_just_key = 1;
break;
- case HA_EXTRA_KEYREAD_PRESERVE_FIELDS:
- prebuilt->keep_other_fields_on_keyread = 1;
- break;
default:/* Do nothing */
;
}
@@ -5799,7 +5792,6 @@
prebuilt->sql_stat_start = TRUE;
prebuilt->hint_need_to_fetch_extra_cols = 0;
prebuilt->read_just_key = 0;
- prebuilt->keep_other_fields_on_keyread = FALSE;
if (!prebuilt->mysql_has_locked) {
/* This handle is for a temporary table created inside
@@ -5904,7 +5896,6 @@
prebuilt->hint_need_to_fetch_extra_cols = 0;
prebuilt->read_just_key = 0;
- prebuilt->keep_other_fields_on_keyread = FALSE;
if (lock_type == F_WRLCK) {
@@ -6065,7 +6056,6 @@
prebuilt->hint_need_to_fetch_extra_cols = 0;
prebuilt->read_just_key = 0;
- prebuilt->keep_other_fields_on_keyread = FALSE;
if (lock_type == F_WRLCK) {
prebuilt->select_lock_type = LOCK_X;
| Thread |
|---|
| • bk commit into 5.0 tree (sergefp:1.1839) | Sergey Petrunia | 17 May |