Commit 03f94c5c authored by monty@donna.mysql.fi's avatar monty@donna.mysql.fi
Browse files

Only mark MERGE readonly if all tables are readonly

Optimize some queries when using LIMIT
parent 9ee2a297
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@ int mode;
int handle_locking;
{
  int save_errno,i,errpos;
  uint files,dir_length,length;
  uint files,dir_length,length, options;
  ulonglong file_offset;
  char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end;
  MRG_INFO info,*m_info;
@@ -90,16 +90,22 @@ int handle_locking;
  m_info->open_tables=(MRG_TABLE *) (m_info+1);
  m_info->tables=files;

  options= (uint) ~0;
  for (i=files ; i-- > 0 ; )
  {
    m_info->open_tables[i].table=isam;
    m_info->options|=isam->s->base.options;
    options&=isam->s->base.options;
    m_info->records+=isam->s->state.records;
    m_info->del+=isam->s->state.del;
    m_info->data_file_length=isam->s->state.data_file_length;
    if (i)
      isam=(N_INFO*) (isam->open_list.next->data);
  }
  /* Don't force readonly if not all tables are readonly */
  if (! (options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA)))
    m_info->options&= ~(HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA);

  /* Fix fileinfo for easyer debugging (actually set by rrnd) */
  file_offset=0;
  for (i=0 ; (uint) i < files ; i++)
+7 −1
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@ int mode;
int handle_locking;
{
  int save_errno,i,errpos;
  uint files,dir_length,length;
  uint files,dir_length,length,options;
  ulonglong file_offset;
  char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end;
  MYRG_INFO info,*m_info;
@@ -93,16 +93,22 @@ int handle_locking;
  m_info->tables=files;
  errpos=2;

  options= (uint) ~0;
  for (i=files ; i-- > 0 ; )
  {
    m_info->open_tables[i].table=isam;
    m_info->options|=isam->s->options;
    options&=isam->s->options;
    m_info->records+=isam->state->records;
    m_info->del+=isam->state->del;
    m_info->data_file_length+=isam->state->data_file_length;
    if (i)
      isam=(MI_INFO*) (isam->open_list.next->data);
  }
  /* Don't force readonly if not all tables are readonly */
  if (! (options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA)))
    m_info->options&= ~(HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA);

  /* Fix fileinfo for easyer debugging (actually set by rrnd) */
  file_offset=0;
  for (i=0 ; (uint) i < files ; i++)
+38 −26
Original line number Diff line number Diff line
@@ -104,7 +104,7 @@ static COND *make_cond_for_table(COND *cond,table_map table,
static Item* part_of_refkey(TABLE *form,Field *field);
static uint find_shortest_key(TABLE *table, key_map usable_keys);
static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,
				    ha_rows select_limit);
				    ha_rows select_limit, bool no_changes);
static int create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit);
static int remove_duplicates(JOIN *join,TABLE *entry,List<Item> &fields);
static int remove_dup_with_compare(THD *thd, TABLE *entry, Field **field,
@@ -154,7 +154,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
  TABLE		*tmp_table;
  int		error,tmp;
  bool		need_tmp,hidden_group_fields;
  bool		simple_order,simple_group,no_order;
  bool		simple_order,simple_group,no_order, skip_sort_order;
  Item::cond_result cond_value;
  SQL_SELECT	*select;
  DYNAMIC_ARRAY keyuse;
@@ -169,7 +169,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
  select_distinct=test(select_options & SELECT_DISTINCT);
  tmp_table=0;
  select=0;
  no_order=0;
  no_order=skip_sort_order=0;
  bzero((char*) &keyuse,sizeof(keyuse));
  thd->proc_info="init";
  thd->used_tables=0;				// Updated by setup_fields
@@ -433,8 +433,10 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
      select_distinct=0;
  }
  else if (select_distinct && join.tables - join.const_tables == 1 &&
	   (order || thd->select_limit == HA_POS_ERROR ||
	    (join.select_options & OPTION_FOUND_ROWS)))
	   (thd->select_limit == HA_POS_ERROR ||
	    (join.select_options & OPTION_FOUND_ROWS) ||
	    order &&
	    !(skip_sort_order=test_if_skip_sort_order(&join.join_tab[join.const_tables], order, thd->select_limit,1))))
  {
    if ((group=create_distinct_group(order,fields)))
    {
@@ -518,7 +520,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
  if (!(select_options & SELECT_BIG_RESULT) &&
      ((group && join.const_tables != join.tables &&
	!test_if_skip_sort_order(&join.join_tab[join.const_tables], group,
				 HA_POS_ERROR)) ||
				 thd->select_limit,0)) ||
       select_distinct) &&
      join.tmp_table_param.quick_group && !procedure)
  {
@@ -532,10 +534,9 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
    if (order &&
	(join.const_tables == join.tables ||
	 test_if_skip_sort_order(&join.join_tab[join.const_tables], order,
				 (having || group ||
				  join.const_tables != join.tables - 1 ||
				 (join.const_tables != join.tables - 1 ||
				  (join.select_options & OPTION_FOUND_ROWS)) ?
				 HA_POS_ERROR : thd->select_limit)))
				 HA_POS_ERROR : thd->select_limit,0)))
      order=0;
    select_describe(&join,need_tmp,
		    (order != 0 &&
@@ -571,7 +572,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
			    group : (ORDER*) 0),
			   group ? 0 : select_distinct,
			   group && simple_group,
			   order == 0 &&
			   (order == 0 || skip_sort_order) &&
			   !(join.select_options & OPTION_FOUND_ROWS),
			   join.select_options)))
      goto err;					/* purecov: inspected */
@@ -622,6 +623,13 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
	  break;
	join_tab->not_used_in_distinct=1;
      } while (join_tab-- != join.join_tab);
      /* Optimize "select distinct b from t1 order by key_part_1 limit #" */
      if (order && skip_sort_order)
      {
	(void) test_if_skip_sort_order(&join.join_tab[join.const_tables],
				       order, thd->select_limit,0);
	order=0;
      }
    }

    /* Copy data to the temporary table */
@@ -4757,6 +4765,7 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
	if (create_myisam_from_heap(table, &join->tmp_table_param, error,1))
	  DBUG_RETURN(1);			// Not a table_is_full error
	table->uniques=0;			// To ensure rows are the same
      }
      if (++join->send_records >= join->tmp_table_param.end_write_records &
	  join->do_send_rows)
      {
@@ -4768,7 +4777,6 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
      }
    }
  }
  }
end:
  DBUG_RETURN(0);
}
@@ -5162,7 +5170,8 @@ static uint find_shortest_key(TABLE *table, key_map usable_keys)
/* Return 1 if we don't have to do file sorting */

static bool
test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
			bool no_changes)
{
  int ref_key;
  TABLE *table=tab->table;
@@ -5216,12 +5225,15 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
      {
	int flag;
	if ((flag=test_if_order_by_key(order,table,nr)))
	{
	  if (!no_changes)
	  {
	    tab->index=nr;
	    tab->read_first_record=  (flag > 0 ? join_init_read_first_with_key:
				      join_init_read_last_with_key);
	    table->file->index_init(nr);
	    tab->type=JT_NEXT;	// Read with index_first(), index_next()
	  }
	  DBUG_RETURN(1);
	}
      }
@@ -5239,7 +5251,7 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
  SQL_SELECT *select=tab->select;
  DBUG_ENTER("create_sort_index");

  if (test_if_skip_sort_order(tab,order,select_limit))
  if (test_if_skip_sort_order(tab,order,select_limit,0))
    DBUG_RETURN(0);
  if (!(sortorder=make_unireg_sortorder(order,&length)))
    goto err;				/* purecov: inspected */