mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merge 5.0.80 release and 5.0 community. Version left at 5.0.80.
This commit is contained in:
@ -78,7 +78,6 @@ static store_key *get_store_key(THD *thd,
|
||||
KEYUSE *keyuse, table_map used_tables,
|
||||
KEY_PART_INFO *key_part, char *key_buff,
|
||||
uint maybe_null);
|
||||
static bool make_simple_join(JOIN *join,TABLE *tmp_table);
|
||||
static void make_outerjoin_info(JOIN *join);
|
||||
static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *item);
|
||||
static void make_join_readinfo(JOIN *join, ulonglong options);
|
||||
@ -100,7 +99,7 @@ static COND* substitute_for_best_equal_field(COND *cond,
|
||||
void *table_join_idx);
|
||||
static COND *simplify_joins(JOIN *join, List<TABLE_LIST> *join_list,
|
||||
COND *conds, bool top);
|
||||
static bool check_interleaving_with_nj(JOIN_TAB *last, JOIN_TAB *next);
|
||||
static bool check_interleaving_with_nj(JOIN_TAB *next);
|
||||
static void restore_prev_nj_state(JOIN_TAB *last);
|
||||
static void reset_nj_counters(List<TABLE_LIST> *join_list);
|
||||
static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
|
||||
@ -1619,8 +1618,13 @@ JOIN::exec()
|
||||
We have to test for 'conds' here as the WHERE may not be constant
|
||||
even if we don't have any tables for prepared statements or if
|
||||
conds uses something like 'rand()'.
|
||||
If the HAVING clause is either impossible or always true, then
|
||||
JOIN::having is set to NULL by optimize_cond.
|
||||
In this case JOIN::exec must check for JOIN::having_value, in the
|
||||
same way it checks for JOIN::cond_value.
|
||||
*/
|
||||
if (cond_value != Item::COND_FALSE &&
|
||||
having_value != Item::COND_FALSE &&
|
||||
(!conds || conds->val_int()) &&
|
||||
(!having || having->val_int()))
|
||||
{
|
||||
@ -1815,7 +1819,7 @@ JOIN::exec()
|
||||
|
||||
/* Free first data from old join */
|
||||
curr_join->join_free();
|
||||
if (make_simple_join(curr_join, curr_tmp_table))
|
||||
if (curr_join->make_simple_join(this, curr_tmp_table))
|
||||
DBUG_VOID_RETURN;
|
||||
calc_group_buffer(curr_join, group_list);
|
||||
count_field_types(select_lex, &curr_join->tmp_table_param,
|
||||
@ -1935,7 +1939,7 @@ JOIN::exec()
|
||||
curr_join->select_distinct=0;
|
||||
}
|
||||
curr_tmp_table->reginfo.lock_type= TL_UNLOCK;
|
||||
if (make_simple_join(curr_join, curr_tmp_table))
|
||||
if (curr_join->make_simple_join(this, curr_tmp_table))
|
||||
DBUG_VOID_RETURN;
|
||||
calc_group_buffer(curr_join, curr_join->group_list);
|
||||
count_field_types(select_lex, &curr_join->tmp_table_param,
|
||||
@ -2381,11 +2385,12 @@ typedef struct st_sargable_param
|
||||
*/
|
||||
|
||||
static bool
|
||||
make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
||||
make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
|
||||
DYNAMIC_ARRAY *keyuse_array)
|
||||
{
|
||||
int error;
|
||||
TABLE *table;
|
||||
TABLE_LIST *tables= tables_arg;
|
||||
uint i,table_count,const_count,key;
|
||||
table_map found_const_table_map, all_table_map, found_ref, refs;
|
||||
key_map const_ref, eq_part;
|
||||
@ -2423,10 +2428,10 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
||||
table_vector[i]=s->table=table=tables->table;
|
||||
table->pos_in_table_list= tables;
|
||||
error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
|
||||
if(error)
|
||||
if (error)
|
||||
{
|
||||
table->file->print_error(error, MYF(0));
|
||||
DBUG_RETURN(1);
|
||||
table->file->print_error(error, MYF(0));
|
||||
goto error;
|
||||
}
|
||||
table->quick_keys.clear_all();
|
||||
table->reginfo.join_tab=s;
|
||||
@ -2511,7 +2516,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
||||
{
|
||||
join->tables=0; // Don't use join->table
|
||||
my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0));
|
||||
DBUG_RETURN(1);
|
||||
goto error;
|
||||
}
|
||||
s->key_dependent= s->dependent;
|
||||
}
|
||||
@ -2521,7 +2526,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
||||
if (update_ref_and_keys(join->thd, keyuse_array, stat, join->tables,
|
||||
conds, join->cond_equal,
|
||||
~outer_join, join->select_lex, &sargables))
|
||||
DBUG_RETURN(1);
|
||||
goto error;
|
||||
|
||||
/* Read tables with 0 or 1 rows (system tables) */
|
||||
join->const_table_map= 0;
|
||||
@ -2537,7 +2542,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
||||
if ((tmp=join_read_const_table(s, p_pos)))
|
||||
{
|
||||
if (tmp > 0)
|
||||
DBUG_RETURN(1); // Fatal error
|
||||
goto error; // Fatal error
|
||||
}
|
||||
else
|
||||
found_const_table_map|= s->table->map;
|
||||
@ -2609,7 +2614,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
||||
if ((tmp= join_read_const_table(s, join->positions+const_count-1)))
|
||||
{
|
||||
if (tmp > 0)
|
||||
DBUG_RETURN(1); // Fatal error
|
||||
goto error; // Fatal error
|
||||
}
|
||||
else
|
||||
found_const_table_map|= table->map;
|
||||
@ -2658,12 +2663,12 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
||||
set_position(join,const_count++,s,start_keyuse);
|
||||
if (create_ref_for_key(join, s, start_keyuse,
|
||||
found_const_table_map))
|
||||
DBUG_RETURN(1);
|
||||
goto error;
|
||||
if ((tmp=join_read_const_table(s,
|
||||
join->positions+const_count-1)))
|
||||
{
|
||||
if (tmp > 0)
|
||||
DBUG_RETURN(1); // Fatal error
|
||||
goto error; // Fatal error
|
||||
}
|
||||
else
|
||||
found_const_table_map|= table->map;
|
||||
@ -2740,7 +2745,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
||||
*s->on_expr_ref ? *s->on_expr_ref : conds,
|
||||
1, &error);
|
||||
if (!select)
|
||||
DBUG_RETURN(1);
|
||||
goto error;
|
||||
records= get_quick_record_count(join->thd, select, s->table,
|
||||
&s->const_keys, join->row_limit);
|
||||
s->quick=select->quick;
|
||||
@ -2786,7 +2791,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
||||
{
|
||||
optimize_keyuse(join, keyuse_array);
|
||||
if (choose_plan(join, all_table_map & ~join->const_table_map))
|
||||
DBUG_RETURN(TRUE);
|
||||
goto error;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2796,6 +2801,17 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
||||
}
|
||||
/* Generate an execution plan from the found optimal join order. */
|
||||
DBUG_RETURN(join->thd->killed || get_best_combination(join));
|
||||
|
||||
error:
|
||||
/*
|
||||
Need to clean up join_tab from TABLEs in case of error.
|
||||
They won't get cleaned up by JOIN::cleanup() because JOIN::join_tab
|
||||
may not be assigned yet by this function (which is building join_tab).
|
||||
Dangling TABLE::reginfo.join_tab may cause part_of_refkey to choke.
|
||||
*/
|
||||
for (tables= tables_arg; tables; tables= tables->next_leaf)
|
||||
tables->table->reginfo.join_tab= NULL;
|
||||
DBUG_RETURN (1);
|
||||
}
|
||||
|
||||
|
||||
@ -4730,6 +4746,18 @@ greedy_search(JOIN *join,
|
||||
*/
|
||||
join->positions[idx]= best_pos;
|
||||
|
||||
/*
|
||||
Update the interleaving state after extending the current partial plan
|
||||
with a new table.
|
||||
We are doing this here because best_extension_by_limited_search reverts
|
||||
the interleaving state to the one of the non-extended partial plan
|
||||
on exit.
|
||||
*/
|
||||
IF_DBUG(bool is_interleave_error= )
|
||||
check_interleaving_with_nj (best_table);
|
||||
/* This has been already checked by best_extension_by_limited_search */
|
||||
DBUG_ASSERT(!is_interleave_error);
|
||||
|
||||
/* find the position of 'best_table' in 'join->best_ref' */
|
||||
best_idx= idx;
|
||||
JOIN_TAB *pos= join->best_ref[best_idx];
|
||||
@ -4747,7 +4775,7 @@ greedy_search(JOIN *join,
|
||||
--size_remain;
|
||||
++idx;
|
||||
|
||||
DBUG_EXECUTE("opt", print_plan(join, join->tables,
|
||||
DBUG_EXECUTE("opt", print_plan(join, idx,
|
||||
record_count, read_time, read_time,
|
||||
"extended"););
|
||||
} while (TRUE);
|
||||
@ -4898,7 +4926,7 @@ best_extension_by_limited_search(JOIN *join,
|
||||
table_map real_table_bit= s->table->map;
|
||||
if ((remaining_tables & real_table_bit) &&
|
||||
!(remaining_tables & s->dependent) &&
|
||||
(!idx || !check_interleaving_with_nj(join->positions[idx-1].table, s)))
|
||||
(!idx || !check_interleaving_with_nj(s)))
|
||||
{
|
||||
double current_record_count, current_read_time;
|
||||
|
||||
@ -5043,7 +5071,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
|
||||
{
|
||||
table_map real_table_bit=s->table->map;
|
||||
if ((rest_tables & real_table_bit) && !(rest_tables & s->dependent) &&
|
||||
(!idx|| !check_interleaving_with_nj(join->positions[idx-1].table, s)))
|
||||
(!idx|| !check_interleaving_with_nj(s)))
|
||||
{
|
||||
double records, best;
|
||||
best_access_path(join, s, thd, rest_tables, idx, record_count,
|
||||
@ -5426,48 +5454,42 @@ store_val_in_field(Field *field, Item *item, enum_check_fields check_flag)
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
make_simple_join(JOIN *join,TABLE *tmp_table)
|
||||
/**
|
||||
@details Initialize a JOIN as a query execution plan
|
||||
that accesses a single table via a table scan.
|
||||
|
||||
@param parent contains JOIN_TAB and TABLE object buffers for this join
|
||||
@param tmp_table temporary table
|
||||
|
||||
@retval FALSE success
|
||||
@retval TRUE error occurred
|
||||
*/
|
||||
bool
|
||||
JOIN::make_simple_join(JOIN *parent, TABLE *tmp_table)
|
||||
{
|
||||
TABLE **tableptr;
|
||||
JOIN_TAB *join_tab;
|
||||
DBUG_ENTER("make_simple_join");
|
||||
DBUG_ENTER("JOIN::make_simple_join");
|
||||
|
||||
/*
|
||||
Reuse TABLE * and JOIN_TAB if already allocated by a previous call
|
||||
to this function through JOIN::exec (may happen for sub-queries).
|
||||
*/
|
||||
if (!join->table_reexec)
|
||||
{
|
||||
if (!(join->table_reexec= (TABLE**) join->thd->alloc(sizeof(TABLE*))))
|
||||
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||
if (join->tmp_join)
|
||||
join->tmp_join->table_reexec= join->table_reexec;
|
||||
}
|
||||
if (!join->join_tab_reexec)
|
||||
{
|
||||
if (!(join->join_tab_reexec=
|
||||
(JOIN_TAB*) join->thd->alloc(sizeof(JOIN_TAB))))
|
||||
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||
if (join->tmp_join)
|
||||
join->tmp_join->join_tab_reexec= join->join_tab_reexec;
|
||||
}
|
||||
tableptr= join->table_reexec;
|
||||
join_tab= join->join_tab_reexec;
|
||||
if (!parent->join_tab_reexec &&
|
||||
!(parent->join_tab_reexec= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB))))
|
||||
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||
|
||||
join->join_tab=join_tab;
|
||||
join->table=tableptr; tableptr[0]=tmp_table;
|
||||
join->tables=1;
|
||||
join->const_tables=0;
|
||||
join->const_table_map=0;
|
||||
join->tmp_table_param.field_count= join->tmp_table_param.sum_func_count=
|
||||
join->tmp_table_param.func_count=0;
|
||||
join->tmp_table_param.copy_field=join->tmp_table_param.copy_field_end=0;
|
||||
join->first_record=join->sort_and_group=0;
|
||||
join->send_records=(ha_rows) 0;
|
||||
join->group=0;
|
||||
join->row_limit=join->unit->select_limit_cnt;
|
||||
join->do_send_rows = (join->row_limit) ? 1 : 0;
|
||||
join_tab= parent->join_tab_reexec;
|
||||
table= &parent->table_reexec[0]; parent->table_reexec[0]= tmp_table;
|
||||
tables= 1;
|
||||
const_tables= 0;
|
||||
const_table_map= 0;
|
||||
tmp_table_param.field_count= tmp_table_param.sum_func_count=
|
||||
tmp_table_param.func_count= 0;
|
||||
tmp_table_param.copy_field= tmp_table_param.copy_field_end=0;
|
||||
first_record= sort_and_group=0;
|
||||
send_records= (ha_rows) 0;
|
||||
group= 0;
|
||||
row_limit= unit->select_limit_cnt;
|
||||
do_send_rows= row_limit ? 1 : 0;
|
||||
|
||||
join_tab->cache.buff=0; /* No caching */
|
||||
join_tab->table=tmp_table;
|
||||
@ -5484,7 +5506,7 @@ make_simple_join(JOIN *join,TABLE *tmp_table)
|
||||
join_tab->ref.key = -1;
|
||||
join_tab->not_used_in_distinct=0;
|
||||
join_tab->read_first_record= join_init_read_record;
|
||||
join_tab->join=join;
|
||||
join_tab->join= this;
|
||||
join_tab->ref.key_parts= 0;
|
||||
bzero((char*) &join_tab->read_record,sizeof(join_tab->read_record));
|
||||
tmp_table->status=0;
|
||||
@ -7607,7 +7629,7 @@ static int compare_fields_by_table_order(Item_field *field1,
|
||||
if (outer_ref)
|
||||
return cmp;
|
||||
JOIN_TAB **idx= (JOIN_TAB **) table_join_idx;
|
||||
cmp= idx[field2->field->table->tablenr]-idx[field1->field->table->tablenr];
|
||||
cmp= (uint) (idx[field2->field->table->tablenr] - idx[field1->field->table->tablenr]);
|
||||
return cmp < 0 ? -1 : (cmp ? 1 : 0);
|
||||
}
|
||||
|
||||
@ -8415,9 +8437,6 @@ static void reset_nj_counters(List<TABLE_LIST> *join_list)
|
||||
|
||||
SYNOPSIS
|
||||
check_interleaving_with_nj()
|
||||
join Join being processed
|
||||
last_tab Last table in current partial join order (this function is
|
||||
not called for empty partial join orders)
|
||||
next_tab Table we're going to extend the current partial join with
|
||||
|
||||
DESCRIPTION
|
||||
@ -8502,10 +8521,10 @@ static void reset_nj_counters(List<TABLE_LIST> *join_list)
|
||||
TRUE Requested join order extension not allowed.
|
||||
*/
|
||||
|
||||
static bool check_interleaving_with_nj(JOIN_TAB *last_tab, JOIN_TAB *next_tab)
|
||||
static bool check_interleaving_with_nj(JOIN_TAB *next_tab)
|
||||
{
|
||||
TABLE_LIST *next_emb= next_tab->table->pos_in_table_list->embedding;
|
||||
JOIN *join= last_tab->join;
|
||||
JOIN *join= next_tab->join;
|
||||
|
||||
if (join->cur_embedding_map & ~next_tab->embedding_map)
|
||||
{
|
||||
@ -9637,7 +9656,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
||||
table->s->default_values= table->record[1]+alloc_length;
|
||||
}
|
||||
copy_func[0]=0; // End marker
|
||||
param->func_count= copy_func - param->items_to_copy;
|
||||
param->func_count= (uint) (copy_func - param->items_to_copy);
|
||||
|
||||
recinfo=param->start_recinfo;
|
||||
null_flags=(uchar*) table->record[0];
|
||||
@ -15210,10 +15229,10 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
||||
item_list.push_back(new Item_int((int32)
|
||||
join->select_lex->select_number));
|
||||
item_list.push_back(new Item_string(join->select_lex->type,
|
||||
strlen(join->select_lex->type), cs));
|
||||
(uint) strlen(join->select_lex->type), cs));
|
||||
for (uint i=0 ; i < 7; i++)
|
||||
item_list.push_back(item_null);
|
||||
item_list.push_back(new Item_string(message,strlen(message),cs));
|
||||
item_list.push_back(new Item_string(message,(uint) strlen(message),cs));
|
||||
if (result->send_data(item_list))
|
||||
join->error= 1;
|
||||
}
|
||||
@ -15232,7 +15251,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
||||
item_list.push_back(new Item_null);
|
||||
/* select_type */
|
||||
item_list.push_back(new Item_string(join->select_lex->type,
|
||||
strlen(join->select_lex->type),
|
||||
(uint) strlen(join->select_lex->type),
|
||||
cs));
|
||||
/* table */
|
||||
{
|
||||
@ -15259,7 +15278,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
||||
}
|
||||
/* type */
|
||||
item_list.push_back(new Item_string(join_type_str[JT_ALL],
|
||||
strlen(join_type_str[JT_ALL]),
|
||||
(uint) strlen(join_type_str[JT_ALL]),
|
||||
cs));
|
||||
/* possible_keys */
|
||||
item_list.push_back(item_null);
|
||||
@ -15308,7 +15327,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
||||
join->select_lex->select_number));
|
||||
/* select_type */
|
||||
item_list.push_back(new Item_string(join->select_lex->type,
|
||||
strlen(join->select_lex->type),
|
||||
(uint) strlen(join->select_lex->type),
|
||||
cs));
|
||||
if (tab->type == JT_ALL && tab->select && tab->select->quick)
|
||||
{
|
||||
@ -15333,12 +15352,12 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
||||
{
|
||||
TABLE_LIST *real_table= table->pos_in_table_list;
|
||||
item_list.push_back(new Item_string(real_table->alias,
|
||||
strlen(real_table->alias),
|
||||
(uint) strlen(real_table->alias),
|
||||
cs));
|
||||
}
|
||||
/* type */
|
||||
item_list.push_back(new Item_string(join_type_str[tab->type],
|
||||
strlen(join_type_str[tab->type]),
|
||||
(uint) strlen(join_type_str[tab->type]),
|
||||
cs));
|
||||
/* Build "possible_keys" value and add it to item_list */
|
||||
if (!tab->keys.is_clear_all())
|
||||
@ -15351,7 +15370,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
||||
if (tmp1.length())
|
||||
tmp1.append(',');
|
||||
tmp1.append(table->key_info[j].name,
|
||||
strlen(table->key_info[j].name),
|
||||
(uint) strlen(table->key_info[j].name),
|
||||
system_charset_info);
|
||||
}
|
||||
}
|
||||
@ -15367,17 +15386,17 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
||||
KEY *key_info=table->key_info+ tab->ref.key;
|
||||
register uint length;
|
||||
item_list.push_back(new Item_string(key_info->name,
|
||||
strlen(key_info->name),
|
||||
(uint) strlen(key_info->name),
|
||||
system_charset_info));
|
||||
length= longlong2str(tab->ref.key_length, keylen_str_buf, 10) -
|
||||
keylen_str_buf;
|
||||
length= (uint) (longlong2str(tab->ref.key_length, keylen_str_buf, 10) -
|
||||
keylen_str_buf);
|
||||
item_list.push_back(new Item_string(keylen_str_buf, length,
|
||||
system_charset_info));
|
||||
for (store_key **ref=tab->ref.key_copy ; *ref ; ref++)
|
||||
{
|
||||
if (tmp2.length())
|
||||
tmp2.append(',');
|
||||
tmp2.append((*ref)->name(), strlen((*ref)->name()),
|
||||
tmp2.append((*ref)->name(), (uint) strlen((*ref)->name()),
|
||||
system_charset_info);
|
||||
}
|
||||
item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
|
||||
@ -15387,9 +15406,9 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
||||
KEY *key_info=table->key_info+ tab->index;
|
||||
register uint length;
|
||||
item_list.push_back(new Item_string(key_info->name,
|
||||
strlen(key_info->name),cs));
|
||||
length= longlong2str(key_info->key_length, keylen_str_buf, 10) -
|
||||
keylen_str_buf;
|
||||
(uint) strlen(key_info->name),cs));
|
||||
length= (uint) (longlong2str(key_info->key_length, keylen_str_buf, 10) -
|
||||
keylen_str_buf);
|
||||
item_list.push_back(new Item_string(keylen_str_buf,
|
||||
length,
|
||||
system_charset_info));
|
||||
@ -15422,7 +15441,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
||||
key_read=1;
|
||||
|
||||
if (tab->info)
|
||||
item_list.push_back(new Item_string(tab->info,strlen(tab->info),cs));
|
||||
item_list.push_back(new Item_string(tab->info,(uint) strlen(tab->info),cs));
|
||||
else if (tab->packed_info & TAB_INFO_HAVE_VALUE)
|
||||
{
|
||||
if (tab->packed_info & TAB_INFO_USING_INDEX)
|
||||
@ -15746,7 +15765,7 @@ void TABLE_LIST::print(THD *thd, String *str)
|
||||
if (schema_table)
|
||||
{
|
||||
append_identifier(thd, str, schema_table_name,
|
||||
strlen(schema_table_name));
|
||||
(uint) strlen(schema_table_name));
|
||||
cmp_name= schema_table_name;
|
||||
}
|
||||
else
|
||||
@ -15771,7 +15790,7 @@ void TABLE_LIST::print(THD *thd, String *str)
|
||||
}
|
||||
}
|
||||
|
||||
append_identifier(thd, str, t_alias, strlen(t_alias));
|
||||
append_identifier(thd, str, t_alias, (uint) strlen(t_alias));
|
||||
}
|
||||
|
||||
if (use_index)
|
||||
|
Reference in New Issue
Block a user