Skip to content

Commit 842fdcc

Browse files
authored
fix(optimizer): fix full outer join null filter (#24899)
1 parent b95ba58 commit 842fdcc

File tree

11 files changed

+210
-84
lines changed

11 files changed

+210
-84
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# Regression test for: https://github.com/risingwavelabs/risingwave/issues/24790
2+
statement ok
3+
drop materialized view if exists t_stat;
4+
5+
statement ok
6+
drop materialized view if exists t1_v;
7+
8+
statement ok
9+
drop materialized view if exists t2_v;
10+
11+
statement ok
12+
drop table if exists t;
13+
14+
statement ok
15+
create table t (
16+
id int primary key,
17+
key string,
18+
amount int
19+
);
20+
21+
statement ok
22+
insert into t values
23+
(1, 'k', 100),
24+
(2, 'k', 200);
25+
26+
statement ok
27+
create materialized view t1_v as
28+
select sum(amount) as amount, max(key) as key
29+
from t
30+
where id = 1;
31+
32+
statement ok
33+
create materialized view t2_v as
34+
select sum(amount) as amount, max(key) as key
35+
from t
36+
where id = 2;
37+
38+
statement ok
39+
create materialized view t_stat as
40+
select
41+
coalesce(a.key, b.key) as key,
42+
coalesce(a.amount, 0) as amount_1,
43+
coalesce(b.amount, 0) as amount_2
44+
from t1_v a
45+
full outer join t2_v b
46+
on a.key = b.key;
47+
48+
statement ok
49+
flush;
50+
51+
query TII
52+
select key, amount_1, amount_2 from t_stat;
53+
----
54+
k 100 200
55+
56+
statement ok
57+
drop materialized view t_stat;
58+
59+
statement ok
60+
drop materialized view t1_v;
61+
62+
statement ok
63+
drop materialized view t2_v;
64+
65+
statement ok
66+
drop table t;
67+
68+
# Regression test for full outer join on nullable global-agg key
69+
statement ok
70+
drop materialized view if exists mvj;
71+
72+
statement ok
73+
drop materialized view if exists mv;
74+
75+
statement ok
76+
drop table if exists t;
77+
78+
statement ok
79+
create table t (a int, b int);
80+
81+
statement ok
82+
create materialized view mv as
83+
select max(a) ma, max(b) mb from t;
84+
85+
statement ok
86+
insert into t values (1, NULL);
87+
88+
statement ok
89+
flush;
90+
91+
query II
92+
select ma, mb from mv;
93+
----
94+
1 NULL
95+
96+
statement ok
97+
create materialized view mvj as
98+
select mv1.ma as ma1
99+
from mv as mv1
100+
full outer join mv as mv2
101+
on mv1.mb = mv2.mb;
102+
103+
statement ok
104+
flush;
105+
106+
query I rowsort
107+
select ma1 from mvj;
108+
----
109+
110+
statement ok
111+
drop materialized view mvj;
112+
113+
statement ok
114+
drop materialized view mv;
115+
116+
statement ok
117+
drop table t;

e2e_test/streaming/join/main.slt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ include ./join.slt.part
55
include ./join-3way.slt.part
66
include ./asof_join.slt.part
77
include ./interval_join.slt.part
8+
include ./full_outer_join_global_agg.slt.part
89

910
statement ok
1011
set streaming_join_encoding to memory_optimized;
@@ -13,6 +14,7 @@ include ./join.slt.part
1314
include ./join-3way.slt.part
1415
include ./asof_join.slt.part
1516
include ./interval_join.slt.part
17+
include ./full_outer_join_global_agg.slt.part
1618

1719
statement ok
1820
set streaming_join_encoding to default;

src/frontend/planner_test/tests/testdata/output/explain_dot_format.yaml

Lines changed: 17 additions & 17 deletions
Large diffs are not rendered by default.

src/frontend/planner_test/tests/testdata/output/explain_json_format.yaml

Lines changed: 17 additions & 17 deletions
Large diffs are not rendered by default.

src/frontend/planner_test/tests/testdata/output/explain_xml_format.yaml

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

src/frontend/planner_test/tests/testdata/output/explain_yaml_format.yaml

Lines changed: 17 additions & 17 deletions
Large diffs are not rendered by default.

src/frontend/planner_test/tests/testdata/output/join.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@
558558
└─StreamProject { exprs: [(2:Int32 * $expr1) as $expr2, ($expr1 + $expr1) as $expr3, a._row_id, b._row_id, a.x, b.x] }
559559
└─StreamProject { exprs: [a.x, b.x, Coalesce(a.x, b.x) as $expr1, a._row_id, b._row_id] }
560560
└─StreamFilter { predicate: ((2:Int32 * Coalesce(a.x, b.x)) < 10:Int32) }
561-
└─StreamFilter { predicate: (IsNotNull(a._row_id) OR IsNotNull(b._row_id)) }
561+
└─StreamFilter { predicate: ((IsNotNull(a._row_id) OR IsNotNull(b._row_id)) OR (IsNotNull(a.x) OR IsNotNull(b.x))) }
562562
└─StreamHashJoin { type: FullOuter, predicate: a.x = b.x, output: [a.x, b.x, a._row_id, b._row_id] }
563563
├─StreamExchange { dist: HashShard(a.x) }
564564
│ └─StreamTableScan { table: a, columns: [a.x, a._row_id], stream_scan_type: SnapshotBackfill, stream_key: [a._row_id], pk: [_row_id], dist: UpstreamHashShard(a._row_id) }

src/frontend/planner_test/tests/testdata/output/project.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@
107107
└─StreamProject { exprs: [$expr1, t1._row_id, t2._row_id, t1.v, t2.v] }
108108
└─StreamMaterializedExprs { exprs: [PgSleep(t1.v::Float64) as $expr1] }
109109
└─StreamExchange { dist: HashShard(t1.v, t1._row_id, t2._row_id, t2.v) }
110-
└─StreamFilter { predicate: (IsNotNull(t1._row_id) OR IsNotNull(t2._row_id)) }
110+
└─StreamFilter { predicate: ((IsNotNull(t1._row_id) OR IsNotNull(t2._row_id)) OR (IsNotNull(t1.v) OR IsNotNull(t2.v))) }
111111
└─StreamHashJoin { type: FullOuter, predicate: t1.v = t2.v, output: [t1.v, t1._row_id, t2._row_id, t2.v] }
112112
├─StreamExchange { dist: HashShard(t1.v) }
113113
│ └─StreamTableScan { table: t1, columns: [t1.v, t1._row_id], stream_scan_type: SnapshotBackfill, stream_key: [t1._row_id], pk: [_row_id], dist: UpstreamHashShard(t1._row_id) }
@@ -121,7 +121,7 @@
121121
└── StreamExchange Hash([0, 1, 2, 3]) from 1
122122
123123
Fragment 1
124-
StreamFilter { predicate: (IsNotNull(t1._row_id) OR IsNotNull(t2._row_id)) }
124+
StreamFilter { predicate: ((IsNotNull(t1._row_id) OR IsNotNull(t2._row_id)) OR (IsNotNull(t1.v) OR IsNotNull(t2.v))) }
125125
└── StreamHashJoin { type: FullOuter, predicate: t1.v = t2.v, output: [t1.v, t1._row_id, t2._row_id, t2.v] } { tables: [ HashJoinLeft: 1, HashJoinDegreeLeft: 2, HashJoinRight: 3, HashJoinDegreeRight: 4 ] }
126126
├── StreamExchange Hash([0]) from 2
127127
└── StreamExchange Hash([0]) from 3

0 commit comments

Comments
 (0)