summaryrefslogtreecommitdiff
path: root/sql/sql_union.cc
diff options
context:
space:
mode:
authorunknown <Sinisa@sinisa.nasamreza.org>2002-02-28 13:50:00 +0200
committerunknown <Sinisa@sinisa.nasamreza.org>2002-02-28 13:50:00 +0200
commitbf0b0d3e506e60c210ff17fbe2224dce3ff8822c (patch)
tree438b08ee31c323fa0dbdf6b846dd25e8eec362a1 /sql/sql_union.cc
parente82914796d6ae684a89a377e8a42f651b6c0e4d7 (diff)
downloadmariadb-git-bf0b0d3e506e60c210ff17fbe2224dce3ff8822c.tar.gz
Surgical changes in sql_select and sql_union code in order to
accomodate EXPLAIN properly for all possible variant of UNION's derived tables etc ... This also fixes all reported (and unreported) bugs when EXPLAIN is run on UNION's. select_describe() now has a very dirty hack to avoid some problems with transactional tables on table unlocking. Code speedup is possible. For the moment all that was important was that all tests are passed.
Diffstat (limited to 'sql/sql_union.cc')
-rw-r--r--sql/sql_union.cc58
1 files changed, 28 insertions, 30 deletions
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 51ad2425022..60155e0ce8d 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -31,10 +31,11 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
ORDER *order;
List<Item> item_list;
TABLE *table;
+ int describe=(lex->select_lex.options & SELECT_DESCRIBE) ? 1 : 0;
+ int res;
TABLE_LIST result_table_list;
TMP_TABLE_PARAM tmp_table_param;
select_union *union_result;
- int res;
DBUG_ENTER("mysql_union");
/* Fix tables 'to-be-unioned-from' list to point at opened tables */
@@ -70,33 +71,26 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
lex_sl=0;
order=0;
}
-
- if (lex->select_lex.options & SELECT_DESCRIBE)
+
+ if (describe)
{
- for (sl= &lex->select_lex; sl; sl=sl->next)
- {
- 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)
- sl->options&= ~OPTION_FOUND_ROWS;
- 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 |
- SELECT_DESCRIBE),
- result);
- }
- DBUG_RETURN(0);
+ Item *item;
+ item_list.push_back(new Item_empty_string("table",NAME_LEN));
+ item_list.push_back(new Item_empty_string("type",10));
+ item_list.push_back(item=new Item_empty_string("possible_keys",
+ NAME_LEN*MAX_KEY));
+ item->maybe_null=1;
+ item_list.push_back(item=new Item_empty_string("key",NAME_LEN));
+ item->maybe_null=1;
+ item_list.push_back(item=new Item_int("key_len",0,3));
+ item->maybe_null=1;
+ item_list.push_back(item=new Item_empty_string("ref",
+ NAME_LEN*MAX_REF_PARTS));
+ item->maybe_null=1;
+ item_list.push_back(new Item_real("rows",0.0,0,10));
+ item_list.push_back(new Item_empty_string("Extra",255));
}
-
+ else
{
Item *item;
List_iterator<Item> it(lex->select_lex.item_list);
@@ -113,7 +107,7 @@ 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, !lex->union_option,
+ (ORDER*) 0, !describe & !lex->union_option,
1, 0,
(lex->select_lex.options | thd->options |
TMP_TABLE_ALL_COLUMNS))))
@@ -130,7 +124,9 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
res= -1;
goto exit;
}
- for (sl= &lex->select_lex; sl; sl=sl->next)
+ union_result->save_time_stamp=!describe;
+
+ for (sl=&lex->select_lex;sl;sl=sl->next)
{
thd->offset_limit=sl->offset_limit;
thd->select_limit=sl->select_limit+sl->offset_limit;
@@ -146,7 +142,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
(ORDER*) sl->group_list.first,
sl->having,
(ORDER*) NULL,
- sl->options | thd->options | SELECT_NO_UNLOCK,
+ sl->options | thd->options | SELECT_NO_UNLOCK | ((describe) ? SELECT_DESCRIBE : 0),
union_result);
if (res)
goto exit;
@@ -187,6 +183,8 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
if (thd->select_limit == 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, /*ftfunc_list,*/ order,
(ORDER*) NULL, NULL, (ORDER*) NULL,
@@ -222,7 +220,7 @@ select_union::~select_union()
int select_union::prepare(List<Item> &list)
{
- if (list.elements != table->fields)
+ if (save_time_stamp && list.elements != table->fields)
{
my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT),MYF(0));