summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <heikki@hundin.mysql.fi>2004-03-17 19:37:48 +0200
committerunknown <heikki@hundin.mysql.fi>2004-03-17 19:37:48 +0200
commit68273f0f84597c92a8b727f415564df87bcdb0a5 (patch)
treec5d75fedad7590ad42c86f32a245754a2a6e548e
parent8bdbfee96b876e48387cdc14d6b44a18d82a1043 (diff)
downloadmariadb-git-68273f0f84597c92a8b727f415564df87bcdb0a5.tar.gz
Many files:
Fix Bug #1942: do not retrieve all columns in a table if we only need the 'ref' of the row (usually, the PRIMARY KEY) to calculate an ORDER BY innobase/dict/dict0dict.c: Fix Bug #1942: do not retrieve all columns in a table if we only need the 'ref' of the row (usually, the PRIMARY KEY) to calculate an ORDER BY innobase/include/dict0dict.h: Fix Bug #1942: do not retrieve all columns in a table if we only need the 'ref' of the row (usually, the PRIMARY KEY) to calculate an ORDER BY innobase/include/row0mysql.h: Fix Bug #1942: do not retrieve all columns in a table if we only need the 'ref' of the row (usually, the PRIMARY KEY) to calculate an ORDER BY sql/ha_innodb.cc: Fix Bug #1942: do not retrieve all columns in a table if we only need the 'ref' of the row (usually, the PRIMARY KEY) to calculate an ORDER BY sql/sql_select.cc: Fix Bug #1942: do not retrieve all columns in a table if we only need the 'ref' of the row (usually, the PRIMARY KEY) to calculate an ORDER BY include/my_base.h: Fix Bug #1942: do not retrieve all columns in a table if we only need the 'ref' of the row (usually, the PRIMARY KEY) to calculate an ORDER BY
-rw-r--r--include/my_base.h8
-rw-r--r--innobase/dict/dict0dict.c40
-rw-r--r--innobase/include/dict0dict.h11
-rw-r--r--innobase/include/row0mysql.h21
-rw-r--r--sql/ha_innodb.cc42
-rw-r--r--sql/sql_select.cc2
6 files changed, 98 insertions, 26 deletions
diff --git a/include/my_base.h b/include/my_base.h
index e2b6d010d69..cfdab6a49ba 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -131,10 +131,14 @@ enum ha_extra_function {
HA_EXTRA_IGNORE_DUP_KEY, /* Dup keys don't rollback everything*/
HA_EXTRA_NO_IGNORE_DUP_KEY,
/*
- Instructs InnoDB to retrieve all columns, not just those where
- field->query_id is the same as the current query id
+ Instructs InnoDB to retrieve all columns (except in key read), not just
+ those where field->query_id is the same as the current query id
*/
HA_EXTRA_RETRIEVE_ALL_COLS,
+ /*
+ Instructs InnoDB to retrieve at least all the primary key columns
+ */
+ HA_EXTRA_RETRIEVE_PRIMARY_KEY,
HA_EXTRA_PREPARE_FOR_DELETE,
HA_EXTRA_PREPARE_FOR_UPDATE, /* Remove read cache if problems */
HA_EXTRA_PRELOAD_BUFFER_SIZE /* Set buffer size for preloading */
diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c
index 13ed5bd9af1..3085142e22e 100644
--- a/innobase/dict/dict0dict.c
+++ b/innobase/dict/dict0dict.c
@@ -631,7 +631,7 @@ dict_table_get_on_id(
}
/************************************************************************
-Looks for column n postion in the clustered index. */
+Looks for column n position in the clustered index. */
ulint
dict_table_get_nth_col_pos(
@@ -645,6 +645,44 @@ dict_table_get_nth_col_pos(
n));
}
+/************************************************************************
+Checks if a column is in the ordering columns of the clustered index of a
+table. Column prefixes are treated like whole columns. */
+
+ibool
+dict_table_col_in_clustered_key(
+/*============================*/
+ /* out: TRUE if the column, or its prefix, is
+ in the clustered key */
+ dict_table_t* table, /* in: table */
+ ulint n) /* in: column number */
+{
+ dict_index_t* index;
+ dict_field_t* field;
+ dict_col_t* col;
+ ulint pos;
+ ulint n_fields;
+
+ ut_ad(table);
+
+ col = dict_table_get_nth_col(table, n);
+
+ index = dict_table_get_first_index(table);
+
+ n_fields = dict_index_get_n_unique(index);
+
+ for (pos = 0; pos < n_fields; pos++) {
+ field = dict_index_get_nth_field(index, pos);
+
+ if (col == field->col) {
+
+ return(TRUE);
+ }
+ }
+
+ return(FALSE);
+}
+
/**************************************************************************
Inits the data dictionary module. */
diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h
index 534c9e380b8..688685cff8b 100644
--- a/innobase/include/dict0dict.h
+++ b/innobase/include/dict0dict.h
@@ -493,6 +493,17 @@ dict_table_get_sys_col_no(
/* out: column number */
dict_table_t* table, /* in: table */
ulint sys); /* in: DATA_ROW_ID, ... */
+/************************************************************************
+Checks if a column is in the ordering columns of the clustered index of a
+table. Column prefixes are treated like whole columns. */
+
+ibool
+dict_table_col_in_clustered_key(
+/*============================*/
+ /* out: TRUE if the column, or its prefix, is
+ in the clustered key */
+ dict_table_t* table, /* in: table */
+ ulint n); /* in: column number */
/***********************************************************************
Copies types of columns contained in table to tuple. */
diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h
index fade3709631..32a0c8b5d75 100644
--- a/innobase/include/row0mysql.h
+++ b/innobase/include/row0mysql.h
@@ -510,13 +510,15 @@ struct row_prebuilt_struct {
byte* ins_upd_rec_buff;/* buffer for storing data converted
to the Innobase format from the MySQL
format */
- ibool hint_no_need_to_fetch_extra_cols;
- /* normally this is TRUE, but
- MySQL will set this to FALSE
- if we might be required to fetch also
- other columns than mentioned in the
- query: the clustered index column(s),
- or an auto-increment column*/
+ ulint hint_need_to_fetch_extra_cols;
+ /* normally this is set to 0; if this
+ is set to ROW_RETRIEVE_PRIMARY_KEY,
+ then we should at least retrieve all
+ columns in the primary key; if this
+ is set to ROW_RETRIEVE_ALL_COLS, then
+ we must retrieve all columns in the
+ key (if read_just_key == 1), or all
+ columns in the table */
upd_node_t* upd_node; /* Innobase SQL update node used
to perform updates and deletes */
que_fork_t* ins_graph; /* Innobase SQL query graph used
@@ -572,6 +574,11 @@ struct row_prebuilt_struct {
#define ROW_MYSQL_DUMMY_TEMPLATE 3 /* dummy template used in
row_scan_and_check_index */
+/* Values for hint_need_to_fetch_extra_cols */
+#define ROW_RETRIEVE_PRIMARY_KEY 1
+#define ROW_RETRIEVE_ALL_COLS 2
+
+
#ifndef UNIV_NONINL
#include "row0mysql.ic"
#endif
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 078238fe78f..8e190904e05 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -702,7 +702,7 @@ ha_innobase::init_table_handle_for_HANDLER(void)
/* Always fetch all columns in the index record */
- prebuilt->hint_no_need_to_fetch_extra_cols = FALSE;
+ prebuilt->hint_need_to_fetch_extra_cols = ROW_RETRIEVE_ALL_COLS;
/* We want always to fetch all columns in the whole row? Or do
we???? */
@@ -1951,6 +1951,7 @@ build_template(
ulint n_fields;
ulint n_requested_fields = 0;
ibool fetch_all_in_key = FALSE;
+ ibool fetch_primary_key_cols = FALSE;
ulint i;
if (prebuilt->select_lock_type == LOCK_X) {
@@ -1961,8 +1962,9 @@ build_template(
templ_type = ROW_MYSQL_WHOLE_ROW;
}
- if (templ_type == ROW_MYSQL_REC_FIELDS
- && !prebuilt->hint_no_need_to_fetch_extra_cols) {
+ if (templ_type == ROW_MYSQL_REC_FIELDS) {
+ if (prebuilt->hint_need_to_fetch_extra_cols
+ == ROW_RETRIEVE_ALL_COLS) {
/* We know we must at least fetch all columns in the key, or
all columns in the table */
@@ -1977,15 +1979,14 @@ build_template(
fetch_all_in_key = TRUE;
} else {
- /* We are building a temporary table: fetch all
- columns; the reason is that MySQL may use the
- clustered index key to store rows, but the mechanism
- we use below to detect required columns does not
- reveal that. Actually, it might be enough to
- fetch only all in the key also in this case! */
-
templ_type = ROW_MYSQL_WHOLE_ROW;
}
+ } else if (prebuilt->hint_need_to_fetch_extra_cols
+ == ROW_RETRIEVE_PRIMARY_KEY) {
+ /* We must at least fetch all primary key cols */
+
+ fetch_primary_key_cols = TRUE;
+ }
}
clust_index = dict_table_get_first_index_noninline(prebuilt->table);
@@ -2004,7 +2005,7 @@ build_template(
the clustered index */
}
- n_fields = (ulint)table->fields;
+ n_fields = (ulint)table->fields; /* number of columns */
if (!prebuilt->mysql_template) {
prebuilt->mysql_template = (mysql_row_templ_t*)
@@ -2017,6 +2018,8 @@ build_template(
prebuilt->templ_contains_blob = FALSE;
+ /* Note that in InnoDB, i is the column number. MySQL calls columns
+ 'fields'. */
for (i = 0; i < n_fields; i++) {
templ = prebuilt->mysql_template + n_requested_fields;
field = table->field[i];
@@ -2029,6 +2032,8 @@ build_template(
if (templ_type == ROW_MYSQL_REC_FIELDS
&& !(fetch_all_in_key
&& dict_index_contains_col_or_prefix(index, i))
+ && !(fetch_primary_key_cols
+ && dict_table_col_in_clustered_key(index->table, i))
&& thd->query_id != field->query_id) {
/* This field is not needed in the query, skip it */
@@ -4514,7 +4519,14 @@ ha_innobase::extra(
prebuilt->read_just_key = 0;
break;
case HA_EXTRA_RETRIEVE_ALL_COLS:
- prebuilt->hint_no_need_to_fetch_extra_cols = FALSE;
+ prebuilt->hint_need_to_fetch_extra_cols
+ = ROW_RETRIEVE_ALL_COLS;
+ break;
+ case HA_EXTRA_RETRIEVE_PRIMARY_KEY:
+ if (prebuilt->hint_need_to_fetch_extra_cols == 0) {
+ prebuilt->hint_need_to_fetch_extra_cols
+ = ROW_RETRIEVE_PRIMARY_KEY;
+ }
break;
case HA_EXTRA_KEYREAD:
prebuilt->read_just_key = 1;
@@ -4575,7 +4587,7 @@ ha_innobase::start_stmt(
auto_inc_counter_for_this_stat = 0;
prebuilt->sql_stat_start = TRUE;
- prebuilt->hint_no_need_to_fetch_extra_cols = TRUE;
+ prebuilt->hint_need_to_fetch_extra_cols = 0;
prebuilt->read_just_key = 0;
if (!prebuilt->mysql_has_locked) {
@@ -4652,7 +4664,7 @@ ha_innobase::external_lock(
trx = prebuilt->trx;
prebuilt->sql_stat_start = TRUE;
- prebuilt->hint_no_need_to_fetch_extra_cols = TRUE;
+ prebuilt->hint_need_to_fetch_extra_cols = 0;
prebuilt->read_just_key = 0;
@@ -4996,7 +5008,7 @@ ha_innobase::innobase_read_and_init_auto_inc(
/* Play safe and also give in another way the hint to fetch
all columns in the key: */
- prebuilt->hint_no_need_to_fetch_extra_cols = FALSE;
+ prebuilt->hint_need_to_fetch_extra_cols = ROW_RETRIEVE_ALL_COLS;
prebuilt->trx->mysql_n_tables_locked += 1;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 13efad05eb9..09017c7b9ce 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -845,7 +845,7 @@ JOIN::optimize()
for (uint i_h = const_tables; i_h < tables; i_h++)
{
TABLE* table_h = join_tab[i_h].table;
- table_h->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
+ table_h->file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY);
}
}
#endif