Merge with 4.0.4

BitKeeper/etc/logging_ok:
  auto-union
client/mysqldump.c:
  Auto merged
include/Makefile.am:
  Auto merged
include/my_base.h:
  Auto merged
include/my_sys.h:
  Auto merged
include/sslopt-case.h:
  Auto merged
libmysql/libmysql.c:
  Auto merged
libmysql/libmysql.def:
  Auto merged
libmysqld/lib_sql.cc:
  Auto merged
myisam/ft_boolean_search.c:
  Auto merged
myisam/mi_check.c:
  Auto merged
myisam/mi_create.c:
  Auto merged
myisam/myisamchk.c:
  Auto merged
mysql-test/mysql-test-run.sh:
  Auto merged
mysql-test/r/create.result:
  Auto merged
mysql-test/r/innodb.result:
  Auto merged
mysql-test/r/myisam.result:
  Auto merged
mysql-test/r/select.result:
  Auto merged
mysql-test/r/type_set.result:
  Auto merged
mysql-test/t/create.test:
  Auto merged
mysql-test/t/myisam.test:
  Auto merged
sql/Makefile.am:
  Auto merged
sql/filesort.cc:
  Auto merged
sql/ha_innodb.cc:
  Auto merged
sql/ha_myisam.cc:
  Auto merged
sql/handler.h:
  Auto merged
sql/item_cmpfunc.cc:
  Auto merged
sql/item_strfunc.cc:
  Auto merged
sql/item_strfunc.h:
  Auto merged
sql/lex.h:
  Auto merged
sql/log.cc:
  Auto merged
sql/log_event.cc:
  Auto merged
sql/mysql_priv.h:
  Auto merged
sql/mysqld.cc:
  Auto merged
sql/net_pkg.cc:
  Auto merged
sql/net_serv.cc:
  Auto merged
sql/opt_range.cc:
  Auto merged
sql/set_var.h:
  Auto merged
sql/slave.cc:
  Auto merged
sql/sql_base.cc:
  Auto merged
sql/sql_class.h:
  Auto merged
sql/sql_insert.cc:
  Auto merged
sql/sql_lex.cc:
  Auto merged
sql/sql_lex.h:
  Auto merged
sql/sql_load.cc:
  Auto merged
sql/share/english/errmsg.txt:
  Auto merged
sql/sql_table.cc:
  Auto merged
sql/sql_udf.cc:
  Auto merged
sql/sql_union.cc:
  Auto merged
sql/unireg.h:
  Auto merged
sql/sql_cache.cc:
  Code cleanup (removed ifdef)
This commit is contained in:
unknown 2002-10-02 17:55:12 +03:00
commit 95e772b656
370 changed files with 74767 additions and 5564 deletions

View file

@ -27,63 +27,26 @@
int mysql_union(THD *thd, LEX *lex,select_result *result)
{
SELECT_LEX *sl, *last_sl, *lex_sl;
ORDER *order;
SELECT_LEX *sl;
SELECT_LEX_UNIT *unit= &(lex->unit);
List<Item> item_list;
TABLE *table;
int describe=(lex->select_lex.options & SELECT_DESCRIBE) ? 1 : 0;
int res;
bool found_rows_for_union=false;
TABLE_LIST result_table_list;
TABLE_LIST *first_table=(TABLE_LIST *)lex->select_lex.table_list.first;
TMP_TABLE_PARAM tmp_table_param;
select_union *union_result;
DBUG_ENTER("mysql_union");
st_select_lex_node * global;
/* Fix tables 'to-be-unioned-from' list to point at opened tables */
last_sl= &lex->select_lex;
for (sl= last_sl;
sl && sl->linkage != NOT_A_SELECT;
last_sl=sl, sl=sl->next)
/* Global option */
if (((void*)(global= unit->global_parameters)) == ((void*)unit))
{
for (TABLE_LIST *cursor= (TABLE_LIST *)sl->table_list.first;
cursor;
cursor=cursor->next)
{
if (cursor->do_redirect) // False if CUBE/ROLLUP
{
cursor->table= ((TABLE_LIST*) cursor->table)->table;
cursor->do_redirect=false;
}
}
}
/* last_sel now points at the last select where the ORDER BY is stored */
if (sl)
{
/*
The found SL is an extra SELECT_LEX argument that contains
the ORDER BY and LIMIT parameter for the whole UNION
*/
lex_sl= sl;
order= (ORDER *) lex_sl->order_list.first;
found_rows_for_union = (lex->select_lex.options & OPTION_FOUND_ROWS &&
!describe && sl->select_limit);
found_rows_for_union= (lex->select_lex.options & OPTION_FOUND_ROWS &&
!describe && global->select_limit);
if (found_rows_for_union)
lex->select_lex.options ^= OPTION_FOUND_ROWS;
// This is done to eliminate unnecessary slowing down of the first query
if (!order || !describe)
last_sl->next=0; // Remove this extra element
}
else if (!last_sl->braces)
{
lex_sl= last_sl; // ORDER BY is here
order= (ORDER *) lex_sl->order_list.first;
}
else
{
lex_sl=0;
order=0;
}
if (describe)
@ -120,11 +83,12 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
bzero((char*) &tmp_table_param,sizeof(tmp_table_param));
tmp_table_param.field_count=item_list.elements;
if (!(table=create_tmp_table(thd, &tmp_table_param, item_list,
(ORDER*) 0, !describe & !lex->union_option,
1, 0,
(lex->select_lex.options | thd->options |
TMP_TABLE_ALL_COLUMNS))))
if (!(table= create_tmp_table(thd, &tmp_table_param, item_list,
(ORDER*) 0, !describe & !lex->union_option,
1, 0,
(lex->select_lex.options | thd->options |
TMP_TABLE_ALL_COLUMNS),
unit)))
DBUG_RETURN(-1);
table->file->extra(HA_EXTRA_WRITE_CACHE);
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
@ -140,25 +104,28 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
}
union_result->save_time_stamp=!describe;
union_result->tmp_table_param=&tmp_table_param;
for (sl= &lex->select_lex; sl; sl=sl->next)
for (sl= &lex->select_lex; sl; sl= sl->next_select())
{
lex->select=sl;
thd->offset_limit=sl->offset_limit;
thd->select_limit=sl->select_limit+sl->offset_limit;
if (thd->select_limit < sl->select_limit)
thd->select_limit= HA_POS_ERROR; // no limit
if (thd->select_limit == HA_POS_ERROR)
unit->offset_limit_cnt= sl->offset_limit;
unit->select_limit_cnt= sl->select_limit+sl->offset_limit;
if (unit->select_limit_cnt < sl->select_limit)
unit->select_limit_cnt= HA_POS_ERROR; // no limit
if (unit->select_limit_cnt == HA_POS_ERROR)
sl->options&= ~OPTION_FOUND_ROWS;
res=mysql_select(thd, (describe && sl->linkage==NOT_A_SELECT) ? first_table : (TABLE_LIST*) sl->table_list.first,
sl->item_list,
sl->where,
(sl->braces) ? (ORDER *)sl->order_list.first : (ORDER *) 0,
(ORDER*) sl->group_list.first,
sl->having,
(ORDER*) NULL,
sl->options | thd->options | SELECT_NO_UNLOCK | ((describe) ? SELECT_DESCRIBE : 0),
union_result);
res= mysql_select(thd,
(TABLE_LIST*) sl->table_list.first,
sl->item_list,
sl->where,
(sl->braces) ?
(ORDER *)sl->order_list.first : (ORDER *) 0,
(ORDER*) sl->group_list.first,
sl->having,
(ORDER*) NULL,
sl->options | thd->options |
SELECT_NO_UNLOCK | ((describe) ? SELECT_DESCRIBE : 0),
union_result, unit);
if (res)
goto exit;
}
@ -190,26 +157,20 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
}
if (!thd->fatal_error) // Check if EOM
{
if (lex_sl)
{
thd->offset_limit=lex_sl->offset_limit;
thd->select_limit=lex_sl->select_limit+lex_sl->offset_limit;
if (thd->select_limit < lex_sl->select_limit)
thd->select_limit= HA_POS_ERROR; // no limit
if (thd->select_limit == HA_POS_ERROR)
thd->options&= ~OPTION_FOUND_ROWS;
}
else
{
thd->offset_limit= 0;
thd->select_limit= thd->variables.select_limit;
}
st_select_lex_node * global= unit->global_parameters;
unit->offset_limit_cnt= global->offset_limit;
unit->select_limit_cnt= global->select_limit+global->offset_limit;
if (unit->select_limit_cnt < global->select_limit)
unit->select_limit_cnt= HA_POS_ERROR; // no limit
if (unit->select_limit_cnt == HA_POS_ERROR)
thd->options&= ~OPTION_FOUND_ROWS;
if (describe)
thd->select_limit= HA_POS_ERROR; // no limit
res=mysql_select(thd,&result_table_list,
item_list, NULL, (describe) ? 0 : order,
(ORDER*) NULL, NULL, (ORDER*) NULL,
thd->options, result);
unit->select_limit_cnt= HA_POS_ERROR; // no limit
res= mysql_select(thd,&result_table_list,
item_list, NULL,
(describe) ? 0 : (ORDER*)global->order_list.first,
(ORDER*) NULL, NULL, (ORDER*) NULL,
thd->options, result, unit);
if (found_rows_for_union && !res)
thd->limit_found_rows = (ulonglong)table->file->records;
}
@ -233,7 +194,7 @@ select_union::select_union(TABLE *table_par)
We can always use DUP_IGNORE because the temporary table will only
contain a unique key if we are using not using UNION ALL
*/
info.handle_duplicates=DUP_IGNORE;
info.handle_duplicates= DUP_IGNORE;
}
select_union::~select_union()
@ -241,8 +202,9 @@ select_union::~select_union()
}
int select_union::prepare(List<Item> &list)
int select_union::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
{
unit= u;
if (save_time_stamp && list.elements != table->fields)
{
my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
@ -254,9 +216,9 @@ int select_union::prepare(List<Item> &list)
bool select_union::send_data(List<Item> &values)
{
if (thd->offset_limit)
if (unit->offset_limit_cnt)
{ // using limit offset,count
thd->offset_limit--;
unit->offset_limit_cnt--;
return 0;
}
@ -280,7 +242,7 @@ bool select_union::flush()
if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
{
table->file->print_error(error,MYF(0));
::send_error(&thd->net);
::send_error(thd);
return 1;
}
return 0;