Commit f82947e4 authored by Alexey Botchkov's avatar Alexey Botchkov

MDEV-17399 JSON_TABLE.

atch to get rid of duplicating code of the Create_tmp_table.
parent a5b454f9
#ifndef CREATE_TMP_TABLE_INCLUDED
#define CREATE_TMP_TABLE_INCLUDED
/* Copyright (c) 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
/*
Class for creating internal tempory tables in sql_select.cc
*/
class Create_tmp_table: public Data_type_statistics
{
protected:
// The following members are initialized only in start()
Field **m_from_field, **m_default_field;
KEY_PART_INFO *m_key_part_info;
uchar *m_group_buff, *m_bitmaps;
// The following members are initialized in ctor
uint m_alloced_field_count;
bool m_using_unique_constraint;
uint m_temp_pool_slot;
ORDER *m_group;
bool m_distinct;
bool m_save_sum_fields;
bool m_with_cycle;
ulonglong m_select_options;
ha_rows m_rows_limit;
uint m_group_null_items;
// counter for distinct/other fields
uint m_field_count[2];
// counter for distinct/other fields which can be NULL
uint m_null_count[2];
// counter for distinct/other blob fields
uint m_blobs_count[2];
// counter for "tails" of bit fields which do not fit in a byte
uint m_uneven_bit[2];
public:
enum counter {distinct, other};
/*
shows which field we are processing: distinct/other (set in processing
cycles)
*/
counter current_counter;
Create_tmp_table(ORDER *group, bool distinct, bool save_sum_fields,
ulonglong select_options, ha_rows rows_limit);
virtual ~Create_tmp_table() {}
virtual bool choose_engine(THD *thd, TABLE *table, TMP_TABLE_PARAM *param);
void add_field(TABLE *table, Field *field, uint fieldnr,
bool force_not_null_cols);
TABLE *start(THD *thd,
TMP_TABLE_PARAM *param,
const LEX_CSTRING *table_alias);
bool add_fields(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param, List<Item> &fields);
bool add_schema_fields(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param,
const ST_SCHEMA_TABLE &schema_table);
bool finalize(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
bool do_not_open, bool keep_row_order);
void cleanup_on_failure(THD *thd, TABLE *table);
};
#endif /* CREATE_TMP_TABLE_INCLUDED */
This diff is collapsed.
...@@ -4612,7 +4612,7 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd) ...@@ -4612,7 +4612,7 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd)
table->record[1]= table->record[0]+alloc_length; table->record[1]= table->record[0]+alloc_length;
share->default_values= table->record[1]+alloc_length; share->default_values= table->record[1]+alloc_length;
} }
setup_tmp_table_column_bitmaps(table, bitmaps); setup_tmp_table_column_bitmaps(table, bitmaps, table->s->fields);
recinfo= start_recinfo; recinfo= start_recinfo;
null_flags=(uchar*) table->record[0]; null_flags=(uchar*) table->record[0];
......
...@@ -4247,6 +4247,7 @@ void TMP_TABLE_PARAM::init() ...@@ -4247,6 +4247,7 @@ void TMP_TABLE_PARAM::init()
materialized_subquery= 0; materialized_subquery= 0;
force_not_null_cols= 0; force_not_null_cols= 0;
skip_create_table= 0; skip_create_table= 0;
tmp_name= "temptable"; // Name of temp table on disk
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
...@@ -6084,6 +6084,7 @@ class TMP_TABLE_PARAM :public Sql_alloc ...@@ -6084,6 +6084,7 @@ class TMP_TABLE_PARAM :public Sql_alloc
List<Item> copy_funcs; List<Item> copy_funcs;
Copy_field *copy_field, *copy_field_end; Copy_field *copy_field, *copy_field_end;
uchar *group_buff; uchar *group_buff;
const char *tmp_name;
Item **items_to_copy; /* Fields in tmp table */ Item **items_to_copy; /* Fields in tmp table */
TMP_ENGINE_COLUMNDEF *recinfo, *start_recinfo; TMP_ENGINE_COLUMNDEF *recinfo, *start_recinfo;
KEY *keyinfo; KEY *keyinfo;
...@@ -6157,7 +6158,9 @@ class TMP_TABLE_PARAM :public Sql_alloc ...@@ -6157,7 +6158,9 @@ class TMP_TABLE_PARAM :public Sql_alloc
schema_table(0), materialized_subquery(0), force_not_null_cols(0), schema_table(0), materialized_subquery(0), force_not_null_cols(0),
precomputed_group_by(0), precomputed_group_by(0),
force_copy_fields(0), bit_fields_as_long(0), skip_create_table(0) force_copy_fields(0), bit_fields_as_long(0), skip_create_table(0)
{} {
init();
}
~TMP_TABLE_PARAM() ~TMP_TABLE_PARAM()
{ {
cleanup(); cleanup();
...@@ -7723,9 +7726,8 @@ class THD_list: public THD_list_iterator ...@@ -7723,9 +7726,8 @@ class THD_list: public THD_list_iterator
extern THD_list server_threads; extern THD_list server_threads;
void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps); void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps,
void uint field_count);
setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps, uint field_count);
#endif /* MYSQL_SERVER */ #endif /* MYSQL_SERVER */
#endif /* SQL_CLASS_INCLUDED */ #endif /* SQL_CLASS_INCLUDED */
...@@ -67,6 +67,7 @@ ...@@ -67,6 +67,7 @@
#include "select_handler.h" #include "select_handler.h"
#include "my_json_writer.h" #include "my_json_writer.h"
#include "opt_trace.h" #include "opt_trace.h"
#include "create_tmp_table.h"
/* /*
A key part number that means we're using a fulltext scan. A key part number that means we're using a fulltext scan.
...@@ -18263,50 +18264,10 @@ setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps, uint field_count) ...@@ -18263,50 +18264,10 @@ setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps, uint field_count)
} }
void Create_tmp_table::Create_tmp_table(ORDER *group, bool distinct,
setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps) bool save_sum_fields,
{ ulonglong select_options,
setup_tmp_table_column_bitmaps(table, bitmaps, table->s->fields); ha_rows rows_limit)
}
class Create_tmp_table: public Data_type_statistics
{
// The following members are initialized only in start()
Field **m_from_field, **m_default_field;
KEY_PART_INFO *m_key_part_info;
uchar *m_group_buff, *m_bitmaps;
// The following members are initialized in ctor
uint m_alloced_field_count;
bool m_using_unique_constraint;
uint m_temp_pool_slot;
ORDER *m_group;
bool m_distinct;
bool m_save_sum_fields;
bool m_with_cycle;
ulonglong m_select_options;
ha_rows m_rows_limit;
uint m_group_null_items;
// counter for distinct/other fields
uint m_field_count[2];
// counter for distinct/other fields which can be NULL
uint m_null_count[2];
// counter for distinct/other blob fields
uint m_blobs_count[2];
// counter for "tails" of bit fields which do not fit in a byte
uint m_uneven_bit[2];
public:
enum counter {distinct, other};
/*
shows which field we are processing: distinct/other (set in processing
cycles)
*/
counter current_counter;
Create_tmp_table(const TMP_TABLE_PARAM *param,
ORDER *group, bool distinct, bool save_sum_fields,
ulonglong select_options, ha_rows rows_limit)
:m_alloced_field_count(0), :m_alloced_field_count(0),
m_using_unique_constraint(false), m_using_unique_constraint(false),
m_temp_pool_slot(MY_BIT_NONE), m_temp_pool_slot(MY_BIT_NONE),
...@@ -18318,39 +18279,23 @@ class Create_tmp_table: public Data_type_statistics ...@@ -18318,39 +18279,23 @@ class Create_tmp_table: public Data_type_statistics
m_rows_limit(rows_limit), m_rows_limit(rows_limit),
m_group_null_items(0), m_group_null_items(0),
current_counter(other) current_counter(other)
{ {
m_field_count[Create_tmp_table::distinct]= 0; m_field_count[Create_tmp_table::distinct]= 0;
m_field_count[Create_tmp_table::other]= 0; m_field_count[Create_tmp_table::other]= 0;
m_null_count[Create_tmp_table::distinct]= 0; m_null_count[Create_tmp_table::distinct]= 0;
m_null_count[Create_tmp_table::other]= 0; m_null_count[Create_tmp_table::other]= 0;
m_blobs_count[Create_tmp_table::distinct]= 0; m_blobs_count[Create_tmp_table::distinct]= 0;
m_blobs_count[Create_tmp_table::other]= 0; m_blobs_count[Create_tmp_table::other]= 0;
m_uneven_bit[Create_tmp_table::distinct]= 0; m_uneven_bit[Create_tmp_table::distinct]= 0;
m_uneven_bit[Create_tmp_table::other]= 0; m_uneven_bit[Create_tmp_table::other]= 0;
} }
void add_field(TABLE *table, Field *field, uint fieldnr, bool force_not_null_cols);
TABLE *start(THD *thd,
TMP_TABLE_PARAM *param,
const LEX_CSTRING *table_alias);
bool add_fields(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param, List<Item> &fields);
bool add_schema_fields(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param,
const ST_SCHEMA_TABLE &schema_table);
bool finalize(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
bool do_not_open, bool keep_row_order);
void cleanup_on_failure(THD *thd, TABLE *table);
};
void Create_tmp_table::add_field(TABLE *table, Field *field, uint fieldnr, bool force_not_null_cols) void Create_tmp_table::add_field(TABLE *table, Field *field, uint fieldnr,
bool force_not_null_cols)
{ {
DBUG_ASSERT(!field->field_name.str || strlen(field->field_name.str) == field->field_name.length); DBUG_ASSERT(!field->field_name.str ||
strlen(field->field_name.str) == field->field_name.length);
if (force_not_null_cols) if (force_not_null_cols)
{ {
...@@ -18436,13 +18381,13 @@ TABLE *Create_tmp_table::start(THD *thd, ...@@ -18436,13 +18381,13 @@ TABLE *Create_tmp_table::start(THD *thd,
m_temp_pool_slot = bitmap_lock_set_next(&temp_pool); m_temp_pool_slot = bitmap_lock_set_next(&temp_pool);
if (m_temp_pool_slot != MY_BIT_NONE) // we got a slot if (m_temp_pool_slot != MY_BIT_NONE) // we got a slot
sprintf(path, "%s-temptable-%lx-%i", tmp_file_prefix, sprintf(path, "%s-%s-%lx-%i", tmp_file_prefix, param->tmp_name,
current_pid, m_temp_pool_slot); current_pid, m_temp_pool_slot);
else else
{ {
/* if we run out of slots or we are not using tempool */ /* if we run out of slots or we are not using tempool */
sprintf(path, "%s-temptable-%lx-%llx-%x", tmp_file_prefix,current_pid, sprintf(path, "%s-%s-%lx-%llx-%x", tmp_file_prefix, param->tmp_name,
thd->thread_id, thd->tmp_table++); current_pid, thd->thread_id, thd->tmp_table++);
} }
/* /*
...@@ -18785,6 +18730,40 @@ bool Create_tmp_table::add_fields(THD *thd, ...@@ -18785,6 +18730,40 @@ bool Create_tmp_table::add_fields(THD *thd,
} }
bool Create_tmp_table::choose_engine(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param)
{
TABLE_SHARE *share= table->s;
DBUG_ENTER("Create_tmp_table::choose_engine");
/*
If result table is small; use a heap, otherwise TMP_TABLE_HTON (Aria)
In the future we should try making storage engine selection more dynamic
*/
if (share->blob_fields || m_using_unique_constraint ||
(thd->variables.big_tables &&
!(m_select_options & SELECT_SMALL_RESULT)) ||
(m_select_options & TMP_TABLE_FORCE_MYISAM) ||
thd->variables.tmp_memory_table_size == 0)
{
share->db_plugin= ha_lock_engine(0, TMP_ENGINE_HTON);
table->file= get_new_handler(share, &table->mem_root,
share->db_type());
if (m_group &&
(param->group_parts > table->file->max_key_parts() ||
param->group_length > table->file->max_key_length()))
m_using_unique_constraint= true;
}
else
{
share->db_plugin= ha_lock_engine(0, heap_hton);
table->file= get_new_handler(share, &table->mem_root,
share->db_type());
}
DBUG_RETURN(!table->file);
}
bool Create_tmp_table::finalize(THD *thd, bool Create_tmp_table::finalize(THD *thd,
TABLE *table, TABLE *table,
TMP_TABLE_PARAM *param, TMP_TABLE_PARAM *param,
...@@ -18811,28 +18790,7 @@ bool Create_tmp_table::finalize(THD *thd, ...@@ -18811,28 +18790,7 @@ bool Create_tmp_table::finalize(THD *thd,
DBUG_ASSERT(m_alloced_field_count >= share->fields); DBUG_ASSERT(m_alloced_field_count >= share->fields);
DBUG_ASSERT(m_alloced_field_count >= share->blob_fields); DBUG_ASSERT(m_alloced_field_count >= share->blob_fields);
/* If result table is small; use a heap */ if (choose_engine(thd, table, param))
/* future: storage engine selection can be made dynamic? */
if (share->blob_fields || m_using_unique_constraint
|| (thd->variables.big_tables && !(m_select_options & SELECT_SMALL_RESULT))
|| (m_select_options & TMP_TABLE_FORCE_MYISAM)
|| thd->variables.tmp_memory_table_size == 0)
{
share->db_plugin= ha_lock_engine(0, TMP_ENGINE_HTON);
table->file= get_new_handler(share, &table->mem_root,
share->db_type());
if (m_group &&
(param->group_parts > table->file->max_key_parts() ||
param->group_length > table->file->max_key_length()))
m_using_unique_constraint= true;
}
else
{
share->db_plugin= ha_lock_engine(0, heap_hton);
table->file= get_new_handler(share, &table->mem_root,
share->db_type());
}
if (!table->file)
goto err; goto err;
if (table->file->set_ha_share_ref(&share->ha_share)) if (table->file->set_ha_share_ref(&share->ha_share))
...@@ -18884,7 +18842,7 @@ bool Create_tmp_table::finalize(THD *thd, ...@@ -18884,7 +18842,7 @@ bool Create_tmp_table::finalize(THD *thd,
share->default_values= table->record[1]+alloc_length; share->default_values= table->record[1]+alloc_length;
} }
setup_tmp_table_column_bitmaps(table, m_bitmaps); setup_tmp_table_column_bitmaps(table, m_bitmaps, table->s->fields);
recinfo=param->start_recinfo; recinfo=param->start_recinfo;
null_flags=(uchar*) table->record[0]; null_flags=(uchar*) table->record[0];
...@@ -19339,8 +19297,8 @@ TABLE *create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields, ...@@ -19339,8 +19297,8 @@ TABLE *create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
bool keep_row_order) bool keep_row_order)
{ {
TABLE *table; TABLE *table;
Create_tmp_table maker(param, group, Create_tmp_table maker(group, distinct, save_sum_fields, select_options,
distinct, save_sum_fields, select_options, rows_limit); rows_limit);
if (!(table= maker.start(thd, param, table_alias)) || if (!(table= maker.start(thd, param, table_alias)) ||
maker.add_fields(thd, table, param, fields) || maker.add_fields(thd, table, param, fields) ||
maker.finalize(thd, table, param, do_not_open, keep_row_order)) maker.finalize(thd, table, param, do_not_open, keep_row_order))
...@@ -19359,7 +19317,7 @@ TABLE *create_tmp_table_for_schema(THD *thd, TMP_TABLE_PARAM *param, ...@@ -19359,7 +19317,7 @@ TABLE *create_tmp_table_for_schema(THD *thd, TMP_TABLE_PARAM *param,
bool do_not_open, bool keep_row_order) bool do_not_open, bool keep_row_order)
{ {
TABLE *table; TABLE *table;
Create_tmp_table maker(param, (ORDER *) NULL, false, false, Create_tmp_table maker((ORDER *) NULL, false, false,
select_options, HA_POS_ERROR); select_options, HA_POS_ERROR);
if (!(table= maker.start(thd, param, &table_alias)) || if (!(table= maker.start(thd, param, &table_alias)) ||
maker.add_schema_fields(thd, table, param, schema_table) || maker.add_schema_fields(thd, table, param, schema_table) ||
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment