diff options
author | Igor Babaev <igor@askmonty.org> | 2016-02-09 12:35:59 -0800 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2016-02-09 12:35:59 -0800 |
commit | 2cfc450bf78c2d951729d1a0e8f731c0d987b1d5 (patch) | |
tree | 6c15f411927c9da723265d5f9891592390e97cea /sql/filesort.cc | |
parent | 7b50447aa6d051b8d14bb01ef14802cb8ffee223 (diff) | |
download | mariadb-git-bb-10.2-mdev8646.tar.gz |
This is the consolidated patch for mdev-8646:bb-10.2-mdev8646
"Re-factor the code for post-join operations".
The patch mainly contains the code ported from mysql-5.6 and
created for two essential architectural changes:
1. WL#5558: Resolve ORDER BY execution method at the optimization stage
2. WL#6071: Inline tmp tables into the nested loops algorithm
The first task was implemented for mysql-5.6 by Ole John Aske.
It allows to make all decisions on ORDER BY operation at the optimization
stage.
The second task implemented for mysql-5.6 by Evgeny Potemkin adds JOIN_TAB
nodes for post-join operations that require temporary tables. It allows
to execute these operations within the nested loops algorithm that used to
be used before this task only for join queries. Besides these task moves
all planning on the execution of these operations from the execution phase
to the optimization phase.
Some other re-factoring changes of mysql-5.6 were pulled in, mainly because
it was easier to pull them in than roll them back. In particular all
changes concerning Ref_ptr_array were incorporated.
The port required some changes in the MariaDB code that concerned the
functionality of EXPLAIN and ANALYZE. This was done mainly by Sergey
Petrunia.
Diffstat (limited to 'sql/filesort.cc')
-rw-r--r-- | sql/filesort.cc | 82 |
1 files changed, 68 insertions, 14 deletions
diff --git a/sql/filesort.cc b/sql/filesort.cc index 9289d712cbc..4a1f509a54d 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -120,15 +120,16 @@ void Sort_param::init_for_filesort(uint sortlen, TABLE *table, @param thd Current thread @param table Table to sort - @param sortorder How to sort the table - @param s_length Number of elements in sortorder - @param select Condition to apply to the rows - @param max_rows Return only this many rows + @param filesort How to sort the table @param sort_positions Set to TRUE if we want to force sorting by position (Needed by UPDATE/INSERT or ALTER TABLE or when rowids are required by executor) @param[out] examined_rows Store number of examined rows here - @param[out] found_rows Store the number of found rows here + This is the number of found rows before + applying WHERE condition. + @param[out] found_rows Store the number of found rows here. + This is the number of found rows after + applying WHERE condition. @note If we sort by position (like if sort_positions is 1) filesort() will @@ -140,12 +141,9 @@ void Sort_param::init_for_filesort(uint sortlen, TABLE *table, \# Number of rows */ -ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, - SQL_SELECT *select, ha_rows max_rows, - bool sort_positions, - ha_rows *examined_rows, - ha_rows *found_rows, - Filesort_tracker* tracker) +ha_rows filesort(THD *thd, TABLE *table, Filesort *filesort, + bool sort_positions, ha_rows *examined_rows, + ha_rows *found_rows, Filesort_tracker* tracker) { int error; size_t memory_available= thd->variables.sortbuff_size; @@ -156,9 +154,16 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, Sort_param param; bool multi_byte_charset; Bounded_queue<uchar, uchar> pq; + SQL_SELECT *const select= filesort->select; + ha_rows max_rows= filesort->limit; + uint s_length= 0; DBUG_ENTER("filesort"); - DBUG_EXECUTE("info",TEST_filesort(sortorder,s_length);); + + if (!(s_length= filesort->make_sortorder(thd))) + DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */ + + DBUG_EXECUTE("info",TEST_filesort(filesort->sortorder,s_length);); #ifdef SKIP_DBUG_IN_FILESORT DBUG_PUSH(""); /* No DBUG here */ #endif @@ -190,7 +195,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, error= 1; *found_rows= HA_POS_ERROR; - param.init_for_filesort(sortlength(thd, sortorder, s_length, + param.init_for_filesort(sortlength(thd, filesort->sortorder, s_length, &multi_byte_charset), table, thd->variables.max_length_for_sort_data, @@ -292,7 +297,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, goto err; param.sort_form= table; - param.end=(param.local_sortorder=sortorder)+s_length; + param.end=(param.local_sortorder=filesort->sortorder)+s_length; num_rows= find_all_keys(thd, ¶m, select, &table_sort, &buffpek_pointers, @@ -470,6 +475,55 @@ void filesort_free_buffers(TABLE *table, bool full) } +void Filesort::cleanup() +{ + if (select && own_select) + { + select->cleanup(); + select= NULL; + } +} + + +uint Filesort::make_sortorder(THD *thd) +{ + uint count; + SORT_FIELD *sort,*pos; + ORDER *ord; + DBUG_ENTER("make_sortorder"); + + + count=0; + for (ord = order; ord; ord= ord->next) + count++; + if (!sortorder) + sortorder= (SORT_FIELD*) thd->alloc(sizeof(SORT_FIELD) * (count + 1)); + pos= sort= sortorder; + + if (!pos) + DBUG_RETURN(0); + + for (ord= order; ord; ord= ord->next, pos++) + { + Item *item= ord->item[0]->real_item(); + pos->field= 0; pos->item= 0; + if (item->type() == Item::FIELD_ITEM) + pos->field= ((Item_field*) item)->field; + else if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item()) + pos->field= ((Item_sum*) item)->get_tmp_table_field(); + else if (item->type() == Item::COPY_STR_ITEM) + { // Blob patch + pos->item= ((Item_copy*) item)->get_item(); + } + else + pos->item= *ord->item; + pos->reverse= (ord->direction == ORDER::ORDER_DESC); + DBUG_ASSERT(pos->field != NULL || pos->item != NULL); + } + DBUG_RETURN(count); +} + + /** Read 'count' number of buffer pointers into memory. */ static uchar *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count, |