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.cc76
1 files changed, 56 insertions, 20 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 0ca5ab23288..326c27eff0a 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -975,9 +975,12 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables)
}
bool is_select= false;
+ bool use_sysvar= false;
switch (thd->lex->sql_command)
{
case SQLCOM_SELECT:
+ use_sysvar= true;
+ /* fall through */
case SQLCOM_INSERT_SELECT:
case SQLCOM_REPLACE_SELECT:
case SQLCOM_DELETE_MULTI:
@@ -1021,7 +1024,7 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables)
}
// propagate system_time from sysvar
- if (!vers_conditions.is_set() && is_select)
+ if (!vers_conditions.is_set() && use_sysvar)
{
if (vers_conditions.init_from_sysvar(thd))
DBUG_RETURN(-1);
@@ -6582,6 +6585,7 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
keyuse.keypart= FT_KEYPART;
keyuse.used_tables=cond_func->key_item()->used_tables();
keyuse.optimize= 0;
+ keyuse.ref_table_rows= 0;
keyuse.keypart_map= 0;
keyuse.sj_pred_no= UINT_MAX;
keyuse.validity_ref= 0;
@@ -6965,6 +6969,7 @@ void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array)
uint n_tables= my_count_bits(map);
if (n_tables == 1) // Only one table
{
+ DBUG_ASSERT(!(map & PSEUDO_TABLE_BITS)); // Must be a real table
Table_map_iterator it(map);
int tablenr= it.next_bit();
DBUG_ASSERT(tablenr != Table_map_iterator::BITMAP_END);
@@ -9150,7 +9155,7 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
/*
Check if we have a prefix of key=const that matches a quick select.
*/
- if (!is_hash_join_key_no(key))
+ if (!is_hash_join_key_no(key) && table->quick_keys.is_set(key))
{
key_part_map quick_key_map= (key_part_map(1) << table->quick_key_parts[key]) - 1;
if (table->quick_rows[key] &&
@@ -16560,10 +16565,15 @@ static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
/**
- Set NESTED_JOIN::counter=0 in all nested joins in passed list.
+ Set NESTED_JOIN::counter and n_tables in all nested joins in passed list.
+
+ For all nested joins contained in the passed join_list (including its
+ children), set:
+ - nested_join->counter=0
+ - nested_join->n_tables= {number of non-degenerate direct children}.
- Recursively set NESTED_JOIN::counter=0 for all nested joins contained in
- the passed join_list.
+ Non-degenerate means non-const base table or a join nest that has a
+ non-degenerate child.
@param join_list List of nested joins to process. It may also contain base
tables which will be ignored.
@@ -16586,8 +16596,11 @@ static uint reset_nj_counters(JOIN *join, List<TABLE_LIST> *join_list)
if (!nested_join->n_tables)
is_eliminated_nest= TRUE;
}
- if ((table->nested_join && !is_eliminated_nest) ||
- (!table->nested_join && (table->table->map & ~join->eliminated_tables)))
+ const table_map removed_tables= join->eliminated_tables |
+ join->const_table_map;
+
+ if ((table->nested_join && !is_eliminated_nest) ||
+ (!table->nested_join && (table->table->map & ~removed_tables)))
n++;
}
DBUG_RETURN(n);
@@ -18138,6 +18151,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
bool using_unique_constraint= false;
bool use_packed_rows= false;
bool not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
+ bool save_abort_on_warning;
char *tmpname,path[FN_REFLEN];
uchar *pos, *group_buff, *bitmaps;
uchar *null_flags;
@@ -18605,6 +18619,11 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
}
null_count= (blob_count == 0) ? 1 : 0;
hidden_field_count=param->hidden_field_count;
+
+ /* Protect against warnings in field_conv() in the next loop*/
+ save_abort_on_warning= thd->abort_on_warning;
+ thd->abort_on_warning= 0;
+
for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
{
Field *field= *reg_field;
@@ -18641,25 +18660,31 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
inherit the default value that is defined for the field referred
by the Item_field object from which 'field' has been created.
*/
- const Field *orig_field= default_field[i];
+ Field *orig_field= default_field[i];
/* Get the value from default_values */
if (orig_field->is_null_in_record(orig_field->table->s->default_values))
field->set_null();
else
{
+ /*
+ Copy default value. We have to use field_conv() for copy, instead of
+ memcpy(), because bit_fields may be stored differently
+ */
+ my_ptrdiff_t ptr_diff= (orig_field->table->s->default_values -
+ orig_field->table->record[0]);
field->set_notnull();
- memcpy(field->ptr,
- orig_field->ptr_in_record(orig_field->table->s->default_values),
- field->pack_length_in_rec());
+ orig_field->move_field_offset(ptr_diff);
+ field_conv(field, orig_field);
+ orig_field->move_field_offset(-ptr_diff);
}
- }
+ }
if (from_field[i])
{ /* Not a table Item */
copy->set(field,from_field[i],save_sum_fields);
copy++;
}
- length=field->pack_length();
+ length=field->pack_length_in_rec();
pos+= length;
/* Make entry for create table */
@@ -18681,7 +18706,11 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
// fix table name in field entry
field->set_table_name(&table->alias);
}
+ /* Handle group_null_items */
+ bzero(pos, table->s->reclength - (pos - table->record[0]));
+ MEM_CHECK_DEFINED(table->record[0], table->s->reclength);
+ thd->abort_on_warning= save_abort_on_warning;
param->copy_field_end=copy;
param->recinfo= recinfo; // Pointer to after last field
store_record(table,s->default_values); // Make empty default record
@@ -18950,8 +18979,9 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
goto err;
}
- // Make empty record so random data is not written to disk
- empty_record(table);
+ /* record[0] and share->default_values should now have been set up */
+ MEM_CHECK_DEFINED(table->record[0], table->s->reclength);
+ MEM_CHECK_DEFINED(share->default_values, table->s->reclength);
thd->mem_root= mem_root_save;
@@ -19244,7 +19274,11 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
(*recinfo)->type= FIELD_CHECK;
(*recinfo)->length= MARIA_UNIQUE_HASH_LENGTH;
(*recinfo)++;
- share->reclength+= MARIA_UNIQUE_HASH_LENGTH;
+
+ /* Avoid warnings from valgrind */
+ bzero(table->record[0]+ share->reclength, MARIA_UNIQUE_HASH_LENGTH);
+ bzero(share->default_values+ share->reclength, MARIA_UNIQUE_HASH_LENGTH);
+ share->reclength+= MARIA_UNIQUE_HASH_LENGTH;
}
else
{
@@ -19438,7 +19472,10 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
(*recinfo)->type= FIELD_CHECK;
(*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
(*recinfo)++;
- share->reclength+=MI_UNIQUE_HASH_LENGTH;
+ /* Avoid warnings from valgrind */
+ bzero(table->record[0]+ share->reclength, MI_UNIQUE_HASH_LENGTH);
+ bzero(share->default_values+ share->reclength, MI_UNIQUE_HASH_LENGTH);
+ share->reclength+= MI_UNIQUE_HASH_LENGTH;
}
else
{
@@ -20030,11 +20067,11 @@ bool instantiate_tmp_table(TABLE *table, KEY *keyinfo,
If it is not heap (in-memory) table then convert index to unique
constrain.
*/
+ MEM_CHECK_DEFINED(table->record[0], table->s->reclength);
if (create_internal_tmp_table(table, keyinfo, start_recinfo, recinfo,
options))
return TRUE;
- // Make empty record so random data is not written to disk
- empty_record(table);
+ MEM_CHECK_DEFINED(table->record[0], table->s->reclength);
}
if (open_tmp_table(table))
return TRUE;
@@ -28589,7 +28626,6 @@ AGGR_OP::prepare_tmp_table()
join->select_options))
return true;
(void) table->file->extra(HA_EXTRA_WRITE_CACHE);
- empty_record(table);
}
/* If it wasn't already, start index scan for grouping using table index. */
if (!table->file->inited && table->group &&