Re: Crash in MySQL 4.1 using subselect and UNION ALL

Re: Crash in MySQL 4.1 using subselect and UNION ALL

am 26.10.2002 12:31:49 von Sanja Byelkin

Hi!

On Sat, Oct 26, 2002 at 05:46:40AM +0200, Jocelyn Fournier wrote:
> Hi,
>
> How-to-repeat :
>
> Using the same table than for the distinct bug :
>
> CREATE TABLE `searchconthardwarefr3` (
> `topic` mediumint(8) unsigned NOT NULL default '0',
> `date` date NOT NULL default '0000-00-00',
> `pseudo` varchar(35) character set latin1 NOT NULL default '',
> PRIMARY KEY (`pseudo`,`date`,`topic`),
> KEY `topic` (`topic`)
> ) TYPE=MyISAM ROW_FORMAT=DYNAMIC
>
> INSERT INTO searchconthardwarefr3 (topic,date,pseudo) VALUES
> ('43506','2002-10-02','joce'),('40143','2002-08-03','joce');
>
> mysql> SELECT 1 FROM searchconthardwarefr3 WHERE 1=(SELECT 1 UNION SELECT 1)
> UNION ALL SELECT 1;
> ERROR 2013: Lost connection to MySQL server during query

Thank you for good bug report. It was 2 bugs: incorrect error handling &
global ALL option for unions. Here is fix with some code cleanup:

diff -Nrc a/sql/sql_lex.cc b/sql/sql_lex.cc
*** a/sql/sql_lex.cc Sat Oct 26 13:30:37 2002
--- b/sql/sql_lex.cc Sat Oct 26 13:30:37 2002
***************
*** 944,949 ****
--- 944,950 ----
global_parameters= this;
select_limit_cnt= HA_POS_ERROR;
offset_limit_cnt= 0;
+ union_option= 0;
prepared= optimized= 0;
item= 0;
}
diff -Nrc a/sql/sql_lex.h b/sql/sql_lex.h
*** a/sql/sql_lex.h Sat Oct 26 13:30:37 2002
--- b/sql/sql_lex.h Sat Oct 26 13:30:37 2002
***************
*** 240,245 ****
--- 240,246 ----
bool depended; /* depended from outer select subselect */
/* not NULL if union used in subselect, point to subselect item */
Item_subselect *item;
+ uint union_option;

void init_query();
bool create_total_list(THD *thd, st_lex *lex, TABLE_LIST **result);
***************
*** 373,379 ****
enum ha_rkey_function ha_rkey_mode;
enum enum_enable_or_disable alter_keys_onoff;
enum enum_var_type option_type;
! uint grant, grant_tot_col, which_columns, union_option;
uint fk_delete_opt, fk_update_opt, fk_match_option;
uint param_count;
bool drop_primary, drop_if_exists, local_file, olap;
--- 374,380 ----
enum ha_rkey_function ha_rkey_mode;
enum enum_enable_or_disable alter_keys_onoff;
enum enum_var_type option_type;
! uint grant, grant_tot_col, which_columns;
uint fk_delete_opt, fk_update_opt, fk_match_option;
uint param_count;
bool drop_primary, drop_if_exists, local_file, olap;
diff -Nrc a/sql/sql_parse.cc b/sql/sql_parse.cc
*** a/sql/sql_parse.cc Sat Oct 26 13:30:37 2002
--- b/sql/sql_parse.cc Sat Oct 26 13:30:37 2002
***************
*** 2904,2910 ****
thd->select_number= thd->lex.select_lex.select_number= 1;
thd->lex.value_list.empty();
thd->free_list= 0;
- thd->lex.union_option= 0;
thd->lex.select= &thd->lex.select_lex;
thd->lex.olap=thd->lex.describe=0;
thd->lex.select->olap= UNSPECIFIED_OLAP_TYPE;
--- 2904,2909 ----
diff -Nrc a/sql/sql_select.cc b/sql/sql_select.cc
*** a/sql/sql_select.cc Sat Oct 26 13:30:37 2002
--- b/sql/sql_select.cc Sat Oct 26 13:30:37 2002
***************
*** 371,377 ****
#endif

conds=optimize_cond(conds,&cond_value);
! if (thd->fatal_error) // Out of memory
{
delete procedure;
error = 0;
--- 371,377 ----
#endif

conds=optimize_cond(conds,&cond_value);
! if (thd->fatal_error || thd->net.report_error)
{
delete procedure;
error = 0;
diff -Nrc a/sql/sql_union.cc b/sql/sql_union.cc
*** a/sql/sql_union.cc Sat Oct 26 13:30:37 2002
--- b/sql/sql_union.cc Sat Oct 26 13:30:37 2002
***************
*** 110,116 ****
DBUG_RETURN(0);
prepared= 1;
union_result=0;
- describe=(first_select()->options & SELECT_DESCRIBE) ? 1 : 0;
res= 0;
found_rows_for_union= false;
TMP_TABLE_PARAM tmp_table_param;
--- 110,115 ----
***************
*** 122,151 ****
if (((void*)(global_parameters)) == ((void*)this))
{
found_rows_for_union= first_select()->options & OPTION_FOUND_ROWS &&
! !describe && global_parameters->select_limit;
if (found_rows_for_union)
first_select()->options ^= OPTION_FOUND_ROWS;
}
item_list.empty();
- if (describe)
- {
- 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 it(first_select()->item_list);
--- 121,131 ----
if (((void*)(global_parameters)) == ((void*)this))
{
found_rows_for_union= first_select()->options & OPTION_FOUND_ROWS &&
! global_parameters->select_limit;
if (found_rows_for_union)
first_select()->options ^= OPTION_FOUND_ROWS;
}
item_list.empty();
{
Item *item;
List_iterator it(first_select()->item_list);
***************
*** 162,169 ****
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 &
! !thd->lex.union_option,
1, 0,
(first_select()->options | thd->options |
TMP_TABLE_ALL_COLUMNS),
--- 142,148 ----
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, !union_option,
1, 0,
(first_select()->options | thd->options |
TMP_TABLE_ALL_COLUMNS),
***************
*** 179,185 ****
if (!(union_result=new select_union(table)))
goto err;

! union_result->save_time_stamp=!describe;
union_result->tmp_table_param=&tmp_table_param;

// prepare selects
--- 158,164 ----
if (!(union_result=new select_union(table)))
goto err;

! union_result->save_time_stamp=1;
union_result->tmp_table_param=&tmp_table_param;

// prepare selects
***************
*** 187,194 ****
for (sl= first_select(); sl; sl= sl->next_select())
{
JOIN *join= new JOIN(thd, sl->item_list,
! sl->options | thd->options | SELECT_NO_UNLOCK |
! ((describe) ? SELECT_DESCRIBE : 0),
union_result);
joins.push_back(new JOIN_P(join));
thd->lex.select=sl;
--- 166,172 ----
for (sl= first_select(); sl; sl= sl->next_select())
{
JOIN *join= new JOIN(thd, sl->item_list,
! sl->options | thd->options | SELECT_NO_UNLOCK,
union_result);
joins.push_back(new JOIN_P(join));
thd->lex.select=sl;
***************
*** 236,248 ****
sl->options&= ~OPTION_FOUND_ROWS;

if (!optimized)
! sl->join->optimize();
else
! sl->join->reinit();
!
! sl->join->exec();
! res= sl->join->error;

if (res)
{
thd->lex.select= lex_select_save;
--- 214,228 ----
sl->options&= ~OPTION_FOUND_ROWS;

if (!optimized)
! res= sl->join->optimize();
else
! res= sl->join->reinit();

+ if (!res)
+ {
+ sl->join->exec();
+ res= sl->join->error;
+ }
if (res)
{
thd->lex.select= lex_select_save;
***************
*** 289,300 ****
select_limit_cnt= HA_POS_ERROR; // no limit
if (select_limit_cnt == HA_POS_ERROR)
thd->options&= ~OPTION_FOUND_ROWS;
- if (describe)
- select_limit_cnt= HA_POS_ERROR; // no limit
res= mysql_select(thd,&result_table_list,
item_list, NULL,
- (describe) ?
- 0:
(ORDER*)global_parameters->order_list.first,
(ORDER*) NULL, NULL, (ORDER*) NULL,
thd->options, result, this, first_select(), 1);
--- 269,276 ----
diff -Nrc a/sql/sql_yacc.yy b/sql/sql_yacc.yy
*** a/sql/sql_yacc.yy Sat Oct 26 13:30:37 2002
--- b/sql/sql_yacc.yy Sat Oct 26 13:30:37 2002
***************
*** 4150,4156 ****

union_option:
/* empty */ {}
! | ALL {Lex->union_option=1;};

singleval_subselect:
subselect_start singleval_subselect_init
--- 4150,4156 ----

union_option:
/* empty */ {}
! | ALL {Select->master_unit()->union_option= 1;};

singleval_subselect:
subselect_start singleval_subselect_init


--
For technical support contracts, visit https://order.mysql.com/
__ ___ ___ ____ __
/ |/ /_ __/ __/ __ \/ / Mr. Oleksandr Byelkin
/ /|_/ / // /\ \/ /_/ / /__ MySQL AB, Full-Time Developer
/_/ /_/\_, /___/\___\_\___/ Lugansk, Ukraine
<___/ www.mysql.com

------------------------------------------------------------ ---------
Before posting, please check:
http://www.mysql.com/manual.php (the manual)
http://lists.mysql.com/ (the list archive)

To request this thread, e-mail bugs-thread12863@lists.mysql.com
To unsubscribe, e-mail

Re: Crash in MySQL 4.1 using subselect and UNION ALL

am 26.10.2002 17:12:50 von Sanja Byelkin

Hi!

On Sat, Oct 26, 2002 at 04:58:48PM +0200, Jocelyn Fournier wrote:
> Hi,
>
> The query works now, but EXPLAIN still crashes ;)
>
> EXPLAIN SELECT 1 FROM searchconthardwarefr3 WHERE 1=(SELECT 1 UNION SELECT
> 1) UNION ALL SELECT 1;
> ERROR 2013: Lost connection to MySQL server during query

Yes. I know. I did not fix all bugs in that patch, only 2 listed in that
letter. Here is fix for explain:

diff -Nrc a/sql/sql_select.cc b/sql/sql_select.cc
*** a/sql/sql_select.cc Sat Oct 26 18:07:48 2002
--- b/sql/sql_select.cc Sat Oct 26 18:07:48 2002
***************
*** 7251,7266 ****
select_result *result=join->result;
Item *item_null= new Item_null();
DBUG_ENTER("select_describe");
!
/* Don't log this into the slow query log */
select_lex->options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED);
join->unit->offset_limit_cnt= 0;

if (message)
{
! item_list.push_back(new Item_int((int32) thd->lex.select->select_number));
! item_list.push_back(new Item_string(thd->lex.select->type,
! strlen(thd->lex.select->type),
default_charset_info));
Item *empty= new Item_empty_string("",0);
for (uint i=0 ; i < 7; i++)
--- 7251,7268 ----
select_result *result=join->result;
Item *item_null= new Item_null();
DBUG_ENTER("select_describe");
! DBUG_PRINT("info", ("Select 0x%lx, type %s, message %s",
! (ulong)join->select_lex, join->select_lex->type,
! message));
/* Don't log this into the slow query log */
select_lex->options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED);
join->unit->offset_limit_cnt= 0;

if (message)
{
! item_list.push_back(new Item_int((int32) join->select_lex->select_number));
! item_list.push_back(new Item_string(join->select_lex->type,
! strlen(join->select_lex->type),
default_charset_info));
Item *empty= new Item_empty_string("",0);
for (uint i=0 ; i < 7; i++)
***************
*** 7285,7293 ****
tmp2.length(0);

item_list.empty();
! item_list.push_back(new Item_int((int32) thd->lex.select->select_number));
! item_list.push_back(new Item_string(thd->lex.select->type,
! strlen(thd->lex.select->type),
default_charset_info));
if (tab->type == JT_ALL && tab->select && tab->select->quick)
tab->type= JT_RANGE;
--- 7287,7296 ----
tmp2.length(0);

item_list.empty();
! item_list.push_back(new Item_int((int32)
! join->select_lex->select_number));
! item_list.push_back(new Item_string(join->select_lex->type,
! strlen(join->select_lex->type),
default_charset_info));
if (tab->type == JT_ALL && tab->select && tab->select->quick)
tab->type= JT_RANGE;
***************
*** 7445,7450 ****
--- 7448,7454 ----

int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
{
+ DBUG_ENTER("mysql_explain_union");
int res= 0;
SELECT_LEX *first= unit->first_select();
for (SELECT_LEX *sl= first;
***************
*** 7467,7478 ****
}
if (res > 0)
res= -res; // mysql_explain_select do not report error
! return res;
}

int mysql_explain_select(THD *thd, SELECT_LEX *select_lex, char const *type,
select_result *result)
{
select_lex->type= type;
thd->lex.select= select_lex;
SELECT_LEX_UNIT *unit= select_lex->master_unit();
--- 7471,7484 ----
}
if (res > 0)
res= -res; // mysql_explain_select do not report error
! DBUG_RETURN(res);
}

int mysql_explain_select(THD *thd, SELECT_LEX *select_lex, char const *type,
select_result *result)
{
+ DBUG_ENTER("mysql_explain_select");
+ DBUG_PRINT("info", ("Select 0x%lx, type %s", (ulong)select_lex, type))
select_lex->type= type;
thd->lex.select= select_lex;
SELECT_LEX_UNIT *unit= select_lex->master_unit();
***************
*** 7485,7490 ****
(ORDER*) thd->lex.proc_list.first,
select_lex->options | thd->options | SELECT_DESCRIBE,
result, unit, select_lex, 0);
! return res;
}

--- 7491,7496 ----
(ORDER*) thd->lex.proc_list.first,
select_lex->options | thd->options | SELECT_DESCRIBE,
result, unit, select_lex, 0);
! DBUG_RETURN(res);
}

diff -Nrc a/sql/sql_union.cc b/sql/sql_union.cc
*** a/sql/sql_union.cc Sat Oct 26 18:07:48 2002
--- b/sql/sql_union.cc Sat Oct 26 18:07:48 2002
***************
*** 198,208 ****
int st_select_lex_unit::exec()
{
DBUG_ENTER("st_select_lex_unit::exec");
if(depended || !item || !item->assigned())
{
if (optimized && item && item->assigned())
item->assigned(0); // We will reinit & rexecute unit
- SELECT_LEX *lex_select_save= thd->lex.select;
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
{
thd->lex.select=sl;
--- 198,209 ----
int st_select_lex_unit::exec()
{
DBUG_ENTER("st_select_lex_unit::exec");
+ SELECT_LEX *lex_select_save= thd->lex.select;
+
if(depended || !item || !item->assigned())
{
if (optimized && item && item->assigned())
item->assigned(0); // We will reinit & rexecute unit
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
{
thd->lex.select=sl;
***************
*** 229,242 ****
DBUG_RETURN(res);
}
}
- thd->lex.select= lex_select_save;
optimized= 1;
}

if (union_result->flush())
{
! res= 1; // Error is already sent
! DBUG_RETURN(res);
}

/* Send result to 'result' */
--- 230,242 ----
DBUG_RETURN(res);
}
}
optimized= 1;
}

if (union_result->flush())
{
! thd->lex.select= lex_select_save;
! DBUG_RETURN(1);
}

/* Send result to 'result' */
***************
*** 279,284 ****
--- 279,285 ----
}
}
thd->lex.select_lex.ftfunc_list= &thd->lex.select_lex.ftfunc_list_alloc;
+ thd->lex.select= lex_select_save;
DBUG_RETURN(res);
}


Thank you for your bugreports, again. As far as I list this patch here, I
will not answer on your first letter with this bug description.

--
For technical support contracts, visit https://order.mysql.com/
__ ___ ___ ____ __
/ |/ /_ __/ __/ __ \/ / Mr. Oleksandr Byelkin
/ /|_/ / // /\ \/ /_/ / /__ MySQL AB, Full-Time Developer
/_/ /_/\_, /___/\___\_\___/ Lugansk, Ukraine
<___/ www.mysql.com

------------------------------------------------------------ ---------
Before posting, please check:
http://www.mysql.com/manual.php (the manual)
http://lists.mysql.com/ (the list archive)

To request this thread, e-mail bugs-thread12868@lists.mysql.com
To unsubscribe, e-mail

Re: Crash in MySQL 4.1 using subselect and UNION ALL

am 27.10.2002 20:36:05 von Sanja Byelkin

Hi!

On Sat, Oct 26, 2002 at 05:22:44PM +0200, Jocelyn Fournier wrote:
> Ok, thanks for the patch :)
> Another new bug :
>
> SELECT (SELECT (SELECT 0 UNION SELECT 0));
> ERROR 2013: Lost connection to MySQL server during query
[skip]

Thank you for bugreport. Here is fix:

diff -Nrc a/sql/sql_lex.cc b/sql/sql_lex.cc
*** a/sql/sql_lex.cc Sun Oct 27 21:35:07 2002
--- b/sql/sql_lex.cc Sun Oct 27 21:35:07 2002
***************
*** 945,951 ****
select_limit_cnt= HA_POS_ERROR;
offset_limit_cnt= 0;
union_option= 0;
! prepared= optimized= 0;
item= 0;
}

--- 945,951 ----
select_limit_cnt= HA_POS_ERROR;
offset_limit_cnt= 0;
union_option= 0;
! prepared= optimized= executed= 0;
item= 0;
}

diff -Nrc a/sql/sql_lex.h b/sql/sql_lex.h
*** a/sql/sql_lex.h Sun Oct 27 21:35:07 2002
--- b/sql/sql_lex.h Sun Oct 27 21:35:07 2002
***************
*** 227,234 ****
select_result *result;
int res;
bool describe, found_rows_for_union,
! prepared, //prepare phase already performed for UNION (unit)
! optimized; // optimize phase already performed for UNION (unit)
public:
/*
Pointer to 'last' select or pointer to unit where stored
--- 227,235 ----
select_result *result;
int res;
bool describe, found_rows_for_union,
! prepared, // prepare phase already performed for UNION (unit)
! optimized, // optimize phase already performed for UNION (unit)
! executed; // already executed
public:
/*
Pointer to 'last' select or pointer to unit where stored
diff -Nrc a/sql/sql_union.cc b/sql/sql_union.cc
*** a/sql/sql_union.cc Sun Oct 27 21:35:07 2002
--- b/sql/sql_union.cc Sun Oct 27 21:35:07 2002
***************
*** 199,206 ****
{
DBUG_ENTER("st_select_lex_unit::exec");
SELECT_LEX *lex_select_save= thd->lex.select;
!
! if(depended || !item || !item->assigned())
{
if (optimized && item && item->assigned())
item->assigned(0); // We will reinit & rexecute unit
--- 199,210 ----
{
DBUG_ENTER("st_select_lex_unit::exec");
SELECT_LEX *lex_select_save= thd->lex.select;
!
! if (executed && !depended)
! DBUG_RETURN(0);
! executed= 1;
!
! if (depended || !item || !item->assigned())
{
if (optimized && item && item->assigned())
item->assigned(0); // We will reinit & rexecute unit


--
For technical support contracts, visit https://order.mysql.com/
__ ___ ___ ____ __
/ |/ /_ __/ __/ __ \/ / Mr. Oleksandr Byelkin
/ /|_/ / // /\ \/ /_/ / /__ MySQL AB, Full-Time Developer
/_/ /_/\_, /___/\___\_\___/ Lugansk, Ukraine
<___/ www.mysql.com

------------------------------------------------------------ ---------
Before posting, please check:
http://www.mysql.com/manual.php (the manual)
http://lists.mysql.com/ (the list archive)

To request this thread, e-mail bugs-thread12867@lists.mysql.com
To unsubscribe, e-mail