mirror of
https://github.com/MariaDB/server.git
synced 2025-07-27 18:02:13 +03:00
SQL: RIGHT JOIN in derived [fix #383]
This commit is contained in:
@ -215,5 +215,83 @@ select y from t2 for system_time as of @t1;
|
|||||||
x
|
x
|
||||||
1
|
1
|
||||||
10
|
10
|
||||||
|
# LEFT/RIGHT JOIN
|
||||||
|
create or replace table t1 (x int, y int) with system versioning;
|
||||||
|
create or replace table t2 (x int, y int) with system versioning;
|
||||||
|
insert into t1 values (1, 1), (1, 2), (1, 3), (4, 4), (5, 5);
|
||||||
|
insert into t2 values (1, 2), (2, 1), (3, 1);
|
||||||
|
## LEFT JOIN: t1, t2 versioned
|
||||||
|
select * from (
|
||||||
|
select t1.x as LJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2
|
||||||
|
from t1 left join t2 on t1.x = t2.x)
|
||||||
|
as derived;
|
||||||
|
LJ1_x1 y1 x2 y2
|
||||||
|
1 1 1 2
|
||||||
|
1 2 1 2
|
||||||
|
1 3 1 2
|
||||||
|
4 4 NULL NULL
|
||||||
|
5 5 NULL NULL
|
||||||
|
alter table t2 drop system versioning;
|
||||||
|
## LEFT JOIN: t1 versioned
|
||||||
|
select * from (
|
||||||
|
select t1.x as LJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2
|
||||||
|
from t1 left join t2 on t1.x = t2.x)
|
||||||
|
as derived;
|
||||||
|
LJ2_x1 y1 x2 y2
|
||||||
|
1 1 1 2
|
||||||
|
1 2 1 2
|
||||||
|
1 3 1 2
|
||||||
|
4 4 NULL NULL
|
||||||
|
5 5 NULL NULL
|
||||||
|
alter table t1 drop system versioning;
|
||||||
|
alter table t2 add system versioning;
|
||||||
|
## LEFT JOIN: t2 versioned
|
||||||
|
select * from (
|
||||||
|
select t1.x as LJ3_x1, t1.y as y1, t2.x as x2, t2.y as y2
|
||||||
|
from t1 left join t2 on t1.x = t2.x)
|
||||||
|
as derived;
|
||||||
|
LJ3_x1 y1 x2 y2
|
||||||
|
1 1 1 2
|
||||||
|
1 2 1 2
|
||||||
|
1 3 1 2
|
||||||
|
4 4 NULL NULL
|
||||||
|
5 5 NULL NULL
|
||||||
|
alter table t1 add system versioning;
|
||||||
|
## RIGHT JOIN: t1, t2 versioned
|
||||||
|
select * from (
|
||||||
|
select t1.x as RJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2
|
||||||
|
from t1 right join t2 on t1.x = t2.x)
|
||||||
|
as derived;
|
||||||
|
RJ1_x1 y1 x2 y2
|
||||||
|
1 1 1 2
|
||||||
|
1 2 1 2
|
||||||
|
1 3 1 2
|
||||||
|
NULL NULL 2 1
|
||||||
|
NULL NULL 3 1
|
||||||
|
alter table t2 drop system versioning;
|
||||||
|
## RIGHT JOIN: t1 versioned
|
||||||
|
select * from (
|
||||||
|
select t1.x as RJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2
|
||||||
|
from t1 right join t2 on t1.x = t2.x)
|
||||||
|
as derived;
|
||||||
|
RJ2_x1 y1 x2 y2
|
||||||
|
1 1 1 2
|
||||||
|
1 2 1 2
|
||||||
|
1 3 1 2
|
||||||
|
NULL NULL 2 1
|
||||||
|
NULL NULL 3 1
|
||||||
|
alter table t1 drop system versioning;
|
||||||
|
alter table t2 add system versioning;
|
||||||
|
## RIGHT JOIN: t2 versioned
|
||||||
|
select * from (
|
||||||
|
select t1.x as RJ3_x1, t1.y as y1, t2.x as x2, t2.y as y2
|
||||||
|
from t1 right join t2 on t1.x = t2.x)
|
||||||
|
as derived;
|
||||||
|
RJ3_x1 y1 x2 y2
|
||||||
|
1 1 1 2
|
||||||
|
1 2 1 2
|
||||||
|
1 3 1 2
|
||||||
|
NULL NULL 2 1
|
||||||
|
NULL NULL 3 1
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
drop view vt1, vt2;
|
drop view vt1, vt2;
|
||||||
|
@ -151,5 +151,61 @@ select y from t2 for system_time as of @t1;
|
|||||||
select x from t1 for system_time as of @t0 union
|
select x from t1 for system_time as of @t0 union
|
||||||
select y from t2 for system_time as of @t1;
|
select y from t2 for system_time as of @t1;
|
||||||
|
|
||||||
|
--echo # LEFT/RIGHT JOIN
|
||||||
|
create or replace table t1 (x int, y int) with system versioning;
|
||||||
|
create or replace table t2 (x int, y int) with system versioning;
|
||||||
|
|
||||||
|
insert into t1 values (1, 1), (1, 2), (1, 3), (4, 4), (5, 5);
|
||||||
|
insert into t2 values (1, 2), (2, 1), (3, 1);
|
||||||
|
|
||||||
|
--echo ## LEFT JOIN: t1, t2 versioned
|
||||||
|
select * from (
|
||||||
|
select t1.x as LJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2
|
||||||
|
from t1 left join t2 on t1.x = t2.x)
|
||||||
|
as derived;
|
||||||
|
|
||||||
|
alter table t2 drop system versioning;
|
||||||
|
|
||||||
|
--echo ## LEFT JOIN: t1 versioned
|
||||||
|
select * from (
|
||||||
|
select t1.x as LJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2
|
||||||
|
from t1 left join t2 on t1.x = t2.x)
|
||||||
|
as derived;
|
||||||
|
|
||||||
|
alter table t1 drop system versioning;
|
||||||
|
alter table t2 add system versioning;
|
||||||
|
|
||||||
|
--echo ## LEFT JOIN: t2 versioned
|
||||||
|
select * from (
|
||||||
|
select t1.x as LJ3_x1, t1.y as y1, t2.x as x2, t2.y as y2
|
||||||
|
from t1 left join t2 on t1.x = t2.x)
|
||||||
|
as derived;
|
||||||
|
|
||||||
|
alter table t1 add system versioning;
|
||||||
|
|
||||||
|
--echo ## RIGHT JOIN: t1, t2 versioned
|
||||||
|
select * from (
|
||||||
|
select t1.x as RJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2
|
||||||
|
from t1 right join t2 on t1.x = t2.x)
|
||||||
|
as derived;
|
||||||
|
|
||||||
|
alter table t2 drop system versioning;
|
||||||
|
|
||||||
|
--echo ## RIGHT JOIN: t1 versioned
|
||||||
|
select * from (
|
||||||
|
select t1.x as RJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2
|
||||||
|
from t1 right join t2 on t1.x = t2.x)
|
||||||
|
as derived;
|
||||||
|
|
||||||
|
alter table t1 drop system versioning;
|
||||||
|
alter table t2 add system versioning;
|
||||||
|
|
||||||
|
--echo ## RIGHT JOIN: t2 versioned
|
||||||
|
select * from (
|
||||||
|
select t1.x as RJ3_x1, t1.y as y1, t2.x as x2, t2.y as y2
|
||||||
|
from t1 right join t2 on t1.x = t2.x)
|
||||||
|
as derived;
|
||||||
|
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
drop view vt1, vt2;
|
drop view vt1, vt2;
|
||||||
|
|
||||||
|
@ -818,6 +818,9 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables, COND **where_expr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
COND** dst_cond= where_expr;
|
||||||
|
COND* vers_cond= NULL;
|
||||||
|
|
||||||
for (table= tables; table; table= table->next_local)
|
for (table= tables; table; table= table->next_local)
|
||||||
{
|
{
|
||||||
if (table->table && table->table->versioned())
|
if (table->table && table->table->versioned())
|
||||||
@ -869,7 +872,6 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables, COND **where_expr
|
|||||||
continue;
|
continue;
|
||||||
} // if (vers_conditions)
|
} // if (vers_conditions)
|
||||||
|
|
||||||
COND** dst_cond= where_expr;
|
|
||||||
if (table->on_expr)
|
if (table->on_expr)
|
||||||
{
|
{
|
||||||
dst_cond= &table->on_expr;
|
dst_cond= &table->on_expr;
|
||||||
@ -888,7 +890,6 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables, COND **where_expr
|
|||||||
newx Item_field(thd, &this->context, table->db, table->alias, fstart);
|
newx Item_field(thd, &this->context, table->db, table->alias, fstart);
|
||||||
Item *row_end=
|
Item *row_end=
|
||||||
newx Item_field(thd, &this->context, table->db, table->alias, fend);
|
newx Item_field(thd, &this->context, table->db, table->alias, fend);
|
||||||
Item *row_end2= row_end;
|
|
||||||
|
|
||||||
bool tmp_from_ib=
|
bool tmp_from_ib=
|
||||||
table->table->s->table_category == TABLE_CATEGORY_TEMPORARY &&
|
table->table->s->table_category == TABLE_CATEGORY_TEMPORARY &&
|
||||||
@ -929,7 +930,7 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables, COND **where_expr
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
curr= newx Item_int(thd, ULONGLONG_MAX);
|
curr= newx Item_int(thd, ULONGLONG_MAX);
|
||||||
cond1= newx Item_func_eq(thd, row_end2, curr);
|
cond1= newx Item_func_eq(thd, row_end, curr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FOR_SYSTEM_TIME_AS_OF:
|
case FOR_SYSTEM_TIME_AS_OF:
|
||||||
@ -968,7 +969,7 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables, COND **where_expr
|
|||||||
{
|
{
|
||||||
case FOR_SYSTEM_TIME_UNSPECIFIED:
|
case FOR_SYSTEM_TIME_UNSPECIFIED:
|
||||||
curr= newx Item_int(thd, ULONGLONG_MAX);
|
curr= newx Item_int(thd, ULONGLONG_MAX);
|
||||||
cond1= newx Item_func_eq(thd, row_end2, curr);
|
cond1= newx Item_func_eq(thd, row_end, curr);
|
||||||
break;
|
break;
|
||||||
case FOR_SYSTEM_TIME_AS_OF:
|
case FOR_SYSTEM_TIME_AS_OF:
|
||||||
trx_id0= vers_conditions.unit_start == UNIT_TIMESTAMP ?
|
trx_id0= vers_conditions.unit_start == UNIT_TIMESTAMP ?
|
||||||
@ -1003,23 +1004,33 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables, COND **where_expr
|
|||||||
|
|
||||||
if (cond1)
|
if (cond1)
|
||||||
{
|
{
|
||||||
cond1= and_items(thd,
|
vers_cond= and_items(thd,
|
||||||
*dst_cond,
|
vers_cond,
|
||||||
and_items(thd,
|
and_items(thd,
|
||||||
cond2,
|
cond2,
|
||||||
cond1));
|
cond1));
|
||||||
|
if (table->is_view_or_derived())
|
||||||
if (on_stmt_arena.arena_replaced())
|
vers_cond= or_items(thd, vers_cond, newx Item_func_isnull(thd, row_end));
|
||||||
*dst_cond= cond1;
|
|
||||||
else
|
|
||||||
thd->change_item_tree(dst_cond, cond1);
|
|
||||||
|
|
||||||
this->where= *dst_cond;
|
|
||||||
this->where->top_level_item();
|
|
||||||
}
|
}
|
||||||
} // if (... table->table->versioned())
|
} // if (... table->table->versioned())
|
||||||
} // for (table= tables; ...)
|
} // for (table= tables; ...)
|
||||||
|
|
||||||
|
if (vers_cond)
|
||||||
|
{
|
||||||
|
COND *all_cond= and_items(thd, *dst_cond, vers_cond);
|
||||||
|
bool from_where= dst_cond == where_expr;
|
||||||
|
if (on_stmt_arena.arena_replaced())
|
||||||
|
*dst_cond= all_cond;
|
||||||
|
else
|
||||||
|
thd->change_item_tree(dst_cond, all_cond);
|
||||||
|
|
||||||
|
if (from_where)
|
||||||
|
{
|
||||||
|
this->where= *dst_cond;
|
||||||
|
this->where->top_level_item();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
#undef newx
|
#undef newx
|
||||||
}
|
}
|
||||||
|
@ -2215,6 +2215,10 @@ inline Item * and_items(THD *thd, Item* cond, Item *item)
|
|||||||
{
|
{
|
||||||
return (cond ? (new (thd->mem_root) Item_cond_and(thd, cond, item)) : item);
|
return (cond ? (new (thd->mem_root) Item_cond_and(thd, cond, item)) : item);
|
||||||
}
|
}
|
||||||
|
inline Item * or_items(THD *thd, Item* cond, Item *item)
|
||||||
|
{
|
||||||
|
return (cond ? (new (thd->mem_root) Item_cond_or(thd, cond, item)) : item);
|
||||||
|
}
|
||||||
bool choose_plan(JOIN *join, table_map join_tables);
|
bool choose_plan(JOIN *join, table_map join_tables);
|
||||||
void optimize_wo_join_buffering(JOIN *join, uint first_tab, uint last_tab,
|
void optimize_wo_join_buffering(JOIN *join, uint first_tab, uint last_tab,
|
||||||
table_map last_remaining_tables,
|
table_map last_remaining_tables,
|
||||||
|
Reference in New Issue
Block a user