outer_join_lowering.slt 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992
  1. # Copyright Materialize, Inc. and contributors. All rights reserved.
  2. #
  3. # Use of this software is governed by the Business Source License
  4. # included in the LICENSE file at the root of this repository.
  5. #
  6. # As of the Change Date specified in that file, in accordance with
  7. # the Business Source License, use of this software will be governed
  8. # by the Apache License, Version 2.0.
  9. mode cockroach
  10. simple conn=mz_system,user=mz_system
  11. ALTER SYSTEM SET enable_new_outer_join_lowering TO true;
  12. ----
  13. COMPLETE 0
  14. statement ok
  15. DROP SCHEMA IF EXISTS left_joins_raw CASCADE;
  16. statement ok
  17. DROP SCHEMA IF EXISTS left_joins CASCADE;
  18. statement ok
  19. CREATE SCHEMA left_joins_raw;
  20. statement ok
  21. CREATE SCHEMA left_joins;
  22. statement ok
  23. CREATE TABLE left_joins_raw.outer(
  24. x int not null,
  25. y int not null
  26. );
  27. statement ok
  28. CREATE MATERIALIZED VIEW left_joins.outer AS
  29. SELECT DISTINCT ON(x, y) * FROM left_joins_raw.outer;
  30. statement ok
  31. CREATE TABLE left_joins_raw.facts(
  32. facts_k01 int not null,
  33. dim01_k01 int,
  34. dim02_k01 int,
  35. dim03_k01 int,
  36. facts_d01 int,
  37. facts_d02 int,
  38. facts_d03 int,
  39. facts_d04 int,
  40. facts_d05 int
  41. );
  42. statement ok
  43. CREATE MATERIALIZED VIEW left_joins.facts AS
  44. SELECT DISTINCT ON(facts_k01) * FROM left_joins_raw.facts;
  45. statement ok
  46. CREATE TABLE left_joins_raw.dim01(
  47. dim01_k01 int,
  48. dim01_d01 int,
  49. dim01_d02 int,
  50. dim01_d03 int,
  51. dim01_d04 int,
  52. dim01_d05 int
  53. );
  54. statement ok
  55. CREATE MATERIALIZED VIEW left_joins.dim01 AS
  56. SELECT DISTINCT ON(dim01_k01) * FROM left_joins_raw.dim01;
  57. statement ok
  58. CREATE TABLE left_joins_raw.dim02(
  59. dim02_k01 int,
  60. dim02_d01 int,
  61. dim02_d02 int,
  62. dim02_d03 int,
  63. dim02_d04 int,
  64. dim02_d05 int
  65. );
  66. statement ok
  67. CREATE MATERIALIZED VIEW left_joins.dim02 AS
  68. SELECT DISTINCT ON(dim02_k01) * FROM left_joins_raw.dim02;
  69. # A fallback lowering strategy for outer joins with theta-join ON predicates.
  70. #
  71. # The "outer" part is characterized by:
  72. # 1. A `Union`/`Negate` of two `Distinct` with fat `group_by` keys.
  73. # 2. An equi-join with the preserving side with a fat `on` predicate.
  74. #
  75. # Simplification opportunities:
  76. # - The `Distinct` nodes from (1) can be removed by `ReduceElision`.
  77. # - The `Join` from (2) can be removed by `RedundantJoin`.
  78. #
  79. # Applying the optimization above depends on unique key information.
  80. #
  81. # Projection pushdown is blocked unless the `Join` is removed.
  82. query T multiline
  83. EXPLAIN DECORRELATED PLAN WITH(humanized expressions, arity) FOR
  84. SELECT
  85. facts.facts_k01,
  86. facts.facts_d01,
  87. facts.dim01_k01,
  88. dim01.dim01_d01
  89. FROM
  90. left_joins_raw.facts LEFT JOIN
  91. left_joins_raw.dim01 ON(facts.dim01_k01 > dim01.dim01_k01);
  92. ----
  93. With
  94. cte l0 =
  95. CrossJoin // { arity: 9 }
  96. Constant // { arity: 0 }
  97. - ()
  98. Get materialize.left_joins_raw.facts // { arity: 9 }
  99. cte l1 =
  100. Filter (#1{dim01_k01} > #9{dim01_k01}) // { arity: 15 }
  101. Project (#0{facts_k01}..=#14{dim01_d05}) // { arity: 15 }
  102. CrossJoin // { arity: 15 }
  103. Get l0 // { arity: 9 }
  104. CrossJoin // { arity: 6 }
  105. Constant // { arity: 0 }
  106. - ()
  107. Get materialize.left_joins_raw.dim01 // { arity: 6 }
  108. Return // { arity: 4 }
  109. Project (#0{facts_k01}, #4{facts_d01}, #1{dim01_k01}, #10{dim01_d01}) // { arity: 4 }
  110. Union // { arity: 15 }
  111. Get l1 // { arity: 15 }
  112. CrossJoin // { arity: 15 }
  113. Project (#0{facts_k01}..=#8{facts_d05}) // { arity: 9 }
  114. Join on=(#0{facts_k01} = #9{facts_k01} AND #1{dim01_k01} = #10{dim01_k01} AND #2{dim02_k01} = #11{dim02_k01} AND #3{dim03_k01} = #12{dim03_k01} AND #4{facts_d01} = #13{facts_d01} AND #5{facts_d02} = #14{facts_d02} AND #6{facts_d03} = #15{facts_d03} AND #7{facts_d04} = #16{facts_d04} AND #8{facts_d05} = #17{facts_d05}) // { arity: 18 }
  115. Union // { arity: 9 }
  116. Negate // { arity: 9 }
  117. Distinct project=[#0{facts_k01}..=#8{facts_d05}] // { arity: 9 }
  118. Get l1 // { arity: 15 }
  119. Distinct project=[#0{facts_k01}..=#8{facts_d05}] // { arity: 9 }
  120. Get l0 // { arity: 9 }
  121. Get l0 // { arity: 9 }
  122. Constant // { arity: 6 }
  123. - (null, null, null, null, null, null)
  124. Target cluster: quickstart
  125. EOF
  126. # An optimized lowering strategy for outer joins with equijoin ON predicates.
  127. #
  128. # The "outer" part is characterized by:
  129. # 1. A semijoin between the inner result (l1) and the preserving side (l0).
  130. # 2. An antijoin of l0 w.r.t. this semijoin.
  131. #
  132. # Simplification opportunities:
  133. # - The semijoin from (1) can be removed by `SemijoinIdempotence`.
  134. #
  135. # Applying the optimization above depends on unique key information.
  136. #
  137. # Projection pushdown is always possible.
  138. query T multiline
  139. EXPLAIN DECORRELATED PLAN WITH(humanized expressions, arity) FOR
  140. SELECT
  141. facts.facts_k01,
  142. facts.facts_d01,
  143. facts.dim01_k01,
  144. dim01.dim01_d01
  145. FROM
  146. left_joins_raw.facts LEFT JOIN
  147. left_joins_raw.dim01 ON(facts.dim01_k01 = dim01.dim01_k01);
  148. ----
  149. With
  150. cte l0 =
  151. CrossJoin // { arity: 9 }
  152. Constant // { arity: 0 }
  153. - ()
  154. Get materialize.left_joins_raw.facts // { arity: 9 }
  155. cte l1 =
  156. Filter (#1{dim01_k01} = #9{dim01_k01}) // { arity: 15 }
  157. Project (#0{facts_k01}..=#14{dim01_d05}) // { arity: 15 }
  158. CrossJoin // { arity: 15 }
  159. Get l0 // { arity: 9 }
  160. CrossJoin // { arity: 6 }
  161. Constant // { arity: 0 }
  162. - ()
  163. Get materialize.left_joins_raw.dim01 // { arity: 6 }
  164. Return // { arity: 4 }
  165. Project (#0{facts_k01}, #4{facts_d01}, #1{dim01_k01}, #10{dim01_d01}) // { arity: 4 }
  166. Union // { arity: 15 }
  167. Map (null, null, null, null, null, null) // { arity: 15 }
  168. Union // { arity: 9 }
  169. Negate // { arity: 9 }
  170. Project (#0{facts_k01}..=#8{facts_d05}) // { arity: 9 }
  171. Join on=(#1{dim01_k01} = #9{dim01_k01}) // { arity: 10 }
  172. Filter (#1{dim01_k01}) IS NOT NULL // { arity: 9 }
  173. Get l0 // { arity: 9 }
  174. Distinct project=[#0{dim01_k01}] // { arity: 1 }
  175. Project (#1{dim01_k01}) // { arity: 1 }
  176. Get l1 // { arity: 15 }
  177. Get l0 // { arity: 9 }
  178. Get l1 // { arity: 15 }
  179. Target cluster: quickstart
  180. EOF
  181. # ON predicates with non-trivial equi-join conjuncts were previously planned using
  182. # the fallback lowering strategy.
  183. query T multiline
  184. EXPLAIN DECORRELATED PLAN WITH(enable new outer join lowering = false, humanized expressions, arity) FOR
  185. SELECT * FROM left_joins.outer CROSS JOIN LATERAL (
  186. SELECT
  187. facts.facts_k01,
  188. facts.facts_d01,
  189. facts.dim01_k01,
  190. dim01.dim01_d01
  191. FROM
  192. left_joins_raw.facts LEFT JOIN
  193. left_joins_raw.dim01 ON(facts.dim01_k01 + x = dim01.dim01_k01 + y)
  194. );
  195. ----
  196. With
  197. cte l0 =
  198. CrossJoin // { arity: 2 }
  199. Constant // { arity: 0 }
  200. - ()
  201. Get materialize.left_joins.outer // { arity: 2 }
  202. cte l1 =
  203. Distinct project=[#0{x}, #1{y}] // { arity: 2 }
  204. Get l0 // { arity: 2 }
  205. cte l2 =
  206. CrossJoin // { arity: 11 }
  207. Get l1 // { arity: 2 }
  208. Get materialize.left_joins_raw.facts // { arity: 9 }
  209. cte l3 =
  210. Filter ((#3{dim01_k01} + #0{x}) = (#11{dim01_k01} + #1{y})) // { arity: 17 }
  211. Project (#0{x}..=#10{facts_d05}, #13{dim01_k01}..=#18{dim01_d05}) // { arity: 17 }
  212. Join on=(#0{x} = #11{x} AND #1{y} = #12{y}) // { arity: 19 }
  213. Get l2 // { arity: 11 }
  214. CrossJoin // { arity: 8 }
  215. Get l1 // { arity: 2 }
  216. Get materialize.left_joins_raw.dim01 // { arity: 6 }
  217. Return // { arity: 6 }
  218. Project (#0{x}, #1{y}, #4{facts_k01}..=#7{dim01_d01}) // { arity: 6 }
  219. Join on=(#0{x} = #2{x} AND #1{y} = #3{y}) // { arity: 8 }
  220. Get l0 // { arity: 2 }
  221. Project (#0{x}..=#2{facts_k01}, #6{facts_d01}, #3{dim01_k01}, #12{dim01_d01}) // { arity: 6 }
  222. Union // { arity: 17 }
  223. Get l3 // { arity: 17 }
  224. CrossJoin // { arity: 17 }
  225. Project (#0{x}..=#10{facts_d05}) // { arity: 11 }
  226. Join on=(#0{x} = #11{x} AND #1{y} = #12{y} AND #2{facts_k01} = #13{facts_k01} AND #3{dim01_k01} = #14{dim01_k01} AND #4{dim02_k01} = #15{dim02_k01} AND #5{dim03_k01} = #16{dim03_k01} AND #6{facts_d01} = #17{facts_d01} AND #7{facts_d02} = #18{facts_d02} AND #8{facts_d03} = #19{facts_d03} AND #9{facts_d04} = #20{facts_d04} AND #10{facts_d05} = #21{facts_d05}) // { arity: 22 }
  227. Union // { arity: 11 }
  228. Negate // { arity: 11 }
  229. Distinct project=[#0{x}..=#10{facts_d05}] // { arity: 11 }
  230. Get l3 // { arity: 17 }
  231. Distinct project=[#0{x}..=#10{facts_d05}] // { arity: 11 }
  232. Get l2 // { arity: 11 }
  233. Get l2 // { arity: 11 }
  234. Constant // { arity: 6 }
  235. - (null, null, null, null, null, null)
  236. Target cluster: quickstart
  237. EOF
  238. # ON predicates with non-trivial equi-join conjuncts are planned using the
  239. # optimized lowering strategy.
  240. query T multiline
  241. EXPLAIN DECORRELATED PLAN WITH(humanized expressions, arity) FOR
  242. SELECT * FROM left_joins.outer CROSS JOIN LATERAL (
  243. SELECT
  244. facts.facts_k01,
  245. facts.facts_d01,
  246. facts.dim01_k01,
  247. dim01.dim01_d01
  248. FROM
  249. left_joins_raw.facts LEFT JOIN
  250. left_joins_raw.dim01 ON(facts.dim01_k01 + x = dim01.dim01_k01 + y)
  251. );
  252. ----
  253. With
  254. cte l0 =
  255. CrossJoin // { arity: 2 }
  256. Constant // { arity: 0 }
  257. - ()
  258. Get materialize.left_joins.outer // { arity: 2 }
  259. cte l1 =
  260. Distinct project=[#0{x}, #1{y}] // { arity: 2 }
  261. Get l0 // { arity: 2 }
  262. cte l2 =
  263. CrossJoin // { arity: 11 }
  264. Get l1 // { arity: 2 }
  265. Get materialize.left_joins_raw.facts // { arity: 9 }
  266. cte l3 =
  267. Filter ((#3{dim01_k01} + #0{x}) = (#11{dim01_k01} + #1{y})) // { arity: 17 }
  268. Project (#0{x}..=#10{facts_d05}, #13{dim01_k01}..=#18{dim01_d05}) // { arity: 17 }
  269. Join on=(#0{x} = #11{x} AND #1{y} = #12{y}) // { arity: 19 }
  270. Get l2 // { arity: 11 }
  271. CrossJoin // { arity: 8 }
  272. Get l1 // { arity: 2 }
  273. Get materialize.left_joins_raw.dim01 // { arity: 6 }
  274. Return // { arity: 6 }
  275. Project (#0{x}, #1{y}, #4{facts_k01}..=#7{dim01_d01}) // { arity: 6 }
  276. Join on=(#0{x} = #2{x} AND #1{y} = #3{y}) // { arity: 8 }
  277. Get l0 // { arity: 2 }
  278. Project (#0{x}..=#2{facts_k01}, #6{facts_d01}, #3{dim01_k01}, #12{dim01_d01}) // { arity: 6 }
  279. Union // { arity: 17 }
  280. Map (null, null, null, null, null, null) // { arity: 17 }
  281. Union // { arity: 11 }
  282. Negate // { arity: 11 }
  283. Project (#0{x}..=#10{facts_d05}) // { arity: 11 }
  284. Join on=(#0{x} = #11{x} AND #1{y} = #12{y} AND (#3{dim01_k01} + #0{x}) = #13) // { arity: 14 }
  285. Filter ((#3{dim01_k01} + #0{x})) IS NOT NULL // { arity: 11 }
  286. Get l2 // { arity: 11 }
  287. Distinct project=[#0{x}..=#2] // { arity: 3 }
  288. Project (#17{x}..=#19) // { arity: 3 }
  289. Map (#0{x}, #1{y}, (#3{dim01_k01} + #0{x})) // { arity: 20 }
  290. Get l3 // { arity: 17 }
  291. Get l2 // { arity: 11 }
  292. Get l3 // { arity: 17 }
  293. Target cluster: quickstart
  294. EOF
  295. # ON predicates with non-trivial equi-join conjuncts are planned using the
  296. # optimized lowering strategy. Same as above, but a RIGHT JOIN.
  297. query T multiline
  298. EXPLAIN DECORRELATED PLAN WITH(humanized expressions, arity) FOR
  299. SELECT * FROM left_joins.outer CROSS JOIN LATERAL (
  300. SELECT
  301. facts.facts_k01,
  302. facts.facts_d01,
  303. facts.dim01_k01,
  304. dim01.dim01_d01
  305. FROM
  306. left_joins_raw.dim01 RIGHT JOIN
  307. left_joins_raw.facts ON(facts.dim01_k01 + x = dim01.dim01_k01 + y)
  308. );
  309. ----
  310. With
  311. cte l0 =
  312. CrossJoin // { arity: 2 }
  313. Constant // { arity: 0 }
  314. - ()
  315. Get materialize.left_joins.outer // { arity: 2 }
  316. cte l1 =
  317. Distinct project=[#0{x}, #1{y}] // { arity: 2 }
  318. Get l0 // { arity: 2 }
  319. cte l2 =
  320. CrossJoin // { arity: 11 }
  321. Get l1 // { arity: 2 }
  322. Get materialize.left_joins_raw.facts // { arity: 9 }
  323. cte l3 =
  324. Filter ((#2{dim01_k01} + #1{y}) = (#9{dim01_k01} + #0{x})) // { arity: 17 }
  325. Project (#0{x}..=#7{dim01_d05}, #10{facts_k01}..=#18{facts_d05}) // { arity: 17 }
  326. Join on=(#0{x} = #8{x} AND #1{y} = #9{y}) // { arity: 19 }
  327. CrossJoin // { arity: 8 }
  328. Get l1 // { arity: 2 }
  329. Get materialize.left_joins_raw.dim01 // { arity: 6 }
  330. Get l2 // { arity: 11 }
  331. Return // { arity: 6 }
  332. Project (#0{x}, #1{y}, #4{facts_k01}..=#7{dim01_d01}) // { arity: 6 }
  333. Join on=(#0{x} = #2{x} AND #1{y} = #3{y}) // { arity: 8 }
  334. Get l0 // { arity: 2 }
  335. Project (#0{x}, #1{y}, #8{facts_k01}, #12{facts_d01}, #9{dim01_k01}, #3{dim01_d01}) // { arity: 6 }
  336. Union // { arity: 17 }
  337. Project (#0{x}, #1{y}, #11..=#16, #2{facts_k01}..=#10{facts_d05}) // { arity: 17 }
  338. Map (null, null, null, null, null, null) // { arity: 17 }
  339. Union // { arity: 11 }
  340. Negate // { arity: 11 }
  341. Project (#0{x}..=#10{facts_d05}) // { arity: 11 }
  342. Join on=(#0{x} = #11{x} AND #1{y} = #12{y} AND (#3{dim01_k01} + #0{x}) = #13) // { arity: 14 }
  343. Filter ((#3{dim01_k01} + #0{x})) IS NOT NULL // { arity: 11 }
  344. Get l2 // { arity: 11 }
  345. Distinct project=[#0{x}..=#2] // { arity: 3 }
  346. Project (#17{x}..=#19) // { arity: 3 }
  347. Map (#0{x}, #1{y}, (#2{dim01_k01} + #1{y})) // { arity: 20 }
  348. Get l3 // { arity: 17 }
  349. Get l2 // { arity: 11 }
  350. Get l3 // { arity: 17 }
  351. Target cluster: quickstart
  352. EOF
  353. # ON predicates with at least one equi-join conjunct were previouisly planned
  354. # using the fallback lowering strategy.
  355. query T multiline
  356. EXPLAIN DECORRELATED PLAN WITH(enable new outer join lowering = false, humanized expressions, arity) FOR
  357. SELECT * FROM left_joins.outer CROSS JOIN LATERAL (
  358. SELECT
  359. facts.facts_k01,
  360. facts.facts_d01,
  361. facts.dim01_k01,
  362. dim01.dim01_d01
  363. FROM
  364. left_joins_raw.facts LEFT JOIN
  365. left_joins_raw.dim01 ON(
  366. facts.dim01_k01 + x = dim01.dim01_k01 + y AND
  367. facts_d02 = 42 AND
  368. dim01_d02 = 24
  369. )
  370. );
  371. ----
  372. With
  373. cte l0 =
  374. CrossJoin // { arity: 2 }
  375. Constant // { arity: 0 }
  376. - ()
  377. Get materialize.left_joins.outer // { arity: 2 }
  378. cte l1 =
  379. Distinct project=[#0{x}, #1{y}] // { arity: 2 }
  380. Get l0 // { arity: 2 }
  381. cte l2 =
  382. CrossJoin // { arity: 11 }
  383. Get l1 // { arity: 2 }
  384. Get materialize.left_joins_raw.facts // { arity: 9 }
  385. cte l3 =
  386. Filter ((((#3{dim01_k01} + #0{x}) = (#11{dim01_k01} + #1{y})) AND (#7{facts_d02} = 42)) AND (#13{dim01_d02} = 24)) // { arity: 17 }
  387. Project (#0{x}..=#10{facts_d05}, #13{dim01_k01}..=#18{dim01_d05}) // { arity: 17 }
  388. Join on=(#0{x} = #11{x} AND #1{y} = #12{y}) // { arity: 19 }
  389. Get l2 // { arity: 11 }
  390. CrossJoin // { arity: 8 }
  391. Get l1 // { arity: 2 }
  392. Get materialize.left_joins_raw.dim01 // { arity: 6 }
  393. Return // { arity: 6 }
  394. Project (#0{x}, #1{y}, #4{facts_k01}..=#7{dim01_d01}) // { arity: 6 }
  395. Join on=(#0{x} = #2{x} AND #1{y} = #3{y}) // { arity: 8 }
  396. Get l0 // { arity: 2 }
  397. Project (#0{x}..=#2{facts_k01}, #6{facts_d01}, #3{dim01_k01}, #12{dim01_d01}) // { arity: 6 }
  398. Union // { arity: 17 }
  399. Get l3 // { arity: 17 }
  400. CrossJoin // { arity: 17 }
  401. Project (#0{x}..=#10{facts_d05}) // { arity: 11 }
  402. Join on=(#0{x} = #11{x} AND #1{y} = #12{y} AND #2{facts_k01} = #13{facts_k01} AND #3{dim01_k01} = #14{dim01_k01} AND #4{dim02_k01} = #15{dim02_k01} AND #5{dim03_k01} = #16{dim03_k01} AND #6{facts_d01} = #17{facts_d01} AND #7{facts_d02} = #18{facts_d02} AND #8{facts_d03} = #19{facts_d03} AND #9{facts_d04} = #20{facts_d04} AND #10{facts_d05} = #21{facts_d05}) // { arity: 22 }
  403. Union // { arity: 11 }
  404. Negate // { arity: 11 }
  405. Distinct project=[#0{x}..=#10{facts_d05}] // { arity: 11 }
  406. Get l3 // { arity: 17 }
  407. Distinct project=[#0{x}..=#10{facts_d05}] // { arity: 11 }
  408. Get l2 // { arity: 11 }
  409. Get l2 // { arity: 11 }
  410. Constant // { arity: 6 }
  411. - (null, null, null, null, null, null)
  412. Target cluster: quickstart
  413. EOF
  414. # ON predicates with at least one equi-join conjunct are planned using the
  415. # optimized lowering strategy.
  416. query T multiline
  417. EXPLAIN DECORRELATED PLAN WITH(humanized expressions, arity) FOR
  418. SELECT * FROM left_joins.outer CROSS JOIN LATERAL (
  419. SELECT
  420. facts.facts_k01,
  421. facts.facts_d01,
  422. facts.dim01_k01,
  423. dim01.dim01_d01
  424. FROM
  425. left_joins_raw.facts LEFT JOIN
  426. left_joins_raw.dim01 ON(
  427. facts.dim01_k01 + x = dim01.dim01_k01 + y AND
  428. facts_d02 = 42 AND
  429. dim01_d02 = 24
  430. )
  431. );
  432. ----
  433. With
  434. cte l0 =
  435. CrossJoin // { arity: 2 }
  436. Constant // { arity: 0 }
  437. - ()
  438. Get materialize.left_joins.outer // { arity: 2 }
  439. cte l1 =
  440. Distinct project=[#0{x}, #1{y}] // { arity: 2 }
  441. Get l0 // { arity: 2 }
  442. cte l2 =
  443. CrossJoin // { arity: 11 }
  444. Get l1 // { arity: 2 }
  445. Get materialize.left_joins_raw.facts // { arity: 9 }
  446. cte l3 =
  447. Filter (#7{facts_d02} = 42) AND (#13{dim01_d02} = 24) AND ((#3{dim01_k01} + #0{x}) = (#11{dim01_k01} + #1{y})) // { arity: 17 }
  448. Project (#0{x}..=#10{facts_d05}, #13{dim01_k01}..=#18{dim01_d05}) // { arity: 17 }
  449. Join on=(#0{x} = #11{x} AND #1{y} = #12{y}) // { arity: 19 }
  450. Get l2 // { arity: 11 }
  451. CrossJoin // { arity: 8 }
  452. Get l1 // { arity: 2 }
  453. Get materialize.left_joins_raw.dim01 // { arity: 6 }
  454. Return // { arity: 6 }
  455. Project (#0{x}, #1{y}, #4{facts_k01}..=#7{dim01_d01}) // { arity: 6 }
  456. Join on=(#0{x} = #2{x} AND #1{y} = #3{y}) // { arity: 8 }
  457. Get l0 // { arity: 2 }
  458. Project (#0{x}..=#2{facts_k01}, #6{facts_d01}, #3{dim01_k01}, #12{dim01_d01}) // { arity: 6 }
  459. Union // { arity: 17 }
  460. Map (null, null, null, null, null, null) // { arity: 17 }
  461. Union // { arity: 11 }
  462. Negate // { arity: 11 }
  463. Project (#0{x}..=#10{facts_d05}) // { arity: 11 }
  464. Join on=(#0{x} = #11{x} AND #1{y} = #12{y} AND (#3{dim01_k01} + #0{x}) = #13) // { arity: 14 }
  465. Filter ((#3{dim01_k01} + #0{x})) IS NOT NULL AND (#7{facts_d02} = 42) // { arity: 11 }
  466. Get l2 // { arity: 11 }
  467. Distinct project=[#0{x}..=#2] // { arity: 3 }
  468. Project (#17{x}..=#19) // { arity: 3 }
  469. Map (#0{x}, #1{y}, (#3{dim01_k01} + #0{x})) // { arity: 20 }
  470. Get l3 // { arity: 17 }
  471. Get l2 // { arity: 11 }
  472. Get l3 // { arity: 17 }
  473. Target cluster: quickstart
  474. EOF
  475. # ON predicates with at least one equi-join conjunct are planned using the
  476. # optimized lowering strategy. Same as above, but a RIGHT JOIN.
  477. query T multiline
  478. EXPLAIN DECORRELATED PLAN WITH(humanized expressions, arity) FOR
  479. SELECT * FROM left_joins.outer CROSS JOIN LATERAL (
  480. SELECT
  481. facts.facts_k01,
  482. facts.facts_d01,
  483. facts.dim01_k01,
  484. dim01.dim01_d01
  485. FROM
  486. left_joins_raw.dim01 RIGHT JOIN
  487. left_joins_raw.facts ON(
  488. facts.dim01_k01 + x = dim01.dim01_k01 + y AND
  489. facts_d02 = 42 AND
  490. dim01_d02 = 24
  491. )
  492. );
  493. ----
  494. With
  495. cte l0 =
  496. CrossJoin // { arity: 2 }
  497. Constant // { arity: 0 }
  498. - ()
  499. Get materialize.left_joins.outer // { arity: 2 }
  500. cte l1 =
  501. Distinct project=[#0{x}, #1{y}] // { arity: 2 }
  502. Get l0 // { arity: 2 }
  503. cte l2 =
  504. CrossJoin // { arity: 11 }
  505. Get l1 // { arity: 2 }
  506. Get materialize.left_joins_raw.facts // { arity: 9 }
  507. cte l3 =
  508. Filter (#4{dim01_d02} = 24) AND (#13{facts_d02} = 42) AND ((#2{dim01_k01} + #1{y}) = (#9{dim01_k01} + #0{x})) // { arity: 17 }
  509. Project (#0{x}..=#7{dim01_d05}, #10{facts_k01}..=#18{facts_d05}) // { arity: 17 }
  510. Join on=(#0{x} = #8{x} AND #1{y} = #9{y}) // { arity: 19 }
  511. CrossJoin // { arity: 8 }
  512. Get l1 // { arity: 2 }
  513. Get materialize.left_joins_raw.dim01 // { arity: 6 }
  514. Get l2 // { arity: 11 }
  515. Return // { arity: 6 }
  516. Project (#0{x}, #1{y}, #4{facts_k01}..=#7{dim01_d01}) // { arity: 6 }
  517. Join on=(#0{x} = #2{x} AND #1{y} = #3{y}) // { arity: 8 }
  518. Get l0 // { arity: 2 }
  519. Project (#0{x}, #1{y}, #8{facts_k01}, #12{facts_d01}, #9{dim01_k01}, #3{dim01_d01}) // { arity: 6 }
  520. Union // { arity: 17 }
  521. Project (#0{x}, #1{y}, #11..=#16, #2{facts_k01}..=#10{facts_d05}) // { arity: 17 }
  522. Map (null, null, null, null, null, null) // { arity: 17 }
  523. Union // { arity: 11 }
  524. Negate // { arity: 11 }
  525. Project (#0{x}..=#10{facts_d05}) // { arity: 11 }
  526. Join on=(#0{x} = #11{x} AND #1{y} = #12{y} AND (#3{dim01_k01} + #0{x}) = #13) // { arity: 14 }
  527. Filter ((#3{dim01_k01} + #0{x})) IS NOT NULL AND (#7{facts_d02} = 42) // { arity: 11 }
  528. Get l2 // { arity: 11 }
  529. Distinct project=[#0{x}..=#2] // { arity: 3 }
  530. Project (#17{x}..=#19) // { arity: 3 }
  531. Map (#0{x}, #1{y}, (#2{dim01_k01} + #1{y})) // { arity: 20 }
  532. Get l3 // { arity: 17 }
  533. Get l2 // { arity: 11 }
  534. Get l3 // { arity: 17 }
  535. Target cluster: quickstart
  536. EOF
  537. # ON predicates with non-trivial equi-join conjuncts and local predicates are
  538. # planned using the optimized lowering strategy (FULL OUTER JOIN).
  539. query T multiline
  540. EXPLAIN DECORRELATED PLAN WITH(humanized expressions, arity) FOR
  541. SELECT * FROM left_joins.outer CROSS JOIN LATERAL (
  542. SELECT
  543. dim01_k01,
  544. dim01_k01,
  545. dim02_d02,
  546. dim02_d02
  547. FROM
  548. left_joins_raw.dim01 FULL OUTER JOIN
  549. left_joins_raw.dim02 ON(
  550. coalesce(dim01_k01, x) = coalesce(dim02_k01, y) AND
  551. dim01_d03 > 42 AND dim02_d03 < 24
  552. )
  553. );
  554. ----
  555. With
  556. cte l0 =
  557. CrossJoin // { arity: 2 }
  558. Constant // { arity: 0 }
  559. - ()
  560. Get materialize.left_joins.outer // { arity: 2 }
  561. cte l1 =
  562. Distinct project=[#0{x}, #1{y}] // { arity: 2 }
  563. Get l0 // { arity: 2 }
  564. cte l2 =
  565. CrossJoin // { arity: 8 }
  566. Get l1 // { arity: 2 }
  567. Get materialize.left_joins_raw.dim01 // { arity: 6 }
  568. cte l3 =
  569. CrossJoin // { arity: 8 }
  570. Get l1 // { arity: 2 }
  571. Get materialize.left_joins_raw.dim02 // { arity: 6 }
  572. cte l4 =
  573. Filter (coalesce(#2{dim01_k01}, #0{x}) = coalesce(#8{dim02_k01}, #1{y})) AND (#11{dim02_d03} < 24) AND (#5{dim01_d03} > 42) // { arity: 14 }
  574. Project (#0{x}..=#7{dim01_d05}, #10{dim02_k01}..=#15{dim02_d05}) // { arity: 14 }
  575. Join on=(#0{x} = #8{x} AND #1{y} = #9{y}) // { arity: 16 }
  576. Get l2 // { arity: 8 }
  577. Get l3 // { arity: 8 }
  578. cte l5 =
  579. Distinct project=[#0{x}..=#2] // { arity: 3 }
  580. Project (#14{x}..=#16) // { arity: 3 }
  581. Map (#0{x}, #1{y}, coalesce(#2{dim01_k01}, #0{x})) // { arity: 17 }
  582. Get l4 // { arity: 14 }
  583. Return // { arity: 6 }
  584. Project (#0{x}, #1{y}, #4{dim01_k01}..=#7{dim02_d02}) // { arity: 6 }
  585. Join on=(#0{x} = #2{x} AND #1{y} = #3{y}) // { arity: 8 }
  586. Get l0 // { arity: 2 }
  587. Project (#0{x}..=#2{dim01_k01}, #2{dim01_k01}, #10{dim02_d02}, #10{dim02_d02}) // { arity: 6 }
  588. Union // { arity: 14 }
  589. Project (#0{x}, #1{y}, #8..=#13, #2{dim02_k01}..=#7{dim02_d05}) // { arity: 14 }
  590. Map (null, null, null, null, null, null) // { arity: 14 }
  591. Union // { arity: 8 }
  592. Negate // { arity: 8 }
  593. Project (#0{x}..=#7{dim02_d05}) // { arity: 8 }
  594. Join on=(#0{x} = #8{x} AND #1{y} = #9{y} AND coalesce(#2{dim02_k01}, #1{y}) = #10) // { arity: 11 }
  595. Filter (coalesce(#2{dim02_k01}, #1{y})) IS NOT NULL AND (#5{dim02_d03} < 24) // { arity: 8 }
  596. Get l3 // { arity: 8 }
  597. Get l5 // { arity: 3 }
  598. Get l3 // { arity: 8 }
  599. Map (null, null, null, null, null, null) // { arity: 14 }
  600. Union // { arity: 8 }
  601. Negate // { arity: 8 }
  602. Project (#0{x}..=#7{dim01_d05}) // { arity: 8 }
  603. Join on=(#0{x} = #8{x} AND #1{y} = #9{y} AND coalesce(#2{dim01_k01}, #0{x}) = #10) // { arity: 11 }
  604. Filter (coalesce(#2{dim01_k01}, #0{x})) IS NOT NULL AND (#5{dim01_d03} > 42) // { arity: 8 }
  605. Get l2 // { arity: 8 }
  606. Get l5 // { arity: 3 }
  607. Get l2 // { arity: 8 }
  608. Get l4 // { arity: 14 }
  609. Target cluster: quickstart
  610. EOF
  611. # ON predicates with subqueries are still planned using the fallback lowering
  612. # strategy.
  613. query T multiline
  614. EXPLAIN DECORRELATED PLAN WITH(humanized expressions, arity) FOR
  615. SELECT * FROM left_joins.outer CROSS JOIN LATERAL (
  616. SELECT
  617. facts.facts_k01,
  618. facts.facts_d01,
  619. facts.dim01_k01,
  620. dim01.dim01_d01
  621. FROM
  622. left_joins_raw.facts LEFT JOIN
  623. left_joins_raw.dim01 ON(
  624. facts.dim01_k01 + x = dim01.dim01_k01 + y AND
  625. facts_d02 = 42 AND
  626. dim01_d01 = ANY('{24, 42}'::int[])
  627. )
  628. );
  629. ----
  630. With
  631. cte l0 =
  632. CrossJoin // { arity: 2 }
  633. Constant // { arity: 0 }
  634. - ()
  635. Get materialize.left_joins.outer // { arity: 2 }
  636. cte l1 =
  637. Distinct project=[#0{x}, #1{y}] // { arity: 2 }
  638. Get l0 // { arity: 2 }
  639. cte l2 =
  640. CrossJoin // { arity: 11 }
  641. Get l1 // { arity: 2 }
  642. Get materialize.left_joins_raw.facts // { arity: 9 }
  643. cte l3 =
  644. Project (#0{x}..=#10{facts_d05}, #13{dim01_k01}..=#18{dim01_d05}) // { arity: 17 }
  645. Join on=(#0{x} = #11{x} AND #1{y} = #12{y}) // { arity: 19 }
  646. Get l2 // { arity: 11 }
  647. CrossJoin // { arity: 8 }
  648. Get l1 // { arity: 2 }
  649. Get materialize.left_joins_raw.dim01 // { arity: 6 }
  650. cte l4 =
  651. Distinct project=[#12{dim01_d01}] // { arity: 1 }
  652. Get l3 // { arity: 17 }
  653. cte l5 =
  654. Reduce group_by=[#0{dim01_d01}] aggregates=[any((#0{dim01_d01} = #1{right_col0_0}))] // { arity: 2 }
  655. FlatMap unnest_array(strtoarray("{24, 42}")) // { arity: 2 }
  656. Get l4 // { arity: 1 }
  657. cte l6 =
  658. Union // { arity: 2 }
  659. Get l5 // { arity: 2 }
  660. CrossJoin // { arity: 2 }
  661. Project (#0{dim01_d01}) // { arity: 1 }
  662. Join on=(#0{dim01_d01} = #1{dim01_d01}) // { arity: 2 }
  663. Union // { arity: 1 }
  664. Negate // { arity: 1 }
  665. Distinct project=[#0{dim01_d01}] // { arity: 1 }
  666. Get l5 // { arity: 2 }
  667. Distinct project=[#0{dim01_d01}] // { arity: 1 }
  668. Get l4 // { arity: 1 }
  669. Get l4 // { arity: 1 }
  670. Constant // { arity: 1 }
  671. - (false)
  672. cte l7 =
  673. Union // { arity: 2 }
  674. Get l6 // { arity: 2 }
  675. Project (#0{dim01_d01}, #2) // { arity: 2 }
  676. FlatMap guard_subquery_size(#1{count}) // { arity: 3 }
  677. Reduce group_by=[#0{dim01_d01}] aggregates=[count(*)] // { arity: 2 }
  678. Get l6 // { arity: 2 }
  679. cte l8 =
  680. Project (#0{x}..=#16{dim01_d05}) // { arity: 17 }
  681. Filter ((((#3{dim01_k01} + #0{x}) = (#11{dim01_k01} + #1{y})) AND (#7{facts_d02} = 42)) AND #17{any}) // { arity: 18 }
  682. Project (#0{x}..=#16{dim01_d05}, #18{any}) // { arity: 18 }
  683. Join on=(#12{dim01_d01} = #17{dim01_d01}) // { arity: 19 }
  684. Get l3 // { arity: 17 }
  685. Union // { arity: 2 }
  686. Get l7 // { arity: 2 }
  687. CrossJoin // { arity: 2 }
  688. Project (#0{dim01_d01}) // { arity: 1 }
  689. Join on=(#0{dim01_d01} = #1{dim01_d01}) // { arity: 2 }
  690. Union // { arity: 1 }
  691. Negate // { arity: 1 }
  692. Distinct project=[#0{dim01_d01}] // { arity: 1 }
  693. Get l7 // { arity: 2 }
  694. Distinct project=[#0{dim01_d01}] // { arity: 1 }
  695. Get l4 // { arity: 1 }
  696. Get l4 // { arity: 1 }
  697. Constant // { arity: 1 }
  698. - (null)
  699. Return // { arity: 6 }
  700. Project (#0{x}, #1{y}, #4{facts_k01}..=#7{dim01_d01}) // { arity: 6 }
  701. Join on=(#0{x} = #2{x} AND #1{y} = #3{y}) // { arity: 8 }
  702. Get l0 // { arity: 2 }
  703. Project (#0{x}..=#2{facts_k01}, #6{facts_d01}, #3{dim01_k01}, #12{dim01_d01}) // { arity: 6 }
  704. Union // { arity: 17 }
  705. Get l8 // { arity: 17 }
  706. CrossJoin // { arity: 17 }
  707. Project (#0{x}..=#10{facts_d05}) // { arity: 11 }
  708. Join on=(#0{x} = #11{x} AND #1{y} = #12{y} AND #2{facts_k01} = #13{facts_k01} AND #3{dim01_k01} = #14{dim01_k01} AND #4{dim02_k01} = #15{dim02_k01} AND #5{dim03_k01} = #16{dim03_k01} AND #6{facts_d01} = #17{facts_d01} AND #7{facts_d02} = #18{facts_d02} AND #8{facts_d03} = #19{facts_d03} AND #9{facts_d04} = #20{facts_d04} AND #10{facts_d05} = #21{facts_d05}) // { arity: 22 }
  709. Union // { arity: 11 }
  710. Negate // { arity: 11 }
  711. Distinct project=[#0{x}..=#10{facts_d05}] // { arity: 11 }
  712. Get l8 // { arity: 17 }
  713. Distinct project=[#0{x}..=#10{facts_d05}] // { arity: 11 }
  714. Get l2 // { arity: 11 }
  715. Get l2 // { arity: 11 }
  716. Constant // { arity: 6 }
  717. - (null, null, null, null, null, null)
  718. Target cluster: quickstart
  719. EOF
  720. # The following tests are for the EXPLAIN override of this
  721. # feature flag, so we want to disable it.
  722. simple conn=mz_system,user=mz_system
  723. ALTER SYSTEM SET enable_new_outer_join_lowering TO false;
  724. ----
  725. COMPLETE 0
  726. # EXPLAIN a SELECT with the feature turned in the EXPLAIN config.
  727. query T multiline
  728. EXPLAIN OPTIMIZED PLAN WITH(enable new outer join lowering, humanized expressions, arity) AS VERBOSE TEXT FOR
  729. SELECT
  730. facts.facts_k01,
  731. facts.facts_d01,
  732. facts.facts_d02,
  733. dim01.dim01_k01,
  734. dim01.dim01_d01,
  735. dim01.dim01_d02
  736. FROM
  737. left_joins_raw.facts LEFT JOIN
  738. left_joins_raw.dim01 ON(
  739. coalesce(facts.dim01_k01, 5) = coalesce(dim01.dim01_k01, 5) AND
  740. facts_d01 > 42 AND dim01_d02 < 24
  741. );
  742. ----
  743. Explained Query:
  744. With
  745. cte l0 =
  746. ArrangeBy keys=[[coalesce(#1{dim01_k01}, 5)]] // { arity: 4 }
  747. Project (#0{facts_k01}, #1{dim01_k01}, #4{facts_d01}, #5{facts_d02}) // { arity: 4 }
  748. Filter (#4{facts_d01} > 42) // { arity: 9 }
  749. ReadStorage materialize.left_joins_raw.facts // { arity: 9 }
  750. cte l1 =
  751. Join on=(coalesce(#1{dim01_k01}, 5) = coalesce(#4{dim01_k01}, 5)) type=differential // { arity: 7 }
  752. Get l0 // { arity: 4 }
  753. ArrangeBy keys=[[coalesce(#0{dim01_k01}, 5)]] // { arity: 3 }
  754. Project (#0{dim01_k01}..=#2{dim01_d02}) // { arity: 3 }
  755. Filter (#2{dim01_d02} < 24) // { arity: 6 }
  756. ReadStorage materialize.left_joins_raw.dim01 // { arity: 6 }
  757. Return // { arity: 6 }
  758. Union // { arity: 6 }
  759. Map (null, null, null) // { arity: 6 }
  760. Union // { arity: 3 }
  761. Negate // { arity: 3 }
  762. Project (#0{facts_k01}, #2{facts_d01}, #3{facts_d02}) // { arity: 3 }
  763. Join on=(#4 = coalesce(#1{dim01_k01}, 5)) type=differential // { arity: 5 }
  764. Get l0 // { arity: 4 }
  765. ArrangeBy keys=[[#0]] // { arity: 1 }
  766. Distinct project=[coalesce(#0{dim01_k01}, 5)] // { arity: 1 }
  767. Project (#1{dim01_k01}) // { arity: 1 }
  768. Get l1 // { arity: 7 }
  769. Project (#0{facts_k01}, #4{facts_d01}, #5{facts_d02}) // { arity: 3 }
  770. ReadStorage materialize.left_joins_raw.facts // { arity: 9 }
  771. Project (#0{facts_k01}, #2{facts_d01}..=#6{dim01_d02}) // { arity: 6 }
  772. Get l1 // { arity: 7 }
  773. Source materialize.left_joins_raw.facts
  774. Source materialize.left_joins_raw.dim01
  775. filter=((#2{dim01_d02} < 24))
  776. Target cluster: quickstart
  777. EOF
  778. # Define the above statement as a view.
  779. statement ok
  780. CREATE VIEW v AS
  781. SELECT
  782. facts.facts_k01,
  783. facts.facts_d01,
  784. facts.facts_d02,
  785. dim01.dim01_k01,
  786. dim01.dim01_d01,
  787. dim01.dim01_d02
  788. FROM
  789. left_joins_raw.facts LEFT JOIN
  790. left_joins_raw.dim01 ON(
  791. coalesce(facts.dim01_k01, 5) = coalesce(dim01.dim01_k01, 5) AND
  792. facts_d01 > 42 AND dim01_d02 < 24
  793. );
  794. # EXPLAIN a SELECT * FROM <view> with the feature turned in the EXPLAIN config.
  795. query T multiline
  796. EXPLAIN OPTIMIZED PLAN WITH(enable new outer join lowering, reoptimize imported views, humanized expressions, arity) AS VERBOSE TEXT FOR
  797. SELECT * FROM v;
  798. ----
  799. Explained Query:
  800. With
  801. cte l0 =
  802. ArrangeBy keys=[[coalesce(#1{dim01_k01}, 5)]] // { arity: 4 }
  803. Project (#0{facts_k01}, #1{dim01_k01}, #4{facts_d01}, #5{facts_d02}) // { arity: 4 }
  804. Filter (#4{facts_d01} > 42) // { arity: 9 }
  805. ReadStorage materialize.left_joins_raw.facts // { arity: 9 }
  806. cte l1 =
  807. Join on=(coalesce(#1{dim01_k01}, 5) = coalesce(#4{dim01_k01}, 5)) type=differential // { arity: 7 }
  808. Get l0 // { arity: 4 }
  809. ArrangeBy keys=[[coalesce(#0{dim01_k01}, 5)]] // { arity: 3 }
  810. Project (#0{dim01_k01}..=#2{dim01_d02}) // { arity: 3 }
  811. Filter (#2{dim01_d02} < 24) // { arity: 6 }
  812. ReadStorage materialize.left_joins_raw.dim01 // { arity: 6 }
  813. Return // { arity: 6 }
  814. Union // { arity: 6 }
  815. Map (null, null, null) // { arity: 6 }
  816. Union // { arity: 3 }
  817. Negate // { arity: 3 }
  818. Project (#0{facts_k01}, #2{facts_d01}, #3{facts_d02}) // { arity: 3 }
  819. Join on=(#4 = coalesce(#1{dim01_k01}, 5)) type=differential // { arity: 5 }
  820. Get l0 // { arity: 4 }
  821. ArrangeBy keys=[[#0]] // { arity: 1 }
  822. Distinct project=[coalesce(#0{dim01_k01}, 5)] // { arity: 1 }
  823. Project (#1{dim01_k01}) // { arity: 1 }
  824. Get l1 // { arity: 7 }
  825. Project (#0{facts_k01}, #4{facts_d01}, #5{facts_d02}) // { arity: 3 }
  826. ReadStorage materialize.left_joins_raw.facts // { arity: 9 }
  827. Project (#0{facts_k01}, #2{facts_d01}..=#6{dim01_d02}) // { arity: 6 }
  828. Get l1 // { arity: 7 }
  829. Source materialize.left_joins_raw.facts
  830. Source materialize.left_joins_raw.dim01
  831. filter=((#2{dim01_d02} < 24))
  832. Target cluster: quickstart
  833. EOF
  834. # EXPLAIN a CREATE INDEX with the feature turned in the EXPLAIN config.
  835. query T multiline
  836. EXPLAIN OPTIMIZED PLAN WITH(enable new outer join lowering, reoptimize imported views, humanized expressions, arity) AS VERBOSE TEXT FOR
  837. CREATE INDEX ON v(facts_k01);
  838. ----
  839. materialize.public.v_facts_k01_idx:
  840. ArrangeBy keys=[[#0{facts_k01}]] // { arity: 6 }
  841. ReadGlobalFromSameDataflow materialize.public.v // { arity: 6 }
  842. materialize.public.v:
  843. With
  844. cte l0 =
  845. ArrangeBy keys=[[coalesce(#1{dim01_k01}, 5)]] // { arity: 4 }
  846. Project (#0{facts_k01}, #1{dim01_k01}, #4{facts_d01}, #5{facts_d02}) // { arity: 4 }
  847. Filter (#4{facts_d01} > 42) // { arity: 9 }
  848. ReadStorage materialize.left_joins_raw.facts // { arity: 9 }
  849. cte l1 =
  850. Join on=(coalesce(#1{dim01_k01}, 5) = coalesce(#4{dim01_k01}, 5)) type=differential // { arity: 7 }
  851. Get l0 // { arity: 4 }
  852. ArrangeBy keys=[[coalesce(#0{dim01_k01}, 5)]] // { arity: 3 }
  853. Project (#0{dim01_k01}..=#2{dim01_d02}) // { arity: 3 }
  854. Filter (#2{dim01_d02} < 24) // { arity: 6 }
  855. ReadStorage materialize.left_joins_raw.dim01 // { arity: 6 }
  856. Return // { arity: 6 }
  857. Union // { arity: 6 }
  858. Map (null, null, null) // { arity: 6 }
  859. Union // { arity: 3 }
  860. Negate // { arity: 3 }
  861. Project (#0{facts_k01}, #2{facts_d01}, #3{facts_d02}) // { arity: 3 }
  862. Join on=(#4 = coalesce(#1{dim01_k01}, 5)) type=differential // { arity: 5 }
  863. Get l0 // { arity: 4 }
  864. ArrangeBy keys=[[#0]] // { arity: 1 }
  865. Distinct project=[coalesce(#0{dim01_k01}, 5)] // { arity: 1 }
  866. Project (#1{dim01_k01}) // { arity: 1 }
  867. Get l1 // { arity: 7 }
  868. Project (#0{facts_k01}, #4{facts_d01}, #5{facts_d02}) // { arity: 3 }
  869. ReadStorage materialize.left_joins_raw.facts // { arity: 9 }
  870. Project (#0{facts_k01}, #2{facts_d01}..=#6{dim01_d02}) // { arity: 6 }
  871. Get l1 // { arity: 7 }
  872. Source materialize.left_joins_raw.facts
  873. Source materialize.left_joins_raw.dim01
  874. filter=((#2{dim01_d02} < 24))
  875. Target cluster: quickstart
  876. EOF
  877. # EXPLAIN a CREATE MATERIALIZED VIEW with the feature turned in the EXPLAIN config.
  878. query T multiline
  879. EXPLAIN OPTIMIZED PLAN WITH(enable new outer join lowering, humanized expressions, arity) AS VERBOSE TEXT FOR
  880. CREATE MATERIALIZED VIEW mv AS
  881. SELECT
  882. facts.facts_k01,
  883. facts.facts_d01,
  884. facts.facts_d02,
  885. dim01.dim01_k01,
  886. dim01.dim01_d01,
  887. dim01.dim01_d02
  888. FROM
  889. left_joins_raw.facts LEFT JOIN
  890. left_joins_raw.dim01 ON(
  891. coalesce(facts.dim01_k01, 5) = coalesce(dim01.dim01_k01, 5) AND
  892. facts_d01 > 42 AND dim01_d02 < 24
  893. );
  894. ----
  895. materialize.public.mv:
  896. With
  897. cte l0 =
  898. ArrangeBy keys=[[coalesce(#1{dim01_k01}, 5)]] // { arity: 4 }
  899. Project (#0{facts_k01}, #1{dim01_k01}, #4{facts_d01}, #5{facts_d02}) // { arity: 4 }
  900. Filter (#4{facts_d01} > 42) // { arity: 9 }
  901. ReadStorage materialize.left_joins_raw.facts // { arity: 9 }
  902. cte l1 =
  903. Join on=(coalesce(#1{dim01_k01}, 5) = coalesce(#4{dim01_k01}, 5)) type=differential // { arity: 7 }
  904. Get l0 // { arity: 4 }
  905. ArrangeBy keys=[[coalesce(#0{dim01_k01}, 5)]] // { arity: 3 }
  906. Project (#0{dim01_k01}..=#2{dim01_d02}) // { arity: 3 }
  907. Filter (#2{dim01_d02} < 24) // { arity: 6 }
  908. ReadStorage materialize.left_joins_raw.dim01 // { arity: 6 }
  909. Return // { arity: 6 }
  910. Union // { arity: 6 }
  911. Map (null, null, null) // { arity: 6 }
  912. Union // { arity: 3 }
  913. Negate // { arity: 3 }
  914. Project (#0{facts_k01}, #2{facts_d01}, #3{facts_d02}) // { arity: 3 }
  915. Join on=(#4 = coalesce(#1{dim01_k01}, 5)) type=differential // { arity: 5 }
  916. Get l0 // { arity: 4 }
  917. ArrangeBy keys=[[#0]] // { arity: 1 }
  918. Distinct project=[coalesce(#0{dim01_k01}, 5)] // { arity: 1 }
  919. Project (#1{dim01_k01}) // { arity: 1 }
  920. Get l1 // { arity: 7 }
  921. Project (#0{facts_k01}, #4{facts_d01}, #5{facts_d02}) // { arity: 3 }
  922. ReadStorage materialize.left_joins_raw.facts // { arity: 9 }
  923. Project (#0{facts_k01}, #2{facts_d01}..=#6{dim01_d02}) // { arity: 6 }
  924. Get l1 // { arity: 7 }
  925. Source materialize.left_joins_raw.facts
  926. Source materialize.left_joins_raw.dim01
  927. filter=((#2{dim01_d02} < 24))
  928. Target cluster: quickstart
  929. EOF