predicate_pushdown.slt 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096
  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. # This file contains tests for the PredicatePushdown transform.
  10. mode cockroach
  11. statement ok
  12. CREATE TABLE x (a int not null, u int, b bool)
  13. statement ok
  14. CREATE TABLE y (a int not null)
  15. query T multiline
  16. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT b FROM (SELECT b, not(b) as neg FROM x) WHERE NOT(neg)
  17. ----
  18. Explained Query:
  19. Project (#2{b}) // { arity: 1 }
  20. Filter #2{b} // { arity: 3 }
  21. ReadStorage materialize.public.x // { arity: 3 }
  22. Source materialize.public.x
  23. filter=(#2{b})
  24. Target cluster: quickstart
  25. EOF
  26. query T multiline
  27. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT b FROM (SELECT b, b = false as neg FROM x) WHERE NOT(neg)
  28. ----
  29. Explained Query:
  30. Project (#2{b}) // { arity: 1 }
  31. Filter (#2{b} != false) // { arity: 3 }
  32. ReadStorage materialize.public.x // { arity: 3 }
  33. Source materialize.public.x
  34. filter=((#2{b} != false))
  35. Target cluster: quickstart
  36. EOF
  37. # Inline binary expressions.
  38. query T multiline
  39. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR
  40. SELECT a FROM (SELECT a, a = 3 AS cond, u != 2 as cond2 FROM x) WHERE NOT(cond) AND NOT(cond2)
  41. ----
  42. Explained Query:
  43. Project (#0{a}) // { arity: 1 }
  44. Filter (#1{u} = 2) AND (#0{a} != 3) // { arity: 3 }
  45. ReadStorage materialize.public.x // { arity: 3 }
  46. Source materialize.public.x
  47. filter=((#0{a} != 3) AND (#1{u} = 2))
  48. Target cluster: quickstart
  49. EOF
  50. # This test was testing our earlier heuristics for when can push_filters_through_map inline a Map expression.
  51. # (Which was to not inline binary expressions not having a leaf argument.) This has changed with
  52. # https://github.com/MaterializeInc/materialize/pull/22098, so now we inline in this test.
  53. query T multiline
  54. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR
  55. SELECT a FROM (SELECT a, (a + 1) = (u + 3) AS cond FROM x) WHERE NOT(cond)
  56. ----
  57. Explained Query:
  58. Project (#0{a}) // { arity: 1 }
  59. Filter ((#0{a} + 1) != (#1{u} + 3)) // { arity: 3 }
  60. ReadStorage materialize.public.x // { arity: 3 }
  61. Source materialize.public.x
  62. filter=(((#0{a} + 1) != (#1{u} + 3)))
  63. Target cluster: quickstart
  64. EOF
  65. # Similar to the above: we push everything here since
  66. # https://github.com/MaterializeInc/materialize/pull/22098
  67. query T multiline
  68. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR
  69. SELECT * FROM
  70. (SELECT a, b, b+1 as c FROM
  71. (SELECT a, a+1 as b FROM y))
  72. WHERE b = 3 AND c = 4
  73. ----
  74. Explained Query:
  75. Filter (#1 = 3) AND (4 = (#1 + 1)) // { arity: 3 }
  76. Map ((#0{a} + 1), 4) // { arity: 3 }
  77. ReadStorage materialize.public.y // { arity: 1 }
  78. Source materialize.public.y
  79. filter=((3 = #1) AND (4 = (#1 + 1)))
  80. map=((#0{a} + 1))
  81. Target cluster: quickstart
  82. EOF
  83. # Regression test to ensure that a filter gets pushed down to all inputs of a union.
  84. query T multiline
  85. EXPLAIN DECORRELATED PLAN WITH(arity) FOR
  86. SELECT a FROM (SELECT DISTINCT a FROM x UNION ALL SELECT a FROM y) WHERE a = 3
  87. ----
  88. Filter (#0{a} = 3) // { arity: 1 }
  89. Union // { arity: 1 }
  90. Distinct project=[#0] // { arity: 1 }
  91. Project (#0) // { arity: 1 }
  92. CrossJoin // { arity: 3 }
  93. Constant // { arity: 0 }
  94. - ()
  95. Get materialize.public.x // { arity: 3 }
  96. CrossJoin // { arity: 1 }
  97. Constant // { arity: 0 }
  98. - ()
  99. Get materialize.public.y // { arity: 1 }
  100. Target cluster: quickstart
  101. EOF
  102. query T multiline
  103. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR
  104. SELECT a FROM (SELECT DISTINCT a FROM x UNION ALL SELECT a FROM y) WHERE a = 3
  105. ----
  106. Explained Query:
  107. Union // { arity: 1 }
  108. Map (3) // { arity: 1 }
  109. Distinct project=[] // { arity: 0 }
  110. Project () // { arity: 0 }
  111. Filter (#0{a} = 3) // { arity: 3 }
  112. ReadStorage materialize.public.x // { arity: 3 }
  113. Filter (#0{a} = 3) // { arity: 1 }
  114. ReadStorage materialize.public.y // { arity: 1 }
  115. Source materialize.public.x
  116. filter=((#0{a} = 3))
  117. Source materialize.public.y
  118. filter=((#0{a} = 3))
  119. Target cluster: quickstart
  120. EOF
  121. statement ok
  122. CREATE TABLE t1 (f1 integer, f2 integer)
  123. statement ok
  124. CREATE TABLE t2 (f1 integer, f2 integer)
  125. # redundant equivalence is pushed down to all join branches and removed
  126. query T multiline
  127. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR
  128. SELECT * FROM t1, t2 WHERE t1.f1 = t2.f1 AND t1.f2 = t2.f2 AND t1.f1 + t2.f2 = t2.f1 + t1.f2;
  129. ----
  130. Explained Query:
  131. Project (#0{f1}, #1{f2}, #0{f1}, #1{f2}) // { arity: 4 }
  132. Join on=(#0{f1} = #2{f1} AND #1{f2} = #3{f2}) type=differential // { arity: 4 }
  133. implementation
  134. %0:t1[#0{f1}, #1{f2}]KK » %1:t2[#0{f1}, #1{f2}]KK
  135. ArrangeBy keys=[[#0{f1}, #1{f2}]] // { arity: 2 }
  136. Filter (#0{f1}) IS NOT NULL AND (#1{f2}) IS NOT NULL // { arity: 2 }
  137. ReadStorage materialize.public.t1 // { arity: 2 }
  138. ArrangeBy keys=[[#0{f1}, #1{f2}]] // { arity: 2 }
  139. Filter (#0{f1}) IS NOT NULL AND (#1{f2}) IS NOT NULL // { arity: 2 }
  140. ReadStorage materialize.public.t2 // { arity: 2 }
  141. Source materialize.public.t1
  142. filter=((#0{f1}) IS NOT NULL AND (#1{f2}) IS NOT NULL)
  143. Source materialize.public.t2
  144. filter=((#0{f1}) IS NOT NULL AND (#1{f2}) IS NOT NULL)
  145. Target cluster: quickstart
  146. EOF
  147. # database-issues#2377 avoidable cross joins
  148. query T multiline
  149. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR
  150. select * from t1, t2 where t1.f1 = t2.f1 + 1 or (t1.f1 is null and t2.f1 is null);
  151. ----
  152. Explained Query:
  153. Join on=(#0{f1} = (#2{f1} + 1)) type=differential // { arity: 4 }
  154. implementation
  155. %0:t1[#0{f1}]K » %1:t2[(#0{f1} + 1)]K
  156. ArrangeBy keys=[[#0{f1}]] // { arity: 2 }
  157. ReadStorage materialize.public.t1 // { arity: 2 }
  158. ArrangeBy keys=[[(#0{f1} + 1)]] // { arity: 2 }
  159. ReadStorage materialize.public.t2 // { arity: 2 }
  160. Source materialize.public.t1
  161. Source materialize.public.t2
  162. Target cluster: quickstart
  163. EOF
  164. query T multiline
  165. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR
  166. select * from t1, t2 where t1.f1 = t2.f1 + 1 or (t1.f1 is null and (t2.f1 + 1) is null);
  167. ----
  168. Explained Query:
  169. Join on=(#0{f1} = (#2{f1} + 1)) type=differential // { arity: 4 }
  170. implementation
  171. %0:t1[#0{f1}]K » %1:t2[(#0{f1} + 1)]K
  172. ArrangeBy keys=[[#0{f1}]] // { arity: 2 }
  173. ReadStorage materialize.public.t1 // { arity: 2 }
  174. ArrangeBy keys=[[(#0{f1} + 1)]] // { arity: 2 }
  175. ReadStorage materialize.public.t2 // { arity: 2 }
  176. Source materialize.public.t1
  177. Source materialize.public.t2
  178. Target cluster: quickstart
  179. EOF
  180. query T multiline
  181. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR
  182. select * from t1, t2 where t2.f1 = t1.f1 + 1 or (t1.f1 is null and (t2.f1 + 1) is null);
  183. ----
  184. Explained Query:
  185. Join on=(#2{f1} = (#0{f1} + 1)) type=differential // { arity: 4 }
  186. implementation
  187. %0:t1[(#0{f1} + 1)]K » %1:t2[#0{f1}]K
  188. ArrangeBy keys=[[(#0{f1} + 1)]] // { arity: 2 }
  189. ReadStorage materialize.public.t1 // { arity: 2 }
  190. ArrangeBy keys=[[#0{f1}]] // { arity: 2 }
  191. ReadStorage materialize.public.t2 // { arity: 2 }
  192. Source materialize.public.t1
  193. Source materialize.public.t2
  194. Target cluster: quickstart
  195. EOF
  196. query T multiline
  197. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR
  198. select * from t1, t2 where t2.f1 = t1.f1 + 1 or (t1.f1 is null and ((t2.f1 + 1) is null and t1.f1 is null));
  199. ----
  200. Explained Query:
  201. Join on=(#2{f1} = (#0{f1} + 1)) type=differential // { arity: 4 }
  202. implementation
  203. %0:t1[(#0{f1} + 1)]K » %1:t2[#0{f1}]K
  204. ArrangeBy keys=[[(#0{f1} + 1)]] // { arity: 2 }
  205. ReadStorage materialize.public.t1 // { arity: 2 }
  206. ArrangeBy keys=[[#0{f1}]] // { arity: 2 }
  207. ReadStorage materialize.public.t2 // { arity: 2 }
  208. Source materialize.public.t1
  209. Source materialize.public.t2
  210. Target cluster: quickstart
  211. EOF
  212. # Join-Dependent Predicate Duplication (JoinInputMapper::consequence_for_input)
  213. query T multiline
  214. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR
  215. SELECT * FROM t1, t2 WHERE t1.f1 = t2.f1 AND ((t1.f2 = 3 AND t2.f2 = 4) OR (t1.f2 = 5 AND t2.f2 = 6));
  216. ----
  217. Explained Query:
  218. Project (#0{f1}, #1{f2}, #0{f1}, #3{f2}) // { arity: 4 }
  219. Filter (((#1{f2} = 3) AND (#3{f2} = 4)) OR ((#1{f2} = 5) AND (#3{f2} = 6))) // { arity: 4 }
  220. Join on=(#0{f1} = #2{f1}) type=differential // { arity: 4 }
  221. implementation
  222. %0:t1[#0{f1}]Kef » %1:t2[#0{f1}]Kef
  223. ArrangeBy keys=[[#0{f1}]] // { arity: 2 }
  224. Filter (#0{f1}) IS NOT NULL AND ((#1{f2} = 3) OR (#1{f2} = 5)) // { arity: 2 }
  225. ReadStorage materialize.public.t1 // { arity: 2 }
  226. ArrangeBy keys=[[#0{f1}]] // { arity: 2 }
  227. Filter (#0{f1}) IS NOT NULL AND ((#1{f2} = 4) OR (#1{f2} = 6)) // { arity: 2 }
  228. ReadStorage materialize.public.t2 // { arity: 2 }
  229. Source materialize.public.t1
  230. filter=((#0{f1}) IS NOT NULL AND ((#1{f2} = 3) OR (#1{f2} = 5)))
  231. Source materialize.public.t2
  232. filter=((#0{f1}) IS NOT NULL AND ((#1{f2} = 4) OR (#1{f2} = 6)))
  233. Target cluster: quickstart
  234. EOF
  235. query T multiline
  236. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR
  237. SELECT * FROM t1, t2 WHERE t1.f1 = t2.f1 AND ((t1.f2 = 3 AND t2.f2 = 4) OR t1.f2 = 5);
  238. ----
  239. Explained Query:
  240. Project (#0{f1}, #1{f2}, #0{f1}, #3{f2}) // { arity: 4 }
  241. Filter ((#1{f2} = 5) OR ((#1{f2} = 3) AND (#3{f2} = 4))) // { arity: 4 }
  242. Join on=(#0{f1} = #2{f1}) type=differential // { arity: 4 }
  243. implementation
  244. %0:t1[#0{f1}]Kef » %1:t2[#0{f1}]Kef
  245. ArrangeBy keys=[[#0{f1}]] // { arity: 2 }
  246. Filter (#0{f1}) IS NOT NULL AND ((#1{f2} = 3) OR (#1{f2} = 5)) // { arity: 2 }
  247. ReadStorage materialize.public.t1 // { arity: 2 }
  248. ArrangeBy keys=[[#0{f1}]] // { arity: 2 }
  249. Filter (#0{f1}) IS NOT NULL // { arity: 2 }
  250. ReadStorage materialize.public.t2 // { arity: 2 }
  251. Source materialize.public.t1
  252. filter=((#0{f1}) IS NOT NULL AND ((#1{f2} = 3) OR (#1{f2} = 5)))
  253. Source materialize.public.t2
  254. filter=((#0{f1}) IS NOT NULL)
  255. Target cluster: quickstart
  256. EOF
  257. query T multiline
  258. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR
  259. SELECT * FROM t1, t2
  260. WHERE t1.f2 = 27 OR (t1.f2 <= 1995 AND t1.f1 = t2.f1);
  261. ----
  262. Explained Query:
  263. Filter ((#1{f2} = 27) OR ((#0{f1} = #2{f1}) AND (#1{f2} <= 1995))) // { arity: 4 }
  264. CrossJoin type=differential // { arity: 4 }
  265. implementation
  266. %0:t1[×]eiif » %1:t2[×]eiif
  267. ArrangeBy keys=[[]] // { arity: 2 }
  268. Filter ((#1{f2} = 27) OR (#1{f2} <= 1995)) // { arity: 2 }
  269. ReadStorage materialize.public.t1 // { arity: 2 }
  270. ArrangeBy keys=[[]] // { arity: 2 }
  271. ReadStorage materialize.public.t2 // { arity: 2 }
  272. Source materialize.public.t1
  273. filter=(((#1{f2} = 27) OR (#1{f2} <= 1995)))
  274. Source materialize.public.t2
  275. Target cluster: quickstart
  276. EOF
  277. # Delta join -- In this case, `JoinImplementation` lifts the newly created predicates to after the join at the end of
  278. # MIR. However, MIR -> LIR lowering will push these predicates to their correct place. We can check this in the physical
  279. # plan, i.e., that they are in the `initial_closure`.
  280. statement ok
  281. CREATE INDEX t1_f1_ind on t1(f1)
  282. statement ok
  283. CREATE INDEX t2_f1_ind on t2(f1)
  284. query T multiline
  285. EXPLAIN PHYSICAL PLAN AS VERBOSE TEXT FOR
  286. SELECT * FROM t1, t2 WHERE t1.f1 = t2.f1 AND ((t1.f2 = 3 AND t2.f2 = 4) OR (t1.f2 = 5 AND t2.f2 = 6));
  287. ----
  288. Explained Query:
  289. Join::Linear
  290. final_closure
  291. project=(#0, #1, #0, #2)
  292. linear_stage[0]
  293. closure
  294. filter=((#0{f1}) IS NOT NULL AND (#3 OR #4) AND (#5 OR #6) AND ((#3 AND #5) OR (#4 AND #6)))
  295. map=((#1{f2} = 3), (#1{f2} = 5), (#2{f2} = 4), (#2{f2} = 6))
  296. lookup={ relation=1, key=[#0{f1}] }
  297. stream={ key=[#0{f1}], thinning=(#1) }
  298. source={ relation=0, key=[#0{f1}] }
  299. Get::PassArrangements materialize.public.t1
  300. raw=false
  301. arrangements[0]={ key=[#0{f1}], permutation=id, thinning=(#1) }
  302. types=[integer?, integer?]
  303. Get::PassArrangements materialize.public.t2
  304. raw=false
  305. arrangements[0]={ key=[#0{f1}], permutation=id, thinning=(#1) }
  306. types=[integer?, integer?]
  307. Used Indexes:
  308. - materialize.public.t1_f1_ind (differential join)
  309. - materialize.public.t2_f1_ind (differential join)
  310. Target cluster: quickstart
  311. EOF
  312. # Regression tests for https://github.com/MaterializeInc/database-issues/issues/4659
  313. statement ok
  314. CREATE TABLE tt1 (f1 DOUBLE PRECISION, f2 DOUBLE PRECISION NOT NULL);
  315. statement ok
  316. CREATE TABLE tt2 (f1 DOUBLE PRECISION, f2 DOUBLE PRECISION NOT NULL);
  317. query T multiline
  318. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT *
  319. FROM tt2 ,
  320. (
  321. SELECT AVG(1) AS f1 , COUNT (1) AS f2
  322. FROM tt2
  323. WHERE f2 IS NULL
  324. ) AS a2
  325. WHERE a2.f1 = 1
  326. OR a2.f1 + 4 = 8
  327. AND tt2.f2 = 1;
  328. ----
  329. Explained Query (fast path):
  330. Constant <empty>
  331. Target cluster: quickstart
  332. EOF
  333. query T multiline
  334. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT
  335. s.name, r.name
  336. FROM
  337. mz_schemas s,
  338. mz_relations r
  339. WHERE
  340. r.schema_id = s.id AND (r.type = 'materialized-view' OR (r.type = 'view' AND s.name != 'doesntmatter'))
  341. ----
  342. Explained Query:
  343. Project (#1{name}, #3{name}) // { arity: 2 }
  344. Filter ((#4{type} = "materialized-view") OR ((#4{type} = "view") AND (#1{name} != "doesntmatter"))) // { arity: 5 }
  345. Join on=(#0{id} = #2{schema_id}) type=differential // { arity: 5 }
  346. implementation
  347. %0:mz_schemas[#0{id}]UK » %1[#0{schema_id}]Kef
  348. ArrangeBy keys=[[#0{id}]] // { arity: 2 }
  349. Project (#0{id}, #3{name}) // { arity: 2 }
  350. ReadIndex on=mz_schemas mz_schemas_ind=[*** full scan ***] // { arity: 6 }
  351. ArrangeBy keys=[[#0{schema_id}]] // { arity: 3 }
  352. Union // { arity: 3 }
  353. Project (#2{schema_id}, #3{name}, #9) // { arity: 3 }
  354. Map ("view") // { arity: 10 }
  355. ReadIndex on=mz_views mz_views_ind=[*** full scan ***] // { arity: 9 }
  356. Project (#2{schema_id}, #3{name}, #10) // { arity: 3 }
  357. Map ("materialized-view") // { arity: 11 }
  358. ReadIndex on=mz_materialized_views mz_materialized_views_ind=[*** full scan ***] // { arity: 10 }
  359. Used Indexes:
  360. - mz_catalog.mz_materialized_views_ind (*** full scan ***)
  361. - mz_catalog.mz_schemas_ind (*** full scan ***)
  362. - mz_catalog.mz_views_ind (*** full scan ***)
  363. Target cluster: mz_catalog_server
  364. EOF
  365. # Regression tests for database-issues#5089
  366. # Push predicates through Threshold and TopK
  367. # Test Threshold.
  368. query T multiline
  369. EXPLAIN OPTIMIZED PLAN AS TEXT FOR
  370. WITH cte(a) as (SELECT a FROM x EXCEPT ALL SELECT a FROM y)
  371. SELECT a * 5 FROM cte WHERE a = 5
  372. ----
  373. Explained Query:
  374. Project (#1)
  375. Map (25)
  376. Threshold
  377. Union
  378. Project (#0)
  379. Filter (#0{a} = 5)
  380. ReadStorage materialize.public.x
  381. Negate
  382. Filter (#0{a} = 5)
  383. ReadStorage materialize.public.y
  384. Source materialize.public.x
  385. filter=((#0{a} = 5))
  386. Source materialize.public.y
  387. filter=((#0{a} = 5))
  388. Target cluster: quickstart
  389. EOF
  390. # Test TopK.
  391. query T multiline
  392. EXPLAIN OPTIMIZED PLAN AS TEXT FOR
  393. SELECT a FROM y as y, LATERAL(SELECT u FROM x WHERE y.a = x.a LIMIT 5) WHERE a IN (41, 42);
  394. ----
  395. Explained Query:
  396. With
  397. cte l0 =
  398. Filter ((#0{a} = 41) OR (#0{a} = 42))
  399. ReadStorage materialize.public.y
  400. Return
  401. Project (#0)
  402. Join on=(#0 = #1) type=differential
  403. ArrangeBy keys=[[#0]]
  404. Get l0
  405. ArrangeBy keys=[[#0]]
  406. TopK group_by=[#0] limit=5
  407. Project (#0)
  408. Join on=(#0{a} = #1{a}) type=differential
  409. ArrangeBy keys=[[#0{a}]]
  410. Distinct project=[#0]
  411. Get l0
  412. ArrangeBy keys=[[#0{a}]]
  413. Project (#0)
  414. Filter ((#0{a} = 41) OR (#0{a} = 42))
  415. ReadStorage materialize.public.x
  416. Source materialize.public.x
  417. filter=(((#0{a} = 41) OR (#0{a} = 42)))
  418. Source materialize.public.y
  419. filter=(((#0{a} = 41) OR (#0{a} = 42)))
  420. Target cluster: quickstart
  421. EOF
  422. # One more for https://github.com/MaterializeInc/database-issues/issues/4659
  423. # https://github.com/MaterializeInc/materialize/pull/16147#issuecomment-1322042176
  424. simple conn=mz_system,user=mz_system
  425. ALTER SYSTEM SET enable_rbac_checks TO false;
  426. ----
  427. COMPLETE 0
  428. statement ok
  429. DROP SCHEMA public CASCADE ;
  430. simple conn=mz_system,user=mz_system
  431. ALTER SYSTEM RESET enable_rbac_checks;
  432. ----
  433. COMPLETE 0
  434. statement ok
  435. CREATE SCHEMA public ;
  436. statement ok
  437. CREATE TABLE table_f2_f3 ( f2 INTEGER , f3 INTEGER ) ;
  438. statement ok
  439. CREATE TABLE table_f3_f4_f5 ( f3 INTEGER , f4 INTEGER , f5 INTEGER ) ;
  440. statement ok
  441. CREATE TABLE table_f4_f5_f6 ( f4 INTEGER , f5 INTEGER , f6 INTEGER ) ;
  442. statement ok
  443. INSERT INTO table_f2_f3 VALUES ( 0 , 0 ), ( 0 , 1 ), ( NULL , 0 );
  444. statement ok
  445. INSERT INTO table_f3_f4_f5 VALUES ( 0 , 1 , NULL ), ( 1 , 1 , 0 ), ( 1 , NULL , 0 );
  446. statement ok
  447. INSERT INTO table_f4_f5_f6 VALUES ( 0 , 0 , 1 ), ( 1 , 0 , 0 ), ( NULL , 0 , 1 ), ( NULL , 1 , 0 ), ( NULL , 1 , 0 );
  448. query IIIIII rowsort
  449. SELECT * FROM table_f2_f3 JOIN ( table_f3_f4_f5 JOIN table_f4_f5_f6 USING ( f5 ) ) USING ( f3 )
  450. WHERE f6 IS NULL OR f3 >= f6 AND f6 <= 10000 ;
  451. ----
  452. 1 0 0 1 0 1
  453. 1 0 0 1 1 0
  454. 1 0 0 1 NULL 1
  455. 1 0 0 NULL 0 1
  456. 1 0 0 NULL 1 0
  457. 1 0 0 NULL NULL 1
  458. ## -------------------- Tests for WITH MUTUALLY RECURSIVE --------------------
  459. statement ok
  460. CREATE TABLE init(n int, m int, s string);
  461. statement ok
  462. INSERT INTO init VALUES (1, 3, 'aaa'), (2, 4, 'bbb');
  463. # Across Let bindings, and within a Let binding.
  464. # The `WHERE n<5` should be pushed into l0.
  465. # Furthermore, within l0 it should be pushed down on top of the Gets. The Source should also have it.
  466. query T multiline
  467. EXPLAIN OPTIMIZED PLAN WITH (humanized expressions) AS VERBOSE TEXT FOR
  468. WITH MUTUALLY RECURSIVE
  469. c0(n int) AS (
  470. (SELECT n FROM init)
  471. UNION ALL
  472. (SELECT * FROM c2)
  473. ),
  474. c1(n int) AS (
  475. SELECT n+n FROM c0 WHERE n<5
  476. ),
  477. c2(n int) AS (
  478. (SELECT * FROM c0 WHERE n<5)
  479. UNION ALL
  480. (SELECT * FROM c1)
  481. UNION ALL
  482. (SELECT * FROM c1)
  483. )
  484. SELECT * FROM c2;
  485. ----
  486. Explained Query:
  487. With Mutually Recursive
  488. cte l0 =
  489. Union
  490. Project (#0{n})
  491. Filter (#0{n} < 5)
  492. ReadStorage materialize.public.init
  493. Filter (#0{n} < 5)
  494. Get l2
  495. cte l1 =
  496. Project (#1)
  497. Map ((#0{n} + #0{n}))
  498. Get l0
  499. cte l2 =
  500. Union
  501. Get l0
  502. Get l1
  503. Get l1
  504. Return
  505. Get l2
  506. Source materialize.public.init
  507. filter=((#0{n} < 5))
  508. Target cluster: quickstart
  509. EOF
  510. # Here, a pushdown should NOT happen, because not every use of the Get has the predicate.
  511. # That is, the `< 5` predicate should stay inside the `cte l1 =`, and shouldn't appear anywhere else.
  512. query T multiline
  513. EXPLAIN OPTIMIZED PLAN WITH (humanized expressions) AS VERBOSE TEXT FOR
  514. WITH MUTUALLY RECURSIVE
  515. c0(n int) AS (
  516. (SELECT n FROM init)
  517. UNION ALL
  518. (SELECT * FROM c2)
  519. ),
  520. c1(n int) AS (
  521. SELECT n+n FROM c0 WHERE n<5
  522. ),
  523. c2(n int) AS (
  524. (SELECT * FROM c0)
  525. UNION ALL
  526. (SELECT * FROM c1)
  527. UNION ALL
  528. (SELECT * FROM c1)
  529. )
  530. SELECT * FROM c2;
  531. ----
  532. Explained Query:
  533. With Mutually Recursive
  534. cte l0 =
  535. Union
  536. Project (#0{n})
  537. ReadStorage materialize.public.init
  538. Get l2
  539. cte l1 =
  540. Project (#1)
  541. Filter (#0{n} < 5)
  542. Map ((#0{n} + #0{n}))
  543. Get l0
  544. cte l2 =
  545. Union
  546. Get l0
  547. Get l1
  548. Get l1
  549. Return
  550. Get l2
  551. Source materialize.public.init
  552. Target cluster: quickstart
  553. EOF
  554. # Same as the previous query, but the predicate should stay inside the `cte l2 =`
  555. query T multiline
  556. EXPLAIN OPTIMIZED PLAN WITH (humanized expressions) AS VERBOSE TEXT FOR
  557. WITH MUTUALLY RECURSIVE
  558. c0(n int) AS (
  559. (SELECT n FROM init)
  560. UNION ALL
  561. (SELECT * FROM c2)
  562. ),
  563. c1(n int) AS (
  564. SELECT n+n FROM c0
  565. ),
  566. c2(n int) AS (
  567. (SELECT * FROM c0 WHERE n<5)
  568. UNION ALL
  569. (SELECT * FROM c1)
  570. UNION ALL
  571. (SELECT * FROM c1)
  572. )
  573. SELECT * FROM c2;
  574. ----
  575. Explained Query:
  576. With Mutually Recursive
  577. cte l0 =
  578. Union
  579. Project (#0{n})
  580. ReadStorage materialize.public.init
  581. Get l2
  582. cte l1 =
  583. Project (#1)
  584. Map ((#0{n} + #0{n}))
  585. Get l0
  586. cte l2 =
  587. Union
  588. Filter (#0{n} < 5)
  589. Get l0
  590. Get l1
  591. Get l1
  592. Return
  593. Get l2
  594. Source materialize.public.init
  595. Target cluster: quickstart
  596. EOF
  597. # Similar to the previous two queries, but here one of the uses of `l0` is in the body, so this would catch the error
  598. # case of forgetting to call PredicatePushdown's `action` on the `body` of the `LetRec`, whose role here is to make the
  599. # intersection in `get_predicates` empty.
  600. # The predicate should NOT be pushed into the `cte l0 =`, and should stay in both the `cte l2 =` and the `cte l1 =`.
  601. query T multiline
  602. EXPLAIN OPTIMIZED PLAN WITH (humanized expressions) AS VERBOSE TEXT FOR
  603. WITH MUTUALLY RECURSIVE
  604. c0(n int) AS (
  605. (SELECT n FROM init)
  606. UNION ALL
  607. (SELECT * FROM c2)
  608. ),
  609. c1(n int) AS (
  610. SELECT n+n FROM c0 WHERE n<5
  611. ),
  612. c2(n int) AS (
  613. (SELECT * FROM c0 WHERE n<5)
  614. UNION ALL
  615. (SELECT * FROM c1)
  616. UNION ALL
  617. (SELECT * FROM c1)
  618. )
  619. SELECT * FROM ((SELECT * FROM c2) UNION (SELECT * FROM c0));
  620. ----
  621. Explained Query:
  622. With Mutually Recursive
  623. cte l0 =
  624. Union
  625. Project (#0{n})
  626. ReadStorage materialize.public.init
  627. Get l2
  628. cte l1 =
  629. Project (#1)
  630. Filter (#0{n} < 5)
  631. Map ((#0{n} + #0{n}))
  632. Get l0
  633. cte l2 =
  634. Union
  635. Filter (#0{n} < 5)
  636. Get l0
  637. Get l1
  638. Get l1
  639. Return
  640. Distinct project=[#0{n}]
  641. Union
  642. Get l2
  643. Get l0
  644. Source materialize.public.init
  645. Target cluster: quickstart
  646. EOF
  647. # For now, we can’t push from the body into such a Let binding that is being referenced across
  648. # iterations (l2).
  649. # That is, the `> 7` predicate should stay inside the `cte l0 =` and the body.
  650. query T multiline
  651. EXPLAIN OPTIMIZED PLAN WITH (humanized expressions) AS VERBOSE TEXT FOR
  652. WITH MUTUALLY RECURSIVE
  653. c0(n int) AS (
  654. (SELECT n FROM init)
  655. UNION ALL
  656. (SELECT * FROM c2 WHERE n>7)
  657. ),
  658. c1(n int) AS (
  659. SELECT n+n FROM c0
  660. ),
  661. c2(n int) AS (
  662. (SELECT * FROM c0)
  663. UNION ALL
  664. (SELECT * FROM c1)
  665. UNION ALL
  666. (SELECT * FROM c1)
  667. )
  668. SELECT * FROM c2 WHERE n>7;
  669. ----
  670. Explained Query:
  671. With Mutually Recursive
  672. cte l0 =
  673. Union
  674. Project (#0{n})
  675. ReadStorage materialize.public.init
  676. Filter (#0{n} > 7)
  677. Get l2
  678. cte l1 =
  679. Project (#1)
  680. Map ((#0{n} + #0{n}))
  681. Get l0
  682. cte l2 =
  683. Union
  684. Get l0
  685. Get l1
  686. Get l1
  687. Return
  688. Filter (#0{n} > 7)
  689. Get l2
  690. Source materialize.public.init
  691. Target cluster: quickstart
  692. EOF
  693. # We can push down from the body into such a Let binding that is NOT being referenced across
  694. # iterations (l1).
  695. # The `> 7` should end up inside the `cte l1 =`, and should disappear from everywhere else.
  696. query T multiline
  697. EXPLAIN OPTIMIZED PLAN WITH (humanized expressions) AS VERBOSE TEXT FOR
  698. WITH MUTUALLY RECURSIVE
  699. c0(n int) AS (
  700. (SELECT n FROM init)
  701. UNION ALL
  702. (SELECT * FROM c2)
  703. ),
  704. c1(n int) AS (
  705. SELECT n+n FROM c0
  706. ),
  707. c2(n int) AS (
  708. (SELECT * FROM c0)
  709. UNION ALL
  710. (SELECT * FROM c1 WHERE n>7)
  711. UNION ALL
  712. (SELECT * FROM c1 WHERE n>7)
  713. )
  714. SELECT * FROM c1 WHERE n>7;
  715. ----
  716. Explained Query:
  717. With Mutually Recursive
  718. cte l0 =
  719. Union
  720. Project (#0{n})
  721. ReadStorage materialize.public.init
  722. Get l2
  723. cte l1 =
  724. Project (#1)
  725. Filter (#1 > 7)
  726. Map ((#0{n} + #0{n}))
  727. Get l0
  728. cte l2 =
  729. Union
  730. Get l0
  731. Get l1
  732. Get l1
  733. Return
  734. Project (#1)
  735. Filter (#1 > 7)
  736. Map ((#0{n} + #0{n}))
  737. Get l0
  738. Source materialize.public.init
  739. Target cluster: quickstart
  740. EOF
  741. # Even though the only usage of `l2` has a predicate, we don't push that predicate into `l2`,
  742. # because `l2` is being referenced across iterations.
  743. # That is, the `< 3` predicate should stay inside the `cte l0 =`.
  744. query T multiline
  745. EXPLAIN OPTIMIZED PLAN WITH (humanized expressions) AS VERBOSE TEXT FOR
  746. WITH MUTUALLY RECURSIVE
  747. c0(n int) AS (
  748. (SELECT n FROM init)
  749. UNION ALL
  750. (SELECT * FROM c2 WHERE n<3)
  751. ),
  752. c1(n int) AS (
  753. SELECT n+n FROM c0
  754. ),
  755. c2(n int) AS (
  756. (SELECT * FROM c0)
  757. UNION ALL
  758. (SELECT * FROM c1)
  759. UNION ALL
  760. (SELECT * FROM c1)
  761. )
  762. SELECT * FROM c1;
  763. ----
  764. Explained Query:
  765. With Mutually Recursive
  766. cte l0 =
  767. Union
  768. Project (#0{n})
  769. ReadStorage materialize.public.init
  770. Filter (#0{n} < 3)
  771. Get l2
  772. cte l1 =
  773. Project (#1)
  774. Map ((#0{n} + #0{n}))
  775. Get l0
  776. cte l2 =
  777. Union
  778. Get l0
  779. Get l1
  780. Get l1
  781. Return
  782. Project (#1)
  783. Map ((#0{n} + #0{n}))
  784. Get l0
  785. Source materialize.public.init
  786. Target cluster: quickstart
  787. EOF
  788. # Regression test for https://github.com/MaterializeInc/database-issues/issues/5691
  789. statement ok
  790. with
  791. v1 as (
  792. WITH
  793. creates AS
  794. (
  795. SELECT
  796. details ->> 'logical_size' AS size,
  797. details ->> 'replica_id' AS replica_id,
  798. occurred_at
  799. FROM mz_catalog.mz_audit_events
  800. WHERE
  801. object_type = 'cluster-replica' AND event_type = 'create'
  802. )
  803. SELECT
  804. mz_unsafe.mz_error_if_null(
  805. mz_cluster_replica_sizes.credits_per_hour, 'Replica of unknown size'
  806. )
  807. AS credits_per_hour
  808. FROM
  809. creates
  810. LEFT JOIN
  811. mz_catalog.mz_cluster_replica_sizes
  812. ON mz_cluster_replica_sizes.size = creates.size
  813. )
  814. select * from v1
  815. WHERE credits_per_hour > credits_per_hour;
  816. # Regression test for https://github.com/MaterializeInc/database-issues/issues/6049
  817. statement ok
  818. CREATE ROLE r2;
  819. statement ok
  820. SELECT
  821. member.name AS grantee,
  822. role.name AS role_name
  823. FROM mz_role_members membership
  824. JOIN mz_roles role ON membership.role_id = role.id
  825. JOIN mz_roles member ON membership.member = member.id
  826. WHERE pg_has_role('r2', member.oid, 'USAGE');
  827. query error db error: ERROR: role "r555" does not exist
  828. SELECT
  829. member.name AS grantee,
  830. role.name AS role_name
  831. FROM mz_role_members membership
  832. JOIN mz_roles role ON membership.role_id = role.id
  833. JOIN mz_roles member ON membership.member = member.id
  834. WHERE pg_has_role('r555', member.oid, 'USAGE');
  835. query error db error: ERROR: role "aaa" does not exist
  836. select * from (select 'aaa' as aaa) where pg_has_role('r2', aaa, 'USAGE');
  837. # Test when `push_filters_through_map` needs to do several inlining steps on top of each other
  838. statement ok
  839. CREATE TABLE t(x int, y int);
  840. query T multiline
  841. EXPLAIN OPTIMIZED PLAN WITH (humanized expressions) AS VERBOSE TEXT FOR
  842. SELECT *
  843. FROM (
  844. SELECT x, y, x*y as z1, x*y + 1 AS z2
  845. FROM t
  846. )
  847. WHERE z2 > 5;
  848. ----
  849. Explained Query:
  850. Filter (#3 > 5)
  851. Map ((#0{x} * #1{y}), (#2 + 1))
  852. ReadStorage materialize.public.t
  853. Source materialize.public.t
  854. filter=((((#0{x} * #1{y}) + 1) > 5))
  855. Target cluster: quickstart
  856. EOF
  857. statement ok
  858. DROP ROLE r2;
  859. # Regression test for https://github.com/MaterializeInc/database-issues/issues/6714
  860. # The transitive closure computation in `inline_if_not_too_big` has to do more than one step here. For this, later map
  861. # expressions should mention only the previous map expression, but not earlier ones. Also, there has to be at least
  862. # 3 map expressions, so that adding the support of the last one doesn't immediately cover all of the map expressions.
  863. query T multiline
  864. EXPLAIN OPTIMIZED PLAN WITH (humanized expressions) AS VERBOSE TEXT FOR
  865. SELECT * FROM (
  866. SELECT z2 * 4 AS z3
  867. FROM (
  868. SELECT z1 + 1 AS z2
  869. FROM (
  870. SELECT x, y, x*y AS z1
  871. FROM t
  872. )
  873. )
  874. )
  875. WHERE z3 > 5;
  876. ----
  877. Explained Query:
  878. Project (#2)
  879. Filter (#2 > 5)
  880. Map ((((#0{x} * #1{y}) + 1) * 4))
  881. ReadStorage materialize.public.t
  882. Source materialize.public.t
  883. filter=(((((#0{x} * #1{y}) + 1) * 4) > 5))
  884. Target cluster: quickstart
  885. EOF
  886. # Test when `push_filters_through_map` runs into the inlining limit: The source shouldn't have the filter pushed down
  887. # into it.
  888. query T multiline
  889. EXPLAIN OPTIMIZED PLAN WITH (humanized expressions) AS VERBOSE TEXT FOR
  890. SELECT * FROM (
  891. SELECT * FROM (
  892. SELECT *, x + y + z1 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 AS r1
  893. FROM (
  894. SELECT x, y, x*y as z1, x*y + 1 AS z2
  895. FROM t
  896. )
  897. )
  898. )
  899. WHERE r1 * r1 * r1 * r1 * r1 * r1 * r1 * r1 * r1 * r1 * r1 * r1 * r1 > 5;
  900. ----
  901. Explained Query:
  902. Filter (((((((((((((#4{r1} * #4{r1}) * #4{r1}) * #4{r1}) * #4{r1}) * #4{r1}) * #4{r1}) * #4{r1}) * #4{r1}) * #4{r1}) * #4{r1}) * #4{r1}) * #4{r1}) > 5)
  903. Map ((#0{x} * #1{y}), (#2{"?column?"} + 1), ((((((((((((((((((((((((((#0{x} + #1{y}) + #2{z1}) + #3{z2}) + #3{z2}) + #3{z2}) + #3{z2}) + #3{z2}) + #3{z2}) + #3{z2}) + #3{z2}) + #3{z2}) + #3{z2}) + #3{z2}) + #3{z2}) + #3{z2}) + #3{z2}) + #3{z2}) + #3{z2}) + #3{z2}) + #3{z2}) + #3{z2}) + #3{z2}) + #3{z2}) + #3{z2}) + #3{z2}) + #3{z2}))
  904. ReadStorage materialize.public.t
  905. Source materialize.public.t
  906. Target cluster: quickstart
  907. EOF
  908. # Similar test as above, but a bit smaller, so we are below the inlining limit. The source should get the pushdown.
  909. # Also adds more predicates to test a bit more scenarios.
  910. # Also tests that MFP CSE happens for the MFP that is in the source.
  911. query T multiline
  912. EXPLAIN OPTIMIZED PLAN WITH (humanized expressions) AS VERBOSE TEXT FOR
  913. SELECT * FROM (
  914. SELECT * FROM (
  915. SELECT *, x + y + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z2 + z1 AS r1
  916. FROM (
  917. SELECT x, y, x*y as z1, x*y + 1 AS z2
  918. FROM t
  919. )
  920. )
  921. )
  922. WHERE r1 * r1 * r1 * r1 > 5 AND r1 * x * z2 * r1 < z2 * z1 + y AND x < y AND z2 > z1 AND z1 > z2 + r1 + r1;
  923. ----
  924. Explained Query:
  925. Filter (#0{x} < #1{y}) AND (#3 > #2) AND (#2 > ((#3 + #4) + #4)) AND ((((#4 * #4) * #4) * #4) > 5) AND ((((#4 * #0{x}) * #3) * #4) < ((#3 * #2) + #1{y}))
  926. Map ((#0{x} * #1{y}), (#2 + 1), ((((((((((((((((((((((((((#0{x} + #1{y}) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #2))
  927. ReadStorage materialize.public.t
  928. Source materialize.public.t
  929. filter=((#0{x} < #1{y}) AND (#3 > #2) AND ((((#4 * #0{x}) * #3) * #4) < ((#3 * #2) + #1{y})) AND (#2 > ((#3 + #4) + #4)) AND ((((#4 * #4) * #4) * #4) > 5))
  930. map=((#0{x} * #1{y}), (#2 + 1), ((((((((((((((((((((((((((#0{x} + #1{y}) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #3) + #2))
  931. Target cluster: quickstart
  932. EOF