summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <Sinisa@sinisa.nasamreza.org>2003-03-06 17:02:10 +0200
committerunknown <Sinisa@sinisa.nasamreza.org>2003-03-06 17:02:10 +0200
commit236015ed7ac81e3a4525e04a7769cf503af38e14 (patch)
tree41aacee98da8f1449de6964c7b87878106bb88ca /sql
parent6f5ea7022660f62e8e434c968f0d256aa8c8e47c (diff)
downloadmariadb-git-236015ed7ac81e3a4525e04a7769cf503af38e14.tar.gz
three bug fixes and major code cleanup
Diffstat (limited to 'sql')
-rw-r--r--sql/item_subselect.cc2
-rw-r--r--sql/mysql_priv.h3
-rw-r--r--sql/sql_derived.cc2
-rw-r--r--sql/sql_lex.h12
-rw-r--r--sql/sql_parse.cc2
-rw-r--r--sql/sql_prepare.cc2
-rw-r--r--sql/sql_select.cc30
-rw-r--r--sql/sql_select.h3
-rw-r--r--sql/sql_union.cc64
-rw-r--r--sql/sql_update.cc2
10 files changed, 71 insertions, 51 deletions
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index fb51b5561e9..524bb74d5a5 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -684,7 +684,7 @@ int subselect_single_select_engine::prepare()
(ORDER*) select_lex->group_list.first,
select_lex->having,
(ORDER*) 0, select_lex,
- select_lex->master_unit(), 0, 0))
+ select_lex->master_unit(), 0))
return 1;
thd->lex.current_select= save_select;
return 0;
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 5bf7e6e6951..df3e3f867e0 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -405,8 +405,7 @@ int mysql_select(THD *thd, Item ***rref_pointer_array,
COND *conds, uint og_num, ORDER *order, ORDER *group,
Item *having, ORDER *proc_param, ulong select_type,
select_result *result, SELECT_LEX_UNIT *unit,
- SELECT_LEX *select_lex, bool fake_select_lex,
- bool tables_and_fields_initied);
+ SELECT_LEX *select_lex, bool tables_and_fields_initied);
void free_underlaid_joins(THD *thd, SELECT_LEX *select);
void fix_tables_pointers(SELECT_LEX *select_lex);
void fix_tables_pointers(SELECT_LEX_UNIT *select_lex);
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index c0a4436a059..f2cddeead2f 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -172,7 +172,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
(ORDER *) select_cursor->group_list.first,
select_cursor->having, (ORDER*) NULL,
select_cursor->options | thd->options | SELECT_NO_UNLOCK,
- derived_result, unit, select_cursor, 0, 1);
+ derived_result, unit, select_cursor, 1);
if (!res)
{
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index aff3485dbe4..c0f24d6940e 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -311,6 +311,11 @@ public:
st_select_lex_unit* master_unit();
st_select_lex* outer_select();
st_select_lex* first_select() { return (st_select_lex*) slave; }
+ st_select_lex* first_select_in_union()
+ {
+ return (slave && slave->linkage == GLOBAL_OPTIONS_TYPE) ?
+ (st_select_lex*) slave->next : (st_select_lex*) slave;
+ }
st_select_lex_unit* next_unit() { return (st_select_lex_unit*) next; }
void exclude_level();
@@ -404,6 +409,13 @@ public:
}
friend void mysql_init_query(THD *thd);
+ void make_empty_select(st_select_lex *last_select)
+ {
+ select_number=INT_MAX;
+ init_query();
+ init_select();
+ include_neighbour(last_select);
+ }
};
typedef class st_select_lex SELECT_LEX;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index ce782b0480c..78986c88062 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2433,7 +2433,7 @@ mysql_execute_command(THD *thd)
(ORDER *)NULL,
select_lex->options | thd->options |
SELECT_NO_JOIN_CACHE,
- result, unit, select_lex, 0, 0);
+ result, unit, select_lex, 0);
if (thd->net.report_error)
res= -1;
delete result;
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 3cb4c4e8244..eefd1b5d4e1 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -567,7 +567,7 @@ static bool mysql_test_select_fields(PREP_STMT *stmt, TABLE_LIST *tables,
if (join->prepare(&select_lex->ref_pointer_array, tables,
wild_num, conds, og_num, order, group, having, proc,
- select_lex, unit, 0, 0))
+ select_lex, unit, 0))
DBUG_RETURN(1);
/*
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 47fe271f2b6..23381831ce3 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -182,7 +182,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result)
select_lex->having,
(ORDER*) lex->proc_list.first,
select_lex->options | thd->options,
- result, &(lex->unit), &(lex->select_lex), 0, 0);
+ result, &(lex->unit), &(lex->select_lex), 0);
if (res && result)
result->abort();
@@ -268,7 +268,7 @@ JOIN::prepare(Item ***rref_pointer_array,
Item *having_init,
ORDER *proc_param_init, SELECT_LEX *select,
SELECT_LEX_UNIT *unit,
- bool fake_select_lex, bool tables_and_fields_initied)
+ bool tables_and_fields_initied)
{
DBUG_ENTER("JOIN::prepare");
@@ -279,8 +279,7 @@ JOIN::prepare(Item ***rref_pointer_array,
proc_param= proc_param_init;
tables_list= tables_init;
select_lex= select;
- if (!fake_select_lex)
- select_lex->join= this;
+ select_lex->join= this;
union_part= (unit->first_select()->next_select() != 0);
/* Check that all tables, fields, conds and order are ok */
@@ -1261,7 +1260,6 @@ int
JOIN::cleanup(THD *thd)
{
DBUG_ENTER("JOIN::cleanup");
-
select_lex->join= 0;
if (tmp_join)
@@ -1292,15 +1290,14 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
COND *conds, uint og_num, ORDER *order, ORDER *group,
Item *having, ORDER *proc_param, ulong select_options,
select_result *result, SELECT_LEX_UNIT *unit,
- SELECT_LEX *select_lex, bool fake_select_lex,
- bool tables_and_fields_initied)
+ SELECT_LEX *select_lex, bool tables_and_fields_initied)
{
int err;
bool free_join= 1;
DBUG_ENTER("mysql_select");
JOIN *join;
- if (!fake_select_lex && select_lex->join != 0)
+ if (select_lex->join != 0)
{
//here is EXPLAIN of subselect or derived table
join= select_lex->join;
@@ -1320,8 +1317,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
if (join->prepare(rref_pointer_array, tables, wild_num,
conds, og_num, order, group, having, proc_param,
- select_lex, unit, fake_select_lex,
- tables_and_fields_initied))
+ select_lex, unit, tables_and_fields_initied))
{
DBUG_RETURN(-1);
}
@@ -1350,7 +1346,7 @@ err:
thd->limit_found_rows= curr_join->send_records;
thd->examined_row_count= curr_join->examined_rows;
thd->proc_info="end";
- err= (fake_select_lex ? curr_join->error : join->cleanup(thd));
+ err= join->cleanup(thd);
if (thd->net.report_error)
err= -1;
delete join;
@@ -7086,15 +7082,16 @@ find_order_in_list(THD *thd, Item **ref_pointer_array,
TABLE_LIST *tables,ORDER *order, List<Item> &fields,
List<Item> &all_fields)
{
- if ((*order->item)->type() == Item::INT_ITEM)
+ Item *itemptr=*order->item;
+ if (itemptr->type() == Item::INT_ITEM)
{ /* Order by position */
Item *item=0;
- uint count= (uint) ((Item_int*) (*order->item))->value;
+ uint count= (uint) ((Item_int*)itemptr)->value;
if (count > fields.elements)
{
my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),
- MYF(0),(*order->item)->full_name(),
+ MYF(0),itemptr->full_name(),
thd->where);
return 1;
}
@@ -7103,8 +7100,7 @@ find_order_in_list(THD *thd, Item **ref_pointer_array,
return 0;
}
uint counter;
- Item **item= find_item_in_list(*order->item, fields, &counter,
- IGNORE_ERRORS);
+ Item **item= find_item_in_list(itemptr, fields, &counter, IGNORE_ERRORS);
if (item)
{
order->item= ref_pointer_array + counter;
@@ -8103,7 +8099,7 @@ int mysql_explain_select(THD *thd, SELECT_LEX *select_lex, char const *type,
select_lex->having,
(ORDER*) thd->lex.proc_list.first,
select_lex->options | thd->options | SELECT_DESCRIBE,
- result, unit, select_lex, 0, 0);
+ result, unit, select_lex, 0);
DBUG_RETURN(res);
}
diff --git a/sql/sql_select.h b/sql/sql_select.h
index bb928846186..c5411a8790b 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -256,8 +256,7 @@ class JOIN :public Sql_alloc
int prepare(Item ***rref_pointer_array, TABLE_LIST *tables, uint wind_num,
COND *conds, uint og_num, ORDER *order, ORDER *group,
Item *having, ORDER *proc_param, SELECT_LEX *select,
- SELECT_LEX_UNIT *unit, bool fake_select_lex,
- bool tables_and_fields_initied);
+ SELECT_LEX_UNIT *unit, bool tables_and_fields_initied);
int optimize();
int reinit();
void exec();
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index feaa8371acb..607f3007d1d 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -122,9 +122,9 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result,
this->result= result;
t_and_f= tables_and_fields_initied;
SELECT_LEX_NODE *lex_select_save= thd->lex.current_select;
- SELECT_LEX *sl;
+ SELECT_LEX *select_cursor;
- thd->lex.current_select= sl= first_select();
+ thd->lex.current_select= select_cursor= first_select_in_union();
/* Global option */
if (((void*)(global_parameters)) == ((void*)this))
{
@@ -136,26 +136,27 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result,
if (t_and_f)
{
// Item list and tables will be initialized by mysql_derived
- item_list= sl->item_list;
+ item_list= select_cursor->item_list;
}
else
{
item_list.empty();
- TABLE_LIST *first_table= (TABLE_LIST*) first_select()->table_list.first;
+ TABLE_LIST *first_table= (TABLE_LIST*) select_cursor->table_list.first;
if (setup_tables(first_table) ||
- setup_wild(thd, first_table, sl->item_list, 0, sl->with_wild))
+ setup_wild(thd, first_table, select_cursor->item_list, 0, select_cursor->with_wild))
goto err;
- List_iterator<Item> it(sl->item_list);
+ List_iterator<Item> it(select_cursor->item_list);
Item *item;
while((item=it++))
item->maybe_null=1;
- item_list= sl->item_list;
- sl->with_wild= 0;
- if (setup_ref_array(thd, &sl->ref_pointer_array,
- (item_list.elements + sl->with_sum_func +
- sl->order_list.elements + sl->group_list.elements)) ||
- setup_fields(thd, sl->ref_pointer_array, first_table, item_list,
+ item_list= select_cursor->item_list;
+ select_cursor->with_wild= 0;
+ if (setup_ref_array(thd, &select_cursor->ref_pointer_array,
+ (item_list.elements + select_cursor->with_sum_func +
+ select_cursor->order_list.elements +
+ select_cursor->group_list.elements)) ||
+ setup_fields(thd, select_cursor->ref_pointer_array, first_table, item_list,
0, 0, 1))
goto err;
t_and_f= 1;
@@ -165,7 +166,7 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result,
tmp_table_param.field_count=item_list.elements;
if (!(table= create_tmp_table(thd, &tmp_table_param, item_list,
(ORDER*) 0, !union_option,
- 1, (first_select()->options | thd->options |
+ 1, (select_cursor->options | thd->options |
TMP_TABLE_ALL_COLUMNS),
HA_POS_ERROR)))
goto err;
@@ -181,9 +182,16 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result,
union_result->not_describe=1;
union_result->tmp_table_param=&tmp_table_param;
+
+/*
+ the following piece of code is placed here solely for the purpose of
+ getting correct results with EXPLAIN when UNION is withing a sub-select
+ or derived table ...
+*/
+
if (thd->lex.describe)
{
- for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
+ for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
{
JOIN *join= new JOIN(thd, sl->item_list,
sl->options | thd->options | SELECT_NO_UNLOCK,
@@ -206,16 +214,17 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result,
(ORDER*) sl->group_list.first,
sl->having,
(ORDER*) NULL,
- sl, this, 0, t_and_f);
+ sl, this, t_and_f);
t_and_f= 0;
if (res | thd->is_fatal_error)
goto err;
}
}
+
item_list.empty();
thd->lex.current_select= lex_select_save;
{
- List_iterator<Item> it(first_select()->item_list);
+ List_iterator<Item> it(select_cursor->item_list);
Field **field;
for (field= table->field; *field; field++)
@@ -236,7 +245,8 @@ int st_select_lex_unit::exec()
{
DBUG_ENTER("st_select_lex_unit::exec");
SELECT_LEX_NODE *lex_select_save= thd->lex.current_select;
-
+ SELECT_LEX *select_cursor=first_select_in_union(), *last_select;
+
if (executed && !(dependent || uncacheable))
DBUG_RETURN(0);
executed= 1;
@@ -249,8 +259,9 @@ int st_select_lex_unit::exec()
item->reset();
table->file->delete_all_rows();
}
- for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
+ for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
{
+ last_select=sl;
if (optimized)
res= sl->join->reinit();
else
@@ -276,7 +287,7 @@ int st_select_lex_unit::exec()
(ORDER*) sl->group_list.first,
sl->having,
(ORDER*) NULL,
- sl, this, 0, t_and_f);
+ sl, this, t_and_f);
t_and_f=0;
if (res | thd->is_fatal_error)
{
@@ -307,7 +318,7 @@ int st_select_lex_unit::exec()
/* Send result to 'result' */
// to correct ORDER BY reference resolving
- thd->lex.current_select = first_select();
+ thd->lex.current_select = select_cursor;
res =-1;
{
#if 0
@@ -321,9 +332,10 @@ int st_select_lex_unit::exec()
if (!thd->is_fatal_error) // Check if EOM
{
- SELECT_LEX *sl=thd->lex.current_select->master_unit()->first_select();
- offset_limit_cnt= (sl->braces) ? global_parameters->offset_limit : 0;
- select_limit_cnt= (sl->braces) ? global_parameters->select_limit+
+ SELECT_LEX *fake_select = new SELECT_LEX();
+ fake_select->make_empty_select(last_select);
+ offset_limit_cnt= (select_cursor->braces) ? global_parameters->offset_limit : 0;
+ select_limit_cnt= (select_cursor->braces) ? global_parameters->select_limit+
global_parameters->offset_limit : HA_POS_ERROR;
if (select_limit_cnt < global_parameters->select_limit)
select_limit_cnt= HA_POS_ERROR; // no limit
@@ -334,9 +346,11 @@ int st_select_lex_unit::exec()
global_parameters->order_list.elements,
(ORDER*)global_parameters->order_list.first,
(ORDER*) NULL, NULL, (ORDER*) NULL,
- thd->options, result, this, first_select(), 1, 0);
+ thd->options, result, this, fake_select, 0);
if (found_rows_for_union && !res)
thd->limit_found_rows = (ulonglong)table->file->records;
+ fake_select->exclude();
+ delete fake_select;
}
}
thd->lex.select_lex.ftfunc_list= &thd->lex.select_lex.ftfunc_list_alloc;
@@ -357,7 +371,7 @@ int st_select_lex_unit::cleanup()
free_tmp_table(thd, table);
table= 0; // Safety
}
- for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
+ for (SELECT_LEX *sl= first_select_in_union(); sl; sl= sl->next_select())
{
JOIN *join;
if ((join= sl->join))
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 88f677938ad..dd3eb326b38 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -428,7 +428,7 @@ int mysql_multi_update(THD *thd,
conds, 0, (ORDER *) NULL, (ORDER *)NULL, (Item *) NULL,
(ORDER *)NULL,
options | SELECT_NO_JOIN_CACHE,
- result, unit, select_lex, 0, 0);
+ result, unit, select_lex, 0);
delete result;
DBUG_RETURN(res);
}