aggregation_nullability.slt 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988
  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. statement ok
  11. CREATE TABLE t1(f1 int, f2 int)
  12. statement ok
  13. CREATE TABLE t2(f1 int, f2 int)
  14. statement ok
  15. INSERT INTO t1 VALUES (1, 2)
  16. # regression test for database-issues#2192: a filter on COUNT aggregation must not trigger the outer to inner join conversion
  17. query T multiline
  18. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR select t1.f1, count(t2.f1) from t1 LEFT JOIN t2 ON t1.f1 = t2.f1 group by t1.f1 having count(t2.f1) >= 0;
  19. ----
  20. Explained Query:
  21. With
  22. cte l0 =
  23. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  24. Project (#0{f1}) // { arity: 1 }
  25. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  26. ReadStorage materialize.public.t1 // { arity: 2 }
  27. cte l1 =
  28. Project (#0{f1}) // { arity: 1 }
  29. Join on=(#0{f1} = #1{f1}) type=differential // { arity: 2 }
  30. implementation
  31. %0:l0[#0{f1}]K » %1:t2[#0{f1}]K
  32. Get l0 // { arity: 1 }
  33. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  34. Project (#0{f1}) // { arity: 1 }
  35. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  36. ReadStorage materialize.public.t2 // { arity: 2 }
  37. Return // { arity: 2 }
  38. Filter (#1{count_f1} >= 0) // { arity: 2 }
  39. Reduce group_by=[#0{f1}] aggregates=[count(#1{f1})] // { arity: 2 }
  40. Union // { arity: 2 }
  41. Map (null) // { arity: 2 }
  42. Union // { arity: 1 }
  43. Negate // { arity: 1 }
  44. Project (#0{f1}) // { arity: 1 }
  45. Join on=(#0{f1} = #1{f1}) type=differential // { arity: 2 }
  46. implementation
  47. %1[#0]UKA » %0:l0[#0{f1}]K
  48. Get l0 // { arity: 1 }
  49. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  50. Distinct project=[#0{f1}] // { arity: 1 }
  51. Get l1 // { arity: 1 }
  52. Project (#0{f1}) // { arity: 1 }
  53. ReadStorage materialize.public.t1 // { arity: 2 }
  54. Project (#0{f1}, #0{f1}) // { arity: 2 }
  55. Get l1 // { arity: 1 }
  56. Source materialize.public.t1
  57. Source materialize.public.t2
  58. filter=((#0{f1}) IS NOT NULL)
  59. Target cluster: quickstart
  60. EOF
  61. query II
  62. select t1.f1, count(t2.f1) from t1 LEFT JOIN t2 ON t1.f1 = t2.f1 group by t1.f1 having count(t2.f1) >= 0;
  63. ----
  64. 1 0
  65. # ... but a filter on any other aggregation should convert a left join into an inner join if its parameter comes from the non-preserving side
  66. query T multiline
  67. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR select t1.f1, sum(t2.f1) from t1 LEFT JOIN t2 ON t1.f1 = t2.f1 group by t1.f1 having sum(t2.f1) >= 0;
  68. ----
  69. Explained Query:
  70. Filter (#1{sum_f1} >= 0) // { arity: 2 }
  71. Reduce group_by=[#0{f1}] aggregates=[sum(#0{f1})] // { arity: 2 }
  72. Project (#0{f1}) // { arity: 1 }
  73. Join on=(#0{f1} = #1{f1}) type=differential // { arity: 2 }
  74. implementation
  75. %0:t1[#0{f1}]K » %1:t2[#0{f1}]K
  76. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  77. Project (#0{f1}) // { arity: 1 }
  78. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  79. ReadStorage materialize.public.t1 // { arity: 2 }
  80. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  81. Project (#0{f1}) // { arity: 1 }
  82. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  83. ReadStorage materialize.public.t2 // { arity: 2 }
  84. Source materialize.public.t1
  85. filter=((#0{f1}) IS NOT NULL)
  86. Source materialize.public.t2
  87. filter=((#0{f1}) IS NOT NULL)
  88. Target cluster: quickstart
  89. EOF
  90. query II
  91. select t1.f1, sum(t2.f1) from t1 LEFT JOIN t2 ON t1.f1 = t2.f1 group by t1.f1 having sum(t2.f1) >= 0;
  92. ----
  93. # multiple aggregations
  94. query T multiline
  95. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR select t1.f1, count(t2.f1), sum(t2.f1), max(t2.f1), min(t2.f1), count(t1.f2), sum(t1.f2), min(t1.f2), max(t1.f2) from t1 LEFT JOIN t2 ON t1.f1 = t2.f1 group by t1.f1;
  96. ----
  97. Explained Query:
  98. With
  99. cte l0 =
  100. ArrangeBy keys=[[#0{f1}]] // { arity: 2 }
  101. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  102. ReadStorage materialize.public.t1 // { arity: 2 }
  103. cte l1 =
  104. Project (#0{f1}, #1{f2}) // { arity: 2 }
  105. Join on=(#0{f1} = #2{f1}) type=differential // { arity: 3 }
  106. implementation
  107. %0:l0[#0{f1}]K » %1:t2[#0{f1}]K
  108. Get l0 // { arity: 2 }
  109. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  110. Project (#0{f1}) // { arity: 1 }
  111. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  112. ReadStorage materialize.public.t2 // { arity: 2 }
  113. Return // { arity: 9 }
  114. Reduce group_by=[#0{f1}] aggregates=[count(#2{f1}), sum(#2{f1}), max(#2{f1}), min(#2{f1}), count(#1{f2}), sum(#1{f2}), min(#1{f2}), max(#1{f2})] // { arity: 9 }
  115. Union // { arity: 3 }
  116. Map (null) // { arity: 3 }
  117. Union // { arity: 2 }
  118. Negate // { arity: 2 }
  119. Project (#0{f1}, #1{f2}) // { arity: 2 }
  120. Join on=(#0{f1} = #2{f1}) type=differential // { arity: 3 }
  121. implementation
  122. %1[#0]UKA » %0:l0[#0{f1}]K
  123. Get l0 // { arity: 2 }
  124. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  125. Distinct project=[#0{f1}] // { arity: 1 }
  126. Project (#0{f1}) // { arity: 1 }
  127. Get l1 // { arity: 2 }
  128. ReadStorage materialize.public.t1 // { arity: 2 }
  129. Project (#0{f1}, #1{f2}, #0{f1}) // { arity: 3 }
  130. Get l1 // { arity: 2 }
  131. Source materialize.public.t1
  132. Source materialize.public.t2
  133. filter=((#0{f1}) IS NOT NULL)
  134. Target cluster: quickstart
  135. EOF
  136. query T multiline
  137. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR select t1.f1, count(t2.f1), sum(t2.f1), max(t2.f1), min(t2.f1), count(t1.f2), sum(t1.f2), min(t1.f2), max(t1.f2) from t1 LEFT JOIN t2 ON t1.f1 = t2.f1 group by t1.f1 having sum(t1.f2) >= 0;
  138. ----
  139. Explained Query:
  140. With
  141. cte l0 =
  142. ArrangeBy keys=[[#0{f1}]] // { arity: 2 }
  143. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  144. ReadStorage materialize.public.t1 // { arity: 2 }
  145. cte l1 =
  146. Project (#0{f1}, #1{f2}) // { arity: 2 }
  147. Join on=(#0{f1} = #2{f1}) type=differential // { arity: 3 }
  148. implementation
  149. %0:l0[#0{f1}]K » %1:t2[#0{f1}]K
  150. Get l0 // { arity: 2 }
  151. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  152. Project (#0{f1}) // { arity: 1 }
  153. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  154. ReadStorage materialize.public.t2 // { arity: 2 }
  155. Return // { arity: 9 }
  156. Filter (#6{sum_f2} >= 0) // { arity: 9 }
  157. Reduce group_by=[#0{f1}] aggregates=[count(#2{f1}), sum(#2{f1}), max(#2{f1}), min(#2{f1}), count(#1{f2}), sum(#1{f2}), min(#1{f2}), max(#1{f2})] // { arity: 9 }
  158. Union // { arity: 3 }
  159. Map (null) // { arity: 3 }
  160. Union // { arity: 2 }
  161. Negate // { arity: 2 }
  162. Project (#0{f1}, #1{f2}) // { arity: 2 }
  163. Join on=(#0{f1} = #2{f1}) type=differential // { arity: 3 }
  164. implementation
  165. %1[#0]UKA » %0:l0[#0{f1}]K
  166. Get l0 // { arity: 2 }
  167. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  168. Distinct project=[#0{f1}] // { arity: 1 }
  169. Project (#0{f1}) // { arity: 1 }
  170. Get l1 // { arity: 2 }
  171. ReadStorage materialize.public.t1 // { arity: 2 }
  172. Project (#0{f1}, #1{f2}, #0{f1}) // { arity: 3 }
  173. Get l1 // { arity: 2 }
  174. Source materialize.public.t1
  175. Source materialize.public.t2
  176. filter=((#0{f1}) IS NOT NULL)
  177. Target cluster: quickstart
  178. EOF
  179. query T multiline
  180. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR select t1.f1, count(t2.f1), sum(t2.f1), max(t2.f1), min(t2.f1), count(t1.f2), sum(t1.f2), min(t1.f2), max(t1.f2) from t1 LEFT JOIN t2 ON t1.f1 = t2.f1 group by t1.f1 having sum(t2.f1) >= 0;
  181. ----
  182. Explained Query:
  183. With
  184. cte l0 =
  185. ArrangeBy keys=[[#0{f1}]] // { arity: 2 }
  186. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  187. ReadStorage materialize.public.t1 // { arity: 2 }
  188. cte l1 =
  189. Project (#0{f1}, #1{f2}) // { arity: 2 }
  190. Join on=(#0{f1} = #2{f1}) type=differential // { arity: 3 }
  191. implementation
  192. %0:l0[#0{f1}]K » %1:t2[#0{f1}]K
  193. Get l0 // { arity: 2 }
  194. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  195. Project (#0{f1}) // { arity: 1 }
  196. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  197. ReadStorage materialize.public.t2 // { arity: 2 }
  198. Return // { arity: 9 }
  199. Filter (#2{sum_f1} >= 0) // { arity: 9 }
  200. Reduce group_by=[#0{f1}] aggregates=[count(#2{f1}), sum(#2{f1}), max(#2{f1}), min(#2{f1}), count(#1{f2}), sum(#1{f2}), min(#1{f2}), max(#1{f2})] // { arity: 9 }
  201. Union // { arity: 3 }
  202. Map (null) // { arity: 3 }
  203. Union // { arity: 2 }
  204. Negate // { arity: 2 }
  205. Project (#0{f1}, #1{f2}) // { arity: 2 }
  206. Join on=(#0{f1} = #2{f1}) type=differential // { arity: 3 }
  207. implementation
  208. %1[#0]UKA » %0:l0[#0{f1}]K
  209. Get l0 // { arity: 2 }
  210. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  211. Distinct project=[#0{f1}] // { arity: 1 }
  212. Project (#0{f1}) // { arity: 1 }
  213. Get l1 // { arity: 2 }
  214. ReadStorage materialize.public.t1 // { arity: 2 }
  215. Project (#0{f1}, #1{f2}, #0{f1}) // { arity: 3 }
  216. Get l1 // { arity: 2 }
  217. Source materialize.public.t1
  218. Source materialize.public.t2
  219. filter=((#0{f1}) IS NOT NULL)
  220. Target cluster: quickstart
  221. EOF
  222. # count is never null, predicate removed
  223. query T multiline
  224. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR select t1.f1, count(t1.f2) from t1 group by t1.f1 having count(t1.f2) is not null;
  225. ----
  226. Explained Query:
  227. Reduce group_by=[#0{f1}] aggregates=[count(#1{f2})] // { arity: 2 }
  228. ReadStorage materialize.public.t1 // { arity: 2 }
  229. Source materialize.public.t1
  230. Target cluster: quickstart
  231. EOF
  232. query T multiline
  233. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR select t1.f1, sum(t1.f2) from t1 group by t1.f1 having sum(t1.f2) is not null;
  234. ----
  235. Explained Query:
  236. Filter (#1{sum_f2}) IS NOT NULL // { arity: 2 }
  237. Reduce group_by=[#0{f1}] aggregates=[sum(#1{f2})] // { arity: 2 }
  238. ReadStorage materialize.public.t1 // { arity: 2 }
  239. Source materialize.public.t1
  240. Target cluster: quickstart
  241. EOF
  242. # outer-to-inner-join conversion allowed
  243. query T multiline
  244. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR select t1.f1, sum(t2.f1), max(t2.f1) from t1 LEFT JOIN t2 ON t1.f1 = t2.f1 group by t1.f1 having max(t2.f1) >= 0;
  245. ----
  246. Explained Query:
  247. Reduce group_by=[#0{f1}] aggregates=[sum(#0{f1}), max(#0{f1})] // { arity: 3 }
  248. Project (#0{f1}) // { arity: 1 }
  249. Join on=(#0{f1} = #1{f1}) type=differential // { arity: 2 }
  250. implementation
  251. %0:t1[#0{f1}]Kif » %1:t2[#0{f1}]Kiif
  252. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  253. Project (#0{f1}) // { arity: 1 }
  254. Filter (#0{f1} >= 0) // { arity: 2 }
  255. ReadStorage materialize.public.t1 // { arity: 2 }
  256. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  257. Project (#0{f1}) // { arity: 1 }
  258. Filter (#0{f1} >= 0) // { arity: 2 }
  259. ReadStorage materialize.public.t2 // { arity: 2 }
  260. Source materialize.public.t1
  261. filter=((#0{f1} >= 0))
  262. Source materialize.public.t2
  263. filter=((#0{f1} >= 0))
  264. Target cluster: quickstart
  265. EOF
  266. # outer-to-inner-join conversion allowed
  267. query T multiline
  268. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR select t1.f1, sum(t2.f1), max(t2.f1) from t1 LEFT JOIN t2 ON t1.f1 = t2.f1 group by t1.f1 having max(t2.f1) >= 0 and sum(t2.f1) >= 0;
  269. ----
  270. Explained Query:
  271. Filter (#1{sum_f1} >= 0) // { arity: 3 }
  272. Reduce group_by=[#0{f1}] aggregates=[sum(#0{f1}), max(#0{f1})] // { arity: 3 }
  273. Project (#0{f1}) // { arity: 1 }
  274. Join on=(#0{f1} = #1{f1}) type=differential // { arity: 2 }
  275. implementation
  276. %0:t1[#0{f1}]Kif » %1:t2[#0{f1}]Kiif
  277. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  278. Project (#0{f1}) // { arity: 1 }
  279. Filter (#0{f1} >= 0) // { arity: 2 }
  280. ReadStorage materialize.public.t1 // { arity: 2 }
  281. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  282. Project (#0{f1}) // { arity: 1 }
  283. Filter (#0{f1} >= 0) // { arity: 2 }
  284. ReadStorage materialize.public.t2 // { arity: 2 }
  285. Source materialize.public.t1
  286. filter=((#0{f1} >= 0))
  287. Source materialize.public.t2
  288. filter=((#0{f1} >= 0))
  289. Target cluster: quickstart
  290. EOF
  291. # outer-to-inner-join conversion allowed, but we fail to detect this case
  292. query T multiline
  293. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR select t1.f1, sum(t2.f2), max(t2.f1) from t1 LEFT JOIN t2 ON t1.f1 = t2.f1 group by t1.f1 having max(t2.f1) >= 0;
  294. ----
  295. Explained Query:
  296. With
  297. cte l0 =
  298. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  299. Project (#0{f1}) // { arity: 1 }
  300. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  301. ReadStorage materialize.public.t1 // { arity: 2 }
  302. cte l1 =
  303. Project (#0{f1}, #2{f2}) // { arity: 2 }
  304. Join on=(#0{f1} = #1{f1}) type=differential // { arity: 3 }
  305. implementation
  306. %0:l0[#0{f1}]K » %1:t2[#0{f1}]K
  307. Get l0 // { arity: 1 }
  308. ArrangeBy keys=[[#0{f1}]] // { arity: 2 }
  309. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  310. ReadStorage materialize.public.t2 // { arity: 2 }
  311. Return // { arity: 3 }
  312. Filter (#2{max_f1} >= 0) // { arity: 3 }
  313. Reduce group_by=[#0{f1}] aggregates=[sum(#2{f2}), max(#1{f1})] // { arity: 3 }
  314. Union // { arity: 3 }
  315. Map (null, null) // { arity: 3 }
  316. Union // { arity: 1 }
  317. Negate // { arity: 1 }
  318. Project (#0{f1}) // { arity: 1 }
  319. Join on=(#0{f1} = #1{f1}) type=differential // { arity: 2 }
  320. implementation
  321. %1[#0]UKA » %0:l0[#0{f1}]K
  322. Get l0 // { arity: 1 }
  323. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  324. Distinct project=[#0{f1}] // { arity: 1 }
  325. Project (#0{f1}) // { arity: 1 }
  326. Get l1 // { arity: 2 }
  327. Project (#0{f1}) // { arity: 1 }
  328. ReadStorage materialize.public.t1 // { arity: 2 }
  329. Project (#0{f1}, #0{f1}, #1{f2}) // { arity: 3 }
  330. Get l1 // { arity: 2 }
  331. Source materialize.public.t1
  332. Source materialize.public.t2
  333. filter=((#0{f1}) IS NOT NULL)
  334. Target cluster: quickstart
  335. EOF
  336. # outer-to-inner-join conversion allowed
  337. query T multiline
  338. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR select t1.f1, sum(t2.f1 + t2.f2), max(t2.f1) from t1 LEFT JOIN t2 ON t1.f1 = t2.f1 group by t1.f1 having max(t2.f1) >= 0;
  339. ----
  340. Explained Query:
  341. Reduce group_by=[#0{f1}] aggregates=[sum((#0{f1} + #1{f2})), max(#0{f1})] // { arity: 3 }
  342. Project (#0{f1}, #2{f2}) // { arity: 2 }
  343. Join on=(#0{f1} = #1{f1}) type=differential // { arity: 3 }
  344. implementation
  345. %0:t1[#0{f1}]Kif » %1:t2[#0{f1}]Kiif
  346. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  347. Project (#0{f1}) // { arity: 1 }
  348. Filter (#0{f1} >= 0) // { arity: 2 }
  349. ReadStorage materialize.public.t1 // { arity: 2 }
  350. ArrangeBy keys=[[#0{f1}]] // { arity: 2 }
  351. Filter (#0{f1} >= 0) // { arity: 2 }
  352. ReadStorage materialize.public.t2 // { arity: 2 }
  353. Source materialize.public.t1
  354. filter=((#0{f1} >= 0))
  355. Source materialize.public.t2
  356. filter=((#0{f1} >= 0))
  357. Target cluster: quickstart
  358. EOF
  359. # outer-to-inner-join conversion allowed
  360. query T multiline
  361. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR select t1.f1, sum(t1.f1 + t2.f1), max(t2.f1) from t1 LEFT JOIN t2 ON t1.f1 = t2.f1 group by t1.f1 having max(t2.f1) >= 0;
  362. ----
  363. Explained Query:
  364. Reduce group_by=[#0{f1}] aggregates=[sum((#0{f1} + #0{f1})), max(#0{f1})] // { arity: 3 }
  365. Project (#0{f1}) // { arity: 1 }
  366. Join on=(#0{f1} = #1{f1}) type=differential // { arity: 2 }
  367. implementation
  368. %0:t1[#0{f1}]Kif » %1:t2[#0{f1}]Kiif
  369. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  370. Project (#0{f1}) // { arity: 1 }
  371. Filter (#0{f1} >= 0) // { arity: 2 }
  372. ReadStorage materialize.public.t1 // { arity: 2 }
  373. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  374. Project (#0{f1}) // { arity: 1 }
  375. Filter (#0{f1} >= 0) // { arity: 2 }
  376. ReadStorage materialize.public.t2 // { arity: 2 }
  377. Source materialize.public.t1
  378. filter=((#0{f1} >= 0))
  379. Source materialize.public.t2
  380. filter=((#0{f1} >= 0))
  381. Target cluster: quickstart
  382. EOF
  383. # outer-to-inner-join conversion not allowed since that would alter the result of sum(t1.f1)
  384. query T multiline
  385. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR select t1.f1, sum(t1.f1), max(t2.f1) from t1 LEFT JOIN t2 ON t1.f1 = t2.f1 group by t1.f1 having max(t2.f1) >= 0;
  386. ----
  387. Explained Query:
  388. With
  389. cte l0 =
  390. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  391. Project (#0{f1}) // { arity: 1 }
  392. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  393. ReadStorage materialize.public.t1 // { arity: 2 }
  394. cte l1 =
  395. Project (#0{f1}) // { arity: 1 }
  396. Join on=(#0{f1} = #1{f1}) type=differential // { arity: 2 }
  397. implementation
  398. %0:l0[#0{f1}]K » %1:t2[#0{f1}]K
  399. Get l0 // { arity: 1 }
  400. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  401. Project (#0{f1}) // { arity: 1 }
  402. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  403. ReadStorage materialize.public.t2 // { arity: 2 }
  404. Return // { arity: 3 }
  405. Filter (#2{max_f1} >= 0) // { arity: 3 }
  406. Reduce group_by=[#0{f1}] aggregates=[sum(#0{f1}), max(#1{f1})] // { arity: 3 }
  407. Union // { arity: 2 }
  408. Map (null) // { arity: 2 }
  409. Union // { arity: 1 }
  410. Negate // { arity: 1 }
  411. Project (#0{f1}) // { arity: 1 }
  412. Join on=(#0{f1} = #1{f1}) type=differential // { arity: 2 }
  413. implementation
  414. %1[#0]UKA » %0:l0[#0{f1}]K
  415. Get l0 // { arity: 1 }
  416. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  417. Distinct project=[#0{f1}] // { arity: 1 }
  418. Get l1 // { arity: 1 }
  419. Project (#0{f1}) // { arity: 1 }
  420. ReadStorage materialize.public.t1 // { arity: 2 }
  421. Project (#0{f1}, #0{f1}) // { arity: 2 }
  422. Get l1 // { arity: 1 }
  423. Source materialize.public.t1
  424. Source materialize.public.t2
  425. filter=((#0{f1}) IS NOT NULL)
  426. Target cluster: quickstart
  427. EOF
  428. # outer join to inner join conversion not allowed
  429. query T multiline
  430. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR select t1.f1, count(t2.f2) from t1 LEFT JOIN t2 ON t1.f1 = t2.f1 group by t1.f1;
  431. ----
  432. Explained Query:
  433. With
  434. cte l0 =
  435. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  436. Project (#0{f1}) // { arity: 1 }
  437. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  438. ReadStorage materialize.public.t1 // { arity: 2 }
  439. cte l1 =
  440. Project (#0{f1}, #2{f2}) // { arity: 2 }
  441. Join on=(#0{f1} = #1{f1}) type=differential // { arity: 3 }
  442. implementation
  443. %0:l0[#0{f1}]K » %1:t2[#0{f1}]K
  444. Get l0 // { arity: 1 }
  445. ArrangeBy keys=[[#0{f1}]] // { arity: 2 }
  446. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  447. ReadStorage materialize.public.t2 // { arity: 2 }
  448. Return // { arity: 2 }
  449. Reduce group_by=[#0{f1}] aggregates=[count(#1{f2})] // { arity: 2 }
  450. Union // { arity: 2 }
  451. Map (null) // { arity: 2 }
  452. Union // { arity: 1 }
  453. Negate // { arity: 1 }
  454. Project (#0{f1}) // { arity: 1 }
  455. Join on=(#0{f1} = #1{f1}) type=differential // { arity: 2 }
  456. implementation
  457. %1[#0]UKA » %0:l0[#0{f1}]K
  458. Get l0 // { arity: 1 }
  459. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  460. Distinct project=[#0{f1}] // { arity: 1 }
  461. Project (#0{f1}) // { arity: 1 }
  462. Get l1 // { arity: 2 }
  463. Project (#0{f1}) // { arity: 1 }
  464. ReadStorage materialize.public.t1 // { arity: 2 }
  465. Get l1 // { arity: 2 }
  466. Source materialize.public.t1
  467. Source materialize.public.t2
  468. filter=((#0{f1}) IS NOT NULL)
  469. Target cluster: quickstart
  470. EOF
  471. # outer join to inner join conversion not allowed
  472. query T multiline
  473. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR select t1.f1, count(t2.f2), max(t2.f2) from t1 LEFT JOIN t2 ON t1.f1 = t2.f1 group by t1.f1;
  474. ----
  475. Explained Query:
  476. With
  477. cte l0 =
  478. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  479. Project (#0{f1}) // { arity: 1 }
  480. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  481. ReadStorage materialize.public.t1 // { arity: 2 }
  482. cte l1 =
  483. Project (#0{f1}, #2{f2}) // { arity: 2 }
  484. Join on=(#0{f1} = #1{f1}) type=differential // { arity: 3 }
  485. implementation
  486. %0:l0[#0{f1}]K » %1:t2[#0{f1}]K
  487. Get l0 // { arity: 1 }
  488. ArrangeBy keys=[[#0{f1}]] // { arity: 2 }
  489. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  490. ReadStorage materialize.public.t2 // { arity: 2 }
  491. Return // { arity: 3 }
  492. Reduce group_by=[#0{f1}] aggregates=[count(#1{f2}), max(#1{f2})] // { arity: 3 }
  493. Union // { arity: 2 }
  494. Map (null) // { arity: 2 }
  495. Union // { arity: 1 }
  496. Negate // { arity: 1 }
  497. Project (#0{f1}) // { arity: 1 }
  498. Join on=(#0{f1} = #1{f1}) type=differential // { arity: 2 }
  499. implementation
  500. %1[#0]UKA » %0:l0[#0{f1}]K
  501. Get l0 // { arity: 1 }
  502. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  503. Distinct project=[#0{f1}] // { arity: 1 }
  504. Project (#0{f1}) // { arity: 1 }
  505. Get l1 // { arity: 2 }
  506. Project (#0{f1}) // { arity: 1 }
  507. ReadStorage materialize.public.t1 // { arity: 2 }
  508. Get l1 // { arity: 2 }
  509. Source materialize.public.t1
  510. Source materialize.public.t2
  511. filter=((#0{f1}) IS NOT NULL)
  512. Target cluster: quickstart
  513. EOF
  514. # outer join to inner join conversion allowed
  515. query T multiline
  516. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR select t1.f1, count(t2.f2), max(t2.f2) from t1 LEFT JOIN t2 ON t1.f1 = t2.f1 group by t1.f1 having max(t2.f2) > 0;
  517. ----
  518. Explained Query:
  519. Filter (#2{max_f2} > 0) // { arity: 3 }
  520. Reduce group_by=[#0{f1}] aggregates=[count(#1{f2}), max(#1{f2})] // { arity: 3 }
  521. Project (#0{f1}, #2{f2}) // { arity: 2 }
  522. Join on=(#0{f1} = #1{f1}) type=differential // { arity: 3 }
  523. implementation
  524. %0:t1[#0{f1}]K » %1:t2[#0{f1}]K
  525. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  526. Project (#0{f1}) // { arity: 1 }
  527. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  528. ReadStorage materialize.public.t1 // { arity: 2 }
  529. ArrangeBy keys=[[#0{f1}]] // { arity: 2 }
  530. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  531. ReadStorage materialize.public.t2 // { arity: 2 }
  532. Source materialize.public.t1
  533. filter=((#0{f1}) IS NOT NULL)
  534. Source materialize.public.t2
  535. filter=((#0{f1}) IS NOT NULL)
  536. Target cluster: quickstart
  537. EOF
  538. # outer join to inner join conversion allowed
  539. query T multiline
  540. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR select t1.f1, max(t1.f1 + t2.f2), sum(t1.f2 + t2.f2) from t1 LEFT JOIN t2 ON t1.f1 = t2.f1 group by t1.f1 having max(t1.f1 + t2.f2) > 0;
  541. ----
  542. Explained Query:
  543. Filter (#1{max} > 0) // { arity: 3 }
  544. Reduce group_by=[#0{f1}] aggregates=[max((#0{f1} + #2{f2})), sum((#1{f2} + #2{f2}))] // { arity: 3 }
  545. Project (#0{f1}, #1{f2}, #3{f2}) // { arity: 3 }
  546. Join on=(#0{f1} = #2{f1}) type=differential // { arity: 4 }
  547. implementation
  548. %0:t1[#0{f1}]K » %1:t2[#0{f1}]K
  549. ArrangeBy keys=[[#0{f1}]] // { arity: 2 }
  550. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  551. ReadStorage materialize.public.t1 // { arity: 2 }
  552. ArrangeBy keys=[[#0{f1}]] // { arity: 2 }
  553. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  554. ReadStorage materialize.public.t2 // { arity: 2 }
  555. Source materialize.public.t1
  556. filter=((#0{f1}) IS NOT NULL)
  557. Source materialize.public.t2
  558. filter=((#0{f1}) IS NOT NULL)
  559. Target cluster: quickstart
  560. EOF
  561. # check that a filter on a non-count aggregation doesn't change the COUNT value
  562. statement ok
  563. drop table t1
  564. statement ok
  565. drop table t2
  566. statement ok
  567. create table t1(f1 integer, f2 integer)
  568. statement ok
  569. create table t2(f1 integer, f2 integer)
  570. statement ok
  571. insert into t1 values (1, 0), (1, 1), (1, 1)
  572. statement ok
  573. insert into t2 values (0, 2)
  574. query III
  575. select t1.f1, count(t1.f2), max(t2.f2) from t1 left join t2 on t1.f2 = t2.f1 group by t1.f1
  576. ----
  577. 1 3 2
  578. query III
  579. select t1.f1, count(t1.f2), max(t2.f2) from t1 left join t2 on t1.f2 = t2.f1 group by t1.f1 having max(t2.f2) > 0
  580. ----
  581. 1 3 2
  582. query T multiline
  583. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR select t1.f1, count(t1.f2), max(t2.f2) from t1 left join t2 on t1.f2 = t2.f1 group by t1.f1
  584. ----
  585. Explained Query:
  586. With
  587. cte l0 =
  588. ArrangeBy keys=[[#1{f2}]] // { arity: 2 }
  589. Filter (#1{f2}) IS NOT NULL // { arity: 2 }
  590. ReadStorage materialize.public.t1 // { arity: 2 }
  591. cte l1 =
  592. Project (#0{f1}, #1{f2}, #3{f2}) // { arity: 3 }
  593. Join on=(#1{f2} = #2{f1}) type=differential // { arity: 4 }
  594. implementation
  595. %0:l0[#1{f2}]K » %1:t2[#0{f1}]K
  596. Get l0 // { arity: 2 }
  597. ArrangeBy keys=[[#0{f1}]] // { arity: 2 }
  598. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  599. ReadStorage materialize.public.t2 // { arity: 2 }
  600. Return // { arity: 3 }
  601. Reduce group_by=[#0{f1}] aggregates=[count(#1{f2}), max(#2{f2})] // { arity: 3 }
  602. Union // { arity: 3 }
  603. Map (null) // { arity: 3 }
  604. Union // { arity: 2 }
  605. Negate // { arity: 2 }
  606. Project (#0{f1}, #1{f2}) // { arity: 2 }
  607. Join on=(#1{f2} = #2{f2}) type=differential // { arity: 3 }
  608. implementation
  609. %1[#0]UKA » %0:l0[#1{f2}]K
  610. Get l0 // { arity: 2 }
  611. ArrangeBy keys=[[#0{f2}]] // { arity: 1 }
  612. Distinct project=[#0{f2}] // { arity: 1 }
  613. Project (#1{f2}) // { arity: 1 }
  614. Get l1 // { arity: 3 }
  615. ReadStorage materialize.public.t1 // { arity: 2 }
  616. Get l1 // { arity: 3 }
  617. Source materialize.public.t1
  618. Source materialize.public.t2
  619. filter=((#0{f1}) IS NOT NULL)
  620. Target cluster: quickstart
  621. EOF
  622. query T multiline
  623. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR select t1.f1, count(t1.f2), max(t2.f2) from t1 left join t2 on t1.f2 = t2.f1 group by t1.f1 having max(t2.f2) > 0
  624. ----
  625. Explained Query:
  626. With
  627. cte l0 =
  628. ArrangeBy keys=[[#1{f2}]] // { arity: 2 }
  629. Filter (#1{f2}) IS NOT NULL // { arity: 2 }
  630. ReadStorage materialize.public.t1 // { arity: 2 }
  631. cte l1 =
  632. Project (#0{f1}, #1{f2}, #3{f2}) // { arity: 3 }
  633. Join on=(#1{f2} = #2{f1}) type=differential // { arity: 4 }
  634. implementation
  635. %0:l0[#1{f2}]K » %1:t2[#0{f1}]K
  636. Get l0 // { arity: 2 }
  637. ArrangeBy keys=[[#0{f1}]] // { arity: 2 }
  638. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  639. ReadStorage materialize.public.t2 // { arity: 2 }
  640. Return // { arity: 3 }
  641. Filter (#2{max_f2} > 0) // { arity: 3 }
  642. Reduce group_by=[#0{f1}] aggregates=[count(#1{f2}), max(#2{f2})] // { arity: 3 }
  643. Union // { arity: 3 }
  644. Map (null) // { arity: 3 }
  645. Union // { arity: 2 }
  646. Negate // { arity: 2 }
  647. Project (#0{f1}, #1{f2}) // { arity: 2 }
  648. Join on=(#1{f2} = #2{f2}) type=differential // { arity: 3 }
  649. implementation
  650. %1[#0]UKA » %0:l0[#1{f2}]K
  651. Get l0 // { arity: 2 }
  652. ArrangeBy keys=[[#0{f2}]] // { arity: 1 }
  653. Distinct project=[#0{f2}] // { arity: 1 }
  654. Project (#1{f2}) // { arity: 1 }
  655. Get l1 // { arity: 3 }
  656. ReadStorage materialize.public.t1 // { arity: 2 }
  657. Get l1 // { arity: 3 }
  658. Source materialize.public.t1
  659. Source materialize.public.t2
  660. filter=((#0{f1}) IS NOT NULL)
  661. Target cluster: quickstart
  662. EOF
  663. # if the count is removed, the outer join can be safely converted into an inner join
  664. query T multiline
  665. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR select t1.f1, max(t2.f2) from t1 left join t2 on t1.f2 = t2.f1 group by t1.f1 having max(t2.f2) > 0
  666. ----
  667. Explained Query:
  668. Filter (#1{max_f2} > 0) // { arity: 2 }
  669. Reduce group_by=[#0{f1}] aggregates=[max(#1{f2})] // { arity: 2 }
  670. Project (#0{f1}, #3{f2}) // { arity: 2 }
  671. Join on=(#1{f2} = #2{f1}) type=differential // { arity: 4 }
  672. implementation
  673. %0:t1[#1{f2}]K » %1:t2[#0{f1}]K
  674. ArrangeBy keys=[[#1{f2}]] // { arity: 2 }
  675. Filter (#1{f2}) IS NOT NULL // { arity: 2 }
  676. ReadStorage materialize.public.t1 // { arity: 2 }
  677. ArrangeBy keys=[[#0{f1}]] // { arity: 2 }
  678. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  679. ReadStorage materialize.public.t2 // { arity: 2 }
  680. Source materialize.public.t1
  681. filter=((#1{f2}) IS NOT NULL)
  682. Source materialize.public.t2
  683. filter=((#0{f1}) IS NOT NULL)
  684. Target cluster: quickstart
  685. EOF
  686. # regression test for database-issues#2190
  687. statement ok
  688. drop table t1
  689. statement ok
  690. create table t1(f1 integer)
  691. statement ok
  692. insert into t1 values (0), (1)
  693. query T multiline
  694. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT * FROM (SELECT 123, COUNT(right_table.f1) AS aggregate FROM t1 AS left_table LEFT JOIN t1 AS right_table ON FALSE GROUP BY 1) AS subquery, t1 AS outer_table WHERE outer_table.f1 = subquery.aggregate;
  695. ----
  696. Explained Query:
  697. Project (#2, #1, #0{f1}) // { arity: 3 }
  698. Filter (0 = integer_to_bigint(#0{f1})) // { arity: 3 }
  699. Map (0, 123) // { arity: 3 }
  700. ReadStorage materialize.public.t1 // { arity: 1 }
  701. Source materialize.public.t1
  702. filter=((0 = integer_to_bigint(#0{f1})))
  703. Target cluster: quickstart
  704. EOF
  705. query III
  706. SELECT * FROM (SELECT 123, COUNT(right_table.f1) AS aggregate FROM t1 AS left_table LEFT JOIN t1 AS right_table ON FALSE GROUP BY 1) AS subquery, t1 AS outer_table WHERE outer_table.f1 = subquery.aggregate;
  707. ----
  708. 123 0 0
  709. # non-null requirement on a non-count aggregation coming from a join predicate
  710. statement ok
  711. drop table t1
  712. statement ok
  713. drop table t2
  714. statement ok
  715. create table t1(f1 integer, f2 integer not null)
  716. statement ok
  717. insert into t1 values (null, 0)
  718. statement ok
  719. create table t2(f1 integer, f2 integer)
  720. statement ok
  721. insert into t2 values (null, 0)
  722. statement ok
  723. create table t3(f1 integer, f2 integer)
  724. statement ok
  725. insert into t3 values (null, 0), (null, 0), (1, 1), (6, 6)
  726. query I
  727. SELECT derived.agg1 FROM t1
  728. JOIN (
  729. SELECT COUNT(*) AS agg1 , MAX(t2.f2) AS agg2
  730. FROM t2
  731. RIGHT JOIN t3 ON t3.f2 = 6
  732. ) AS derived ON TRUE
  733. WHERE t1.f2 = derived.agg2;
  734. ----
  735. 4
  736. # the count aggregation prevents the outer-to-inner join conversion
  737. query T multiline
  738. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT derived.agg1 FROM t1
  739. JOIN (
  740. SELECT COUNT(*) AS agg1 , MAX(t2.f2) AS agg2
  741. FROM t2
  742. RIGHT JOIN t3 ON t3.f2 = 6
  743. ) AS derived ON TRUE
  744. WHERE t1.f2 = derived.agg2;
  745. ----
  746. Explained Query:
  747. With
  748. cte l0 =
  749. CrossJoin type=differential // { arity: 2 }
  750. implementation
  751. %1:t3[×]ef » %0:t2[×]ef
  752. ArrangeBy keys=[[]] // { arity: 1 }
  753. Project (#1{f2}) // { arity: 1 }
  754. ReadStorage materialize.public.t2 // { arity: 2 }
  755. ArrangeBy keys=[[]] // { arity: 1 }
  756. Project (#0{f1}) // { arity: 1 }
  757. Filter (#1{f2} = 6) // { arity: 2 }
  758. ReadStorage materialize.public.t3 // { arity: 2 }
  759. Return // { arity: 1 }
  760. Project (#1{count}) // { arity: 1 }
  761. Join on=(#0{f2} = #2{max_f2}) type=differential // { arity: 3 }
  762. implementation
  763. %1[#1{agg2}]UK » %0:t1[#0{f2}]K
  764. ArrangeBy keys=[[#0{f2}]] // { arity: 1 }
  765. Project (#1{f2}) // { arity: 1 }
  766. ReadStorage materialize.public.t1 // { arity: 2 }
  767. ArrangeBy keys=[[#1{max_f2}]] // { arity: 2 }
  768. Filter (#1{max_f2}) IS NOT NULL // { arity: 2 }
  769. Reduce aggregates=[count(*), max(#0{f2})] // { arity: 2 }
  770. Union // { arity: 1 }
  771. Project (#0{f2}) // { arity: 1 }
  772. Get l0 // { arity: 2 }
  773. Project (#4) // { arity: 1 }
  774. Map (null) // { arity: 5 }
  775. Join on=(#0{f1} = #2{f1} AND #1{f2} = #3{f2}) type=differential // { arity: 4 }
  776. implementation
  777. %0[#0, #1]KK » %1:t3[#0, #1]KK
  778. ArrangeBy keys=[[#0{f1}, #1{f2}]] // { arity: 2 }
  779. Union // { arity: 2 }
  780. Negate // { arity: 2 }
  781. Map (6) // { arity: 2 }
  782. Distinct project=[#0{f1}] // { arity: 1 }
  783. Project (#1{f1}) // { arity: 1 }
  784. Get l0 // { arity: 2 }
  785. Distinct project=[#0{f1}, #1{f2}] // { arity: 2 }
  786. ReadStorage materialize.public.t3 // { arity: 2 }
  787. ArrangeBy keys=[[#0{f1}, #1{f2}]] // { arity: 2 }
  788. ReadStorage materialize.public.t3 // { arity: 2 }
  789. Source materialize.public.t1
  790. Source materialize.public.t2
  791. Source materialize.public.t3
  792. Target cluster: quickstart
  793. EOF
  794. statement ok
  795. DROP TABLE t1;
  796. statement ok
  797. CREATE TABLE t1 (f1 INTEGER NOT NULL);
  798. statement ok
  799. INSERT INTO t1 VALUES (1);
  800. statement ok
  801. DROP TABLE t2;
  802. statement ok
  803. CREATE TABLE t2 (f1 INTEGER NOT NULL);
  804. statement ok
  805. INSERT INTO t2 VALUES (1);
  806. statement ok
  807. INSERT INTO t2 VALUES (2);
  808. # outer-to-inner join conversion not allowed
  809. query T multiline
  810. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT SUM(t1.f1 + t2.f1), SUM(t2.f1 + 0)
  811. FROM t2
  812. LEFT JOIN t1
  813. ON t1.f1 < t2.f1
  814. HAVING SUM(t1.f1 + t2.f1) > 0;
  815. ----
  816. Explained Query:
  817. With
  818. cte l0 =
  819. Filter (#1{f1} < #0{f1}) // { arity: 2 }
  820. CrossJoin type=differential // { arity: 2 }
  821. implementation
  822. %0:t2[×] » %1:t1[×]
  823. ArrangeBy keys=[[]] // { arity: 1 }
  824. ReadStorage materialize.public.t2 // { arity: 1 }
  825. ArrangeBy keys=[[]] // { arity: 1 }
  826. ReadStorage materialize.public.t1 // { arity: 1 }
  827. Return // { arity: 2 }
  828. Filter (#0{sum} > 0) // { arity: 2 }
  829. Reduce aggregates=[sum((#1{f1} + #0{f1})), sum((#0{f1} + 0))] // { arity: 2 }
  830. Union // { arity: 2 }
  831. Get l0 // { arity: 2 }
  832. Project (#0{f1}, #2) // { arity: 2 }
  833. Map (null) // { arity: 3 }
  834. Join on=(#0{f1} = #1{f1}) type=differential // { arity: 2 }
  835. implementation
  836. %0[#0]K » %1:t2[#0]K
  837. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  838. Union // { arity: 1 }
  839. Negate // { arity: 1 }
  840. Distinct project=[#0{f1}] // { arity: 1 }
  841. Project (#0{f1}) // { arity: 1 }
  842. Get l0 // { arity: 2 }
  843. Distinct project=[#0{f1}] // { arity: 1 }
  844. ReadStorage materialize.public.t2 // { arity: 1 }
  845. ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
  846. ReadStorage materialize.public.t2 // { arity: 1 }
  847. Source materialize.public.t1
  848. Source materialize.public.t2
  849. Target cluster: quickstart
  850. EOF
  851. query II
  852. SELECT SUM(t1.f1 + t2.f1), SUM(t2.f1 + 0)
  853. FROM t2
  854. LEFT JOIN t1
  855. ON t1.f1 < t2.f1
  856. HAVING SUM(t1.f1 + t2.f1) > 0;
  857. ----
  858. 3 3