mirror of
https://github.com/MariaDB/server.git
synced 2025-01-30 02:30:06 +01:00
correct support for a mix of UNION/UNION ALL in the same query.
Bug#1428
This commit is contained in:
parent
78b4ba746b
commit
c0a9df1aae
8 changed files with 26 additions and 20 deletions
|
@ -36,8 +36,6 @@ a b
|
|||
1 a
|
||||
2 b
|
||||
3 c
|
||||
3 c
|
||||
3 c
|
||||
4 d
|
||||
5 f
|
||||
6 e
|
||||
|
@ -48,8 +46,6 @@ select 0,'#' union select a,b from t1 union all select a,b from t2 union select
|
|||
1 a
|
||||
2 b
|
||||
3 c
|
||||
3 c
|
||||
3 c
|
||||
4 d
|
||||
5 f
|
||||
6 e
|
||||
|
@ -920,5 +916,9 @@ select * from t1 UNION select * from t1 UNION ALL select * from t1;
|
|||
i
|
||||
1
|
||||
1
|
||||
1
|
||||
drop table t1;
|
||||
select 1 as a union all select 1 union all select 2 union select 1 union all select 2;
|
||||
a
|
||||
1
|
||||
2
|
||||
2
|
||||
|
|
|
@ -493,6 +493,7 @@ create table t1 (i int);
|
|||
insert into t1 values (1);
|
||||
select * from t1 UNION select * from t1;
|
||||
select * from t1 UNION ALL select * from t1;
|
||||
# The following should return 2 lines
|
||||
select * from t1 UNION select * from t1 UNION ALL select * from t1;
|
||||
drop table t1;
|
||||
select 1 as a union all select 1 union all select 2 union select 1 union all select 2;
|
||||
|
||||
|
|
|
@ -210,9 +210,6 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset;
|
|||
#define OPTION_RELAXED_UNIQUE_CHECKS (1L << 27)
|
||||
#define SELECT_NO_UNLOCK (1L << 28)
|
||||
|
||||
/* options for UNION set by the yacc parser (stored in unit->union_option) */
|
||||
#define UNION_ALL 1
|
||||
|
||||
/* Bits for different SQL modes modes (including ANSI mode) */
|
||||
#define MODE_REAL_AS_FLOAT 1
|
||||
#define MODE_PIPES_AS_CONCAT 2
|
||||
|
|
|
@ -138,7 +138,7 @@ static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
|
|||
*/
|
||||
if (!(table= create_tmp_table(thd, &derived_result->tmp_table_param,
|
||||
unit->types, (ORDER*) 0,
|
||||
is_union && !unit->union_option, 1,
|
||||
is_union && unit->union_distinct, 1,
|
||||
(first_select->options | thd->options |
|
||||
TMP_TABLE_ALL_COLUMNS),
|
||||
HA_POS_ERROR,
|
||||
|
|
|
@ -997,7 +997,7 @@ void st_select_lex_unit::init_query()
|
|||
global_parameters= first_select();
|
||||
select_limit_cnt= HA_POS_ERROR;
|
||||
offset_limit_cnt= 0;
|
||||
union_option= 0;
|
||||
union_distinct= 0;
|
||||
prepared= optimized= executed= 0;
|
||||
item= 0;
|
||||
union_result= 0;
|
||||
|
@ -1572,7 +1572,7 @@ void st_select_lex_unit::print(String *str)
|
|||
if (sl != first_select())
|
||||
{
|
||||
str->append(" union ", 7);
|
||||
if (union_option & UNION_ALL)
|
||||
if (!union_distinct)
|
||||
str->append("all ", 4);
|
||||
}
|
||||
if (sl->braces)
|
||||
|
|
|
@ -335,7 +335,7 @@ public:
|
|||
/* fake SELECT_LEX for union processing */
|
||||
st_select_lex *fake_select_lex;
|
||||
|
||||
uint union_option;
|
||||
st_select_lex *union_distinct; /* pointer to the last UNION DISTINCT */
|
||||
|
||||
void init_query();
|
||||
bool create_total_list(THD *thd, st_lex *lex, TABLE_LIST **result);
|
||||
|
|
|
@ -210,7 +210,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
|||
union_result->tmp_table_param.field_count= types.elements;
|
||||
if (!(table= create_tmp_table(thd_arg,
|
||||
&union_result->tmp_table_param, types,
|
||||
(ORDER*) 0, !union_option, 1,
|
||||
(ORDER*) 0, union_distinct, 1,
|
||||
(first_select_in_union()->options |
|
||||
thd_arg->options |
|
||||
TMP_TABLE_ALL_COLUMNS),
|
||||
|
@ -267,6 +267,8 @@ int st_select_lex_unit::exec()
|
|||
item->reset();
|
||||
table->file->delete_all_rows();
|
||||
}
|
||||
if (union_distinct) // for subselects
|
||||
table->file->extra(HA_EXTRA_CHANGE_KEY_TO_UNIQUE);
|
||||
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
|
||||
{
|
||||
ha_rows records_at_start= 0;
|
||||
|
@ -317,6 +319,8 @@ int st_select_lex_unit::exec()
|
|||
{
|
||||
records_at_start= table->file->records;
|
||||
sl->join->exec();
|
||||
if (sl == union_distinct)
|
||||
table->file->extra(HA_EXTRA_CHANGE_KEY_TO_DUP);
|
||||
res= sl->join->error;
|
||||
offset_limit_cnt= sl->offset_limit;
|
||||
if (!res && union_result->flush())
|
||||
|
|
|
@ -611,7 +611,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
|||
udf_type if_exists opt_local opt_table_options table_options
|
||||
table_option opt_if_not_exists opt_no_write_to_binlog opt_var_type
|
||||
opt_var_ident_type delete_option opt_temporary all_or_any opt_distinct
|
||||
opt_ignore_leaves fulltext_options spatial_type
|
||||
opt_ignore_leaves fulltext_options spatial_type union_option
|
||||
|
||||
%type <ulong_num>
|
||||
ULONG_NUM raid_types merge_insert_types
|
||||
|
@ -718,7 +718,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
|||
table_to_table_list table_to_table opt_table_list opt_as
|
||||
handler_rkey_function handler_read_or_scan
|
||||
single_multi table_wild_list table_wild_one opt_wild
|
||||
union_clause union_list union_option
|
||||
union_clause union_list
|
||||
precision subselect_start opt_and charset
|
||||
subselect_end select_var_list select_var_list_init help opt_len
|
||||
opt_extended_describe
|
||||
|
@ -5571,7 +5571,7 @@ union_clause:
|
|||
;
|
||||
|
||||
union_list:
|
||||
UNION_SYM union_option
|
||||
UNION_SYM union_option
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
if (lex->exchange)
|
||||
|
@ -5589,6 +5589,9 @@ union_list:
|
|||
YYABORT;
|
||||
mysql_init_select(lex);
|
||||
lex->current_select->linkage=UNION_TYPE;
|
||||
if ($2) /* UNION DISTINCT - remember position */
|
||||
lex->current_select->master_unit()->union_distinct=
|
||||
lex->current_select;
|
||||
}
|
||||
select_init {}
|
||||
;
|
||||
|
@ -5630,9 +5633,10 @@ order_or_limit:
|
|||
;
|
||||
|
||||
union_option:
|
||||
/* empty */ {}
|
||||
| DISTINCT {}
|
||||
| ALL {Select->master_unit()->union_option|= UNION_ALL;};
|
||||
/* empty */ { $$=1; }
|
||||
| DISTINCT { $$=1; }
|
||||
| ALL { $$=0; }
|
||||
;
|
||||
|
||||
singlerow_subselect:
|
||||
subselect_start singlerow_subselect_init
|
||||
|
|
Loading…
Add table
Reference in a new issue