()
| 151 | /// joined rows, not copies of one source's raw docs. |
| 152 | #[tokio::test(flavor = "multi_thread", worker_threads = 4)] |
| 153 | async fn refresh_applies_join() { |
| 154 | let server = TestServer::start().await; |
| 155 | |
| 156 | server.exec("CREATE COLLECTION mv_join_left").await.unwrap(); |
| 157 | server |
| 158 | .exec("CREATE COLLECTION mv_join_right") |
| 159 | .await |
| 160 | .unwrap(); |
| 161 | server |
| 162 | .exec("INSERT INTO mv_join_left { id: 'l1', rid: 'r1', name: 'alice' }") |
| 163 | .await |
| 164 | .unwrap(); |
| 165 | server |
| 166 | .exec("INSERT INTO mv_join_left { id: 'l2', rid: 'r2', name: 'bob' }") |
| 167 | .await |
| 168 | .unwrap(); |
| 169 | server |
| 170 | .exec("INSERT INTO mv_join_right { id: 'r1', tag: 'vip' }") |
| 171 | .await |
| 172 | .unwrap(); |
| 173 | // Deliberately no match for l2 — an INNER JOIN must drop it. |
| 174 | |
| 175 | server |
| 176 | .exec( |
| 177 | "CREATE MATERIALIZED VIEW mv_join ON mv_join_left AS \ |
| 178 | SELECT l.id AS id, r.tag AS tag \ |
| 179 | FROM mv_join_left l JOIN mv_join_right r ON l.rid = r.id", |
| 180 | ) |
| 181 | .await |
| 182 | .unwrap(); |
| 183 | server |
| 184 | .exec("REFRESH MATERIALIZED VIEW mv_join") |
| 185 | .await |
| 186 | .unwrap(); |
| 187 | |
| 188 | let rows = server |
| 189 | .query_named_rows("SELECT * FROM mv_join") |
| 190 | .await |
| 191 | .unwrap(); |
| 192 | assert_eq!( |
| 193 | rows.len(), |
| 194 | 1, |
| 195 | "INNER JOIN view must materialize only the matched pair, got {rows:?}" |
| 196 | ); |
| 197 | } |
| 198 | |
| 199 | /// When the view's WHERE predicate narrows the source, a subsequent refresh |
| 200 | /// must remove view rows that no longer match. |
nothing calls this directly
no test coverage detected