summaryrefslogtreecommitdiff
path: root/sql/sql_select.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r--sql/sql_select.cc109
1 files changed, 71 insertions, 38 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 737f568fd62..2d80767a141 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
/**
@file
@@ -8606,6 +8606,7 @@ JOIN::make_simple_join(JOIN *parent, TABLE *temp_table)
join_tab->ref.key = -1;
join_tab->read_first_record= join_init_read_record;
join_tab->join= this;
+ join_tab->ref.key_parts= 0;
bzero((char*) &join_tab->read_record,sizeof(join_tab->read_record));
temp_table->status=0;
temp_table->null_row=0;
@@ -9931,7 +9932,7 @@ end_sj_materialize(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
if (table->file->is_fatal_error(error, HA_CHECK_DUP) &&
create_internal_tmp_table_from_heap(thd, table,
sjm->sjm_table_param.start_recinfo,
- &sjm->sjm_table_param.recinfo, error, 1))
+ &sjm->sjm_table_param.recinfo, error, 1, NULL))
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
}
}
@@ -10501,10 +10502,7 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
join_read_system :join_read_const;
if (table->covering_keys.is_set(tab->ref.key) &&
!table->no_keyread)
- {
- table->key_read=1;
- table->file->extra(HA_EXTRA_KEYREAD);
- }
+ table->enable_keyread();
else if ((!jcl || jcl > 4) && !tab->ref.is_access_triggered())
push_index_cond(tab, tab->ref.key);
break;
@@ -10513,10 +10511,7 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
/* fall through */
if (table->covering_keys.is_set(tab->ref.key) &&
!table->no_keyread)
- {
- table->key_read=1;
- table->file->extra(HA_EXTRA_KEYREAD);
- }
+ table->enable_keyread();
else if ((!jcl || jcl > 4) && !tab->ref.is_access_triggered())
push_index_cond(tab, tab->ref.key);
break;
@@ -11121,11 +11116,27 @@ void JOIN::cleanup(bool full)
else
clean_pre_sort_join_tab();
}
+ /*
+ Call cleanup() on join tabs used by the join optimization
+ (join->join_tab may now be pointing to result of make_simple_join
+ reading from the temporary table)
- for (tab= first_linear_tab(this, WITH_CONST_TABLES); tab;
- tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS))
+ We also need to check table_count to handle various degenerate joins
+ w/o tables: they don't have some members initialized and
+ WALK_OPTIMIZATION_TABS may not work correctly for them.
+ */
+ enum enum_exec_or_opt tabs_kind;
+ if (first_breadth_first_tab(this, WALK_OPTIMIZATION_TABS))
+ tabs_kind= WALK_OPTIMIZATION_TABS;
+ else
+ tabs_kind= WALK_EXECUTION_TABS;
+ if (table_count)
{
- tab->cleanup();
+ for (tab= first_breadth_first_tab(this, tabs_kind); tab;
+ tab= next_breadth_first_tab(this, tabs_kind, tab))
+ {
+ tab->cleanup();
+ }
}
cleaned= true;
}
@@ -11136,8 +11147,10 @@ void JOIN::cleanup(bool full)
{
if (tab->table)
{
- DBUG_PRINT("info", ("close index: %s.%s", tab->table->s->db.str,
- tab->table->s->table_name.str));
+ DBUG_PRINT("info", ("close index: %s.%s alias: %s",
+ tab->table->s->db.str,
+ tab->table->s->table_name.str,
+ tab->table->alias.c_ptr()));
tab->table->file->ha_index_or_rnd_end();
}
}
@@ -14488,7 +14501,7 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
if (new_field)
new_field->init(table);
- if (copy_func && item->is_result_field())
+ if (copy_func && item->real_item()->is_result_field())
*((*copy_func)++) = item; // Save for copy_funcs
if (modify_item)
item->set_result_field(new_field);
@@ -15597,8 +15610,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
if (share->db_type() == TMP_ENGINE_HTON)
{
if (create_internal_tmp_table(table, param->keyinfo, param->start_recinfo,
- &param->recinfo, select_options,
- thd->variables.big_tables))
+ &param->recinfo, select_options))
goto err;
}
if (open_tmp_table(table))
@@ -15816,7 +15828,7 @@ bool open_tmp_table(TABLE *table)
bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
TMP_ENGINE_COLUMNDEF *start_recinfo,
TMP_ENGINE_COLUMNDEF **recinfo,
- ulonglong options, my_bool big_tables)
+ ulonglong options)
{
int error;
MARIA_KEYDEF keydef;
@@ -15909,7 +15921,8 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
}
bzero((char*) &create_info,sizeof(create_info));
- if (big_tables && !(options & SELECT_SMALL_RESULT))
+ /* Use long data format, to ensure we never get a 'table is full' error */
+ if (!(options & SELECT_SMALL_RESULT))
create_info.data_file_length= ~(ulonglong) 0;
/*
@@ -15985,7 +15998,7 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
TMP_ENGINE_COLUMNDEF *start_recinfo,
TMP_ENGINE_COLUMNDEF **recinfo,
- ulonglong options, my_bool big_tables)
+ ulonglong options)
{
int error;
MI_KEYDEF keydef;
@@ -16072,7 +16085,7 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
MI_CREATE_INFO create_info;
bzero((char*) &create_info,sizeof(create_info));
- if (big_tables && !(options & SELECT_SMALL_RESULT))
+ if (!(options & SELECT_SMALL_RESULT))
create_info.data_file_length= ~(ulonglong) 0;
if ((error=mi_create(share->table_name.str, share->keys, &keydef,
@@ -16095,7 +16108,6 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
DBUG_RETURN(1);
}
-
#endif /* USE_ARIA_FOR_TMP_TABLES */
@@ -16110,7 +16122,8 @@ create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
TMP_ENGINE_COLUMNDEF *start_recinfo,
TMP_ENGINE_COLUMNDEF **recinfo,
int error,
- bool ignore_last_dupp_key_error)
+ bool ignore_last_dupp_key_error,
+ bool *is_duplicate)
{
TABLE new_table;
TABLE_SHARE share;
@@ -16143,8 +16156,7 @@ create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
if (create_internal_tmp_table(&new_table, table->key_info, start_recinfo,
recinfo,
thd->lex->select_lex.options |
- thd->variables.option_bits,
- thd->variables.big_tables))
+ thd->variables.option_bits))
goto err2;
if (open_tmp_table(&new_table))
goto err1;
@@ -16188,6 +16200,13 @@ create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
!ignore_last_dupp_key_error)
goto err;
+ if (is_duplicate)
+ *is_duplicate= TRUE;
+ }
+ else
+ {
+ if (is_duplicate)
+ *is_duplicate= FALSE;
}
/* remove heap table and change to use myisam table */
@@ -16772,7 +16791,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
if (rc != NESTED_LOOP_NO_MORE_ROWS)
{
error= (*join_tab->read_first_record)(join_tab);
- if (join_tab->keep_current_rowid)
+ if (!error && join_tab->keep_current_rowid)
join_tab->table->file->position(join_tab->table->record[0]);
rc= evaluate_join_record(join, join_tab, error);
}
@@ -17689,6 +17708,8 @@ join_read_first(JOIN_TAB *tab)
{
int error= 0;
TABLE *table=tab->table;
+ DBUG_ENTER("join_read_first");
+
if (table->covering_keys.is_set(tab->index) && !table->no_keyread &&
!table->key_read)
table->enable_keyread();
@@ -17705,9 +17726,9 @@ join_read_first(JOIN_TAB *tab)
{
if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
report_error(table, error);
- return -1;
+ DBUG_RETURN(-1);
}
- return 0;
+ DBUG_RETURN(0);
}
@@ -17727,6 +17748,8 @@ join_read_last(JOIN_TAB *tab)
{
TABLE *table=tab->table;
int error= 0;
+ DBUG_ENTER("join_read_first");
+
if (table->covering_keys.is_set(tab->index) && !table->no_keyread &&
!table->key_read)
table->enable_keyread();
@@ -17740,9 +17763,9 @@ join_read_last(JOIN_TAB *tab)
if (!error)
error= table->file->prepare_index_scan();
if (error || (error= tab->table->file->ha_index_last(tab->table->record[0])))
- return report_error(table, error);
+ DBUG_RETURN(report_error(table, error));
- return 0;
+ DBUG_RETURN(0);
}
@@ -17856,7 +17879,13 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (!end_of_records)
{
if (join->table_count &&
- join->join_tab->is_using_loose_index_scan())
+ (join->join_tab->is_using_loose_index_scan() ||
+ /*
+ When order by used a loose scan as its input, the quick select may
+ be attached to pre_sort_join_tab.
+ */
+ (join->pre_sort_join_tab &&
+ join->pre_sort_join_tab->is_using_loose_index_scan())))
{
/* Copy non-aggregated fields when loose index scan is used. */
copy_fields(&join->tmp_table_param);
@@ -18097,11 +18126,14 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{
if (!table->file->is_fatal_error(error, HA_CHECK_DUP))
goto end;
+ bool is_duplicate;
if (create_internal_tmp_table_from_heap(join->thd, table,
join->tmp_table_param.start_recinfo,
&join->tmp_table_param.recinfo,
- error,1))
+ error, 1, &is_duplicate))
DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error
+ if (is_duplicate)
+ goto end;
table->s->uniques=0; // To ensure rows are the same
}
if (++join->send_records >= join->tmp_table_param.end_write_records &&
@@ -18186,7 +18218,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (create_internal_tmp_table_from_heap(join->thd, table,
join->tmp_table_param.start_recinfo,
&join->tmp_table_param.recinfo,
- error, 0))
+ error, 0, NULL))
DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error
/* Change method to update rows */
if ((error= table->file->ha_index_init(0, 0)))
@@ -18291,7 +18323,7 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
create_internal_tmp_table_from_heap(join->thd, table,
join->tmp_table_param.start_recinfo,
&join->tmp_table_param.recinfo,
- error, 0))
+ error, 0, NULL))
DBUG_RETURN(NESTED_LOOP_ERROR);
}
if (join->rollup.state != ROLLUP::STATE_NONE)
@@ -19697,6 +19729,9 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
MY_THREAD_SPECIFIC));
table->status=0; // May be wrong if quick_select
+ if (!tab->preread_init_done && tab->preread_init())
+ goto err;
+
// If table has a range, move it to select
if (select && !select->quick && tab->ref.key >= 0)
{
@@ -19733,8 +19768,6 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
get_schema_tables_result(join, PROCESSED_BY_CREATE_SORT_INDEX))
goto err;
- if (!tab->preread_init_done && tab->preread_init())
- goto err;
if (table->s->tmp_table)
table->file->info(HA_STATUS_VARIABLE); // Get record count
filesort_retval= filesort(thd, table, join->sortorder, length,
@@ -22046,7 +22079,7 @@ int JOIN::rollup_write_data(uint idx, TABLE *table_arg)
if (create_internal_tmp_table_from_heap(thd, table_arg,
tmp_table_param.start_recinfo,
&tmp_table_param.recinfo,
- write_error, 0))
+ write_error, 0, NULL))
return 1;
}
}