summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2017-12-12 20:27:47 +0300
committerAleksey Midenkov <midenok@gmail.com>2017-12-12 20:39:44 +0300
commita0e137c4a9e8a86aeca2b56456f75e1278b7460c (patch)
treea1aa1015764032aae27fa3b0b3686811fc008804
parentcb4657e3b42e273318344181754a0cf8fb393524 (diff)
downloadmariadb-git-a0e137c4a9e8a86aeca2b56456f75e1278b7460c.tar.gz
SQL: RIGHT JOIN in derived [fix #383]
-rw-r--r--mysql-test/suite/versioning/r/derived.result78
-rw-r--r--mysql-test/suite/versioning/t/derived.test56
-rw-r--r--sql/sql_select.cc39
-rw-r--r--sql/sql_select.h4
4 files changed, 163 insertions, 14 deletions
diff --git a/mysql-test/suite/versioning/r/derived.result b/mysql-test/suite/versioning/r/derived.result
index 4e2e136d5bd..bc1176da175 100644
--- a/mysql-test/suite/versioning/r/derived.result
+++ b/mysql-test/suite/versioning/r/derived.result
@@ -215,5 +215,83 @@ select y from t2 for system_time as of @t1;
x
1
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 view vt1, vt2;
diff --git a/mysql-test/suite/versioning/t/derived.test b/mysql-test/suite/versioning/t/derived.test
index 5c9d0c18793..590f4bc9292 100644
--- a/mysql-test/suite/versioning/t/derived.test
+++ b/mysql-test/suite/versioning/t/derived.test
@@ -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 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 view vt1, vt2;
+
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index e0e160b45aa..184cad22f67 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -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)
{
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;
} // if (vers_conditions)
- COND** dst_cond= where_expr;
if (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);
Item *row_end=
newx Item_field(thd, &this->context, table->db, table->alias, fend);
- Item *row_end2= row_end;
bool tmp_from_ib=
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
{
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;
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:
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;
case FOR_SYSTEM_TIME_AS_OF:
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)
{
- cond1= and_items(thd,
- *dst_cond,
+ vers_cond= and_items(thd,
+ vers_cond,
and_items(thd,
cond2,
cond1));
-
- if (on_stmt_arena.arena_replaced())
- *dst_cond= cond1;
- else
- thd->change_item_tree(dst_cond, cond1);
-
- this->where= *dst_cond;
- this->where->top_level_item();
+ if (table->is_view_or_derived())
+ vers_cond= or_items(thd, vers_cond, newx Item_func_isnull(thd, row_end));
}
} // if (... table->table->versioned())
} // 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);
#undef newx
}
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 659bc4e7827..662047c02e3 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -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);
}
+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);
void optimize_wo_join_buffering(JOIN *join, uint first_tab, uint last_tab,
table_map last_remaining_tables,