column_knowledge.slt 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791
  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. simple conn=mz_system,user=mz_system
  10. ALTER SYSTEM SET unsafe_enable_table_keys = true
  11. ----
  12. COMPLETE 0
  13. #
  14. # Test various cases of equivalence propagation
  15. #
  16. mode cockroach
  17. statement ok
  18. CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 INTEGER);
  19. statement ok
  20. CREATE TABLE t2 (f1 INTEGER PRIMARY KEY, f2 INTEGER);
  21. statement ok
  22. CREATE TABLE t3 (f1 INTEGER PRIMARY KEY, f2 INTEGER);
  23. # No propagation for single tables
  24. query T multiline
  25. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT * FROM t1 WHERE t1.f1 = 123 AND t1.f1 = t1.f2
  26. ----
  27. Explained Query (fast path):
  28. Filter (#0{f1} = 123) AND (#0{f1} = #1{f2})
  29. PeekPersist materialize.public.t1 [value=(123)]
  30. Target cluster: quickstart
  31. EOF
  32. # Inner joins
  33. query T multiline
  34. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT * FROM t1 , t2 WHERE t1.f1 = 123 AND t1.f1 = t2.f1
  35. ----
  36. Explained Query:
  37. CrossJoin type=differential // { arity: 4 }
  38. implementation
  39. %0:t1[×]Uef » %1:t2[×]Uef
  40. ArrangeBy keys=[[]] // { arity: 2 }
  41. Filter (#0{f1} = 123) // { arity: 2 }
  42. ReadStorage materialize.public.t1 // { arity: 2 }
  43. ArrangeBy keys=[[]] // { arity: 2 }
  44. Filter (#0{f1} = 123) // { arity: 2 }
  45. ReadStorage materialize.public.t2 // { arity: 2 }
  46. Source materialize.public.t1
  47. filter=((#0{f1} = 123))
  48. Source materialize.public.t2
  49. filter=((#0{f1} = 123))
  50. Target cluster: quickstart
  51. EOF
  52. # Outer joins
  53. # TODO the second join should be removed as redundant and replaced with `Get(l1)`.
  54. query T multiline
  55. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT * FROM t1 LEFT JOIN t2 ON (t1.f1 = t2.f1) WHERE t1.f1 = 123;
  56. ----
  57. Explained Query:
  58. With
  59. cte l0 =
  60. Filter (#0{f1} = 123) // { arity: 2 }
  61. ReadStorage materialize.public.t1 // { arity: 2 }
  62. cte l1 =
  63. CrossJoin type=differential // { arity: 4 }
  64. implementation
  65. %0:l0[×]Uef » %1:t2[×]Uef
  66. ArrangeBy keys=[[]] // { arity: 2 }
  67. Get l0 // { arity: 2 }
  68. ArrangeBy keys=[[]] // { arity: 2 }
  69. Filter (#0{f1} = 123) // { arity: 2 }
  70. ReadStorage materialize.public.t2 // { arity: 2 }
  71. Return // { arity: 4 }
  72. Union // { arity: 4 }
  73. Map (null, null) // { arity: 4 }
  74. Union // { arity: 2 }
  75. Negate // { arity: 2 }
  76. Project (#0{f1}, #1{f2}) // { arity: 2 }
  77. Get l1 // { arity: 4 }
  78. Get l0 // { arity: 2 }
  79. Get l1 // { arity: 4 }
  80. Source materialize.public.t1
  81. filter=((#0{f1} = 123))
  82. Source materialize.public.t2
  83. filter=((#0{f1} = 123))
  84. Target cluster: quickstart
  85. EOF
  86. query T multiline
  87. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT * FROM t1 LEFT JOIN t2 USING (f1) WHERE t1.f1 = 123;
  88. ----
  89. Explained Query:
  90. With
  91. cte l0 =
  92. Filter (#0{f1} = 123) // { arity: 2 }
  93. ReadStorage materialize.public.t1 // { arity: 2 }
  94. cte l1 =
  95. CrossJoin type=differential // { arity: 3 }
  96. implementation
  97. %0:l0[×]Uef » %1:t2[×]Uef
  98. ArrangeBy keys=[[]] // { arity: 2 }
  99. Get l0 // { arity: 2 }
  100. ArrangeBy keys=[[]] // { arity: 1 }
  101. Project (#1{f2}) // { arity: 1 }
  102. Filter (#0{f1} = 123) // { arity: 2 }
  103. ReadStorage materialize.public.t2 // { arity: 2 }
  104. Return // { arity: 3 }
  105. Union // { arity: 3 }
  106. Map (null) // { arity: 3 }
  107. Union // { arity: 2 }
  108. Negate // { arity: 2 }
  109. Project (#0{f1}, #1{f2}) // { arity: 2 }
  110. Get l1 // { arity: 3 }
  111. Get l0 // { arity: 2 }
  112. Get l1 // { arity: 3 }
  113. Source materialize.public.t1
  114. filter=((#0{f1} = 123))
  115. Source materialize.public.t2
  116. filter=((#0{f1} = 123))
  117. Target cluster: quickstart
  118. EOF
  119. query T multiline
  120. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT * FROM t1 LEFT JOIN t2 ON (TRUE) WHERE t1.f1 = t2.f1 AND t1.f1 = 123;
  121. ----
  122. Explained Query:
  123. CrossJoin type=differential // { arity: 4 }
  124. implementation
  125. %0:t1[×]Uef » %1:t2[×]Uef
  126. ArrangeBy keys=[[]] // { arity: 2 }
  127. Filter (#0{f1} = 123) // { arity: 2 }
  128. ReadStorage materialize.public.t1 // { arity: 2 }
  129. ArrangeBy keys=[[]] // { arity: 2 }
  130. Filter (#0{f1} = 123) // { arity: 2 }
  131. ReadStorage materialize.public.t2 // { arity: 2 }
  132. Source materialize.public.t1
  133. filter=((#0{f1} = 123))
  134. Source materialize.public.t2
  135. filter=((#0{f1} = 123))
  136. Target cluster: quickstart
  137. EOF
  138. # Transitive application
  139. query T multiline
  140. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT * FROM t1, t2, t3 WHERE t1.f1 = 123 AND t1.f1 = t2.f1 AND t2.f1 = t3.f1;
  141. ----
  142. Explained Query:
  143. CrossJoin type=delta // { arity: 6 }
  144. implementation
  145. %0:t1 » %1:t2[×]Uef » %2:t3[×]Uef
  146. %1:t2 » %0:t1[×]Uef » %2:t3[×]Uef
  147. %2:t3 » %0:t1[×]Uef » %1:t2[×]Uef
  148. ArrangeBy keys=[[]] // { arity: 2 }
  149. Filter (#0{f1} = 123) // { arity: 2 }
  150. ReadStorage materialize.public.t1 // { arity: 2 }
  151. ArrangeBy keys=[[]] // { arity: 2 }
  152. Filter (#0{f1} = 123) // { arity: 2 }
  153. ReadStorage materialize.public.t2 // { arity: 2 }
  154. ArrangeBy keys=[[]] // { arity: 2 }
  155. Filter (#0{f1} = 123) // { arity: 2 }
  156. ReadStorage materialize.public.t3 // { arity: 2 }
  157. Source materialize.public.t1
  158. filter=((#0{f1} = 123))
  159. Source materialize.public.t2
  160. filter=((#0{f1} = 123))
  161. Source materialize.public.t3
  162. filter=((#0{f1} = 123))
  163. Target cluster: quickstart
  164. EOF
  165. # HAVING clause
  166. query T multiline
  167. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT t1.f1 FROM t1, t2 WHERE t1.f1 = t2.f1 GROUP BY t1.f1 HAVING t1.f1 = 123;
  168. ----
  169. Explained Query:
  170. Map (123) // { arity: 1 }
  171. CrossJoin type=differential // { arity: 0 }
  172. implementation
  173. %0:t1[×]Uef » %1:t2[×]Uef
  174. ArrangeBy keys=[[]] // { arity: 0 }
  175. Project () // { arity: 0 }
  176. Filter (#0{f1} = 123) // { arity: 2 }
  177. ReadStorage materialize.public.t1 // { arity: 2 }
  178. ArrangeBy keys=[[]] // { arity: 0 }
  179. Project () // { arity: 0 }
  180. Filter (#0{f1} = 123) // { arity: 2 }
  181. ReadStorage materialize.public.t2 // { arity: 2 }
  182. Source materialize.public.t1
  183. filter=((#0{f1} = 123))
  184. Source materialize.public.t2
  185. filter=((#0{f1} = 123))
  186. Target cluster: quickstart
  187. EOF
  188. #
  189. # Subqueries
  190. #
  191. query T multiline
  192. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT (SELECT t1.f1 FROM t1 WHERE t1.f1 = t2.f1) FROM t2 WHERE t2.f1 = 123;
  193. ----
  194. Explained Query:
  195. With
  196. cte l0 =
  197. Project () // { arity: 0 }
  198. Filter (#0{f1} = 123) // { arity: 2 }
  199. ReadStorage materialize.public.t2 // { arity: 2 }
  200. cte l1 =
  201. ArrangeBy keys=[[]] // { arity: 0 }
  202. Get l0 // { arity: 0 }
  203. cte l2 =
  204. CrossJoin type=differential // { arity: 1 }
  205. implementation
  206. %0:l1[×]Uef » %1:t1[×]Uef
  207. Get l1 // { arity: 0 }
  208. ArrangeBy keys=[[]] // { arity: 1 }
  209. Project (#0{f1}) // { arity: 1 }
  210. Filter (#0{f1} = 123) // { arity: 2 }
  211. ReadStorage materialize.public.t1 // { arity: 2 }
  212. Return // { arity: 1 }
  213. CrossJoin type=differential // { arity: 1 }
  214. implementation
  215. %0:l1[×]Uef » %1[×]Uef
  216. Get l1 // { arity: 0 }
  217. ArrangeBy keys=[[]] // { arity: 1 }
  218. Union // { arity: 1 }
  219. Get l2 // { arity: 1 }
  220. Map (null) // { arity: 1 }
  221. Union // { arity: 0 }
  222. Negate // { arity: 0 }
  223. Project () // { arity: 0 }
  224. Get l2 // { arity: 1 }
  225. Get l0 // { arity: 0 }
  226. Source materialize.public.t1
  227. filter=((#0{f1} = 123))
  228. Source materialize.public.t2
  229. filter=((#0{f1} = 123))
  230. Target cluster: quickstart
  231. EOF
  232. # This case is currently not optimized
  233. query T multiline
  234. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT (SELECT t1.f1 FROM t1) = t2.f1 FROM t2 WHERE t2.f1 = 123;
  235. ----
  236. Explained Query:
  237. With
  238. cte l0 =
  239. Union // { arity: 1 }
  240. Project (#0{f1}) // { arity: 1 }
  241. ReadStorage materialize.public.t1 // { arity: 2 }
  242. Project (#1) // { arity: 1 }
  243. FlatMap guard_subquery_size(#0{count}) // { arity: 2 }
  244. Reduce aggregates=[count(*)] // { arity: 1 }
  245. Project () // { arity: 0 }
  246. ReadStorage materialize.public.t1 // { arity: 2 }
  247. Return // { arity: 1 }
  248. Project (#1) // { arity: 1 }
  249. Map ((#0{f1} = 123)) // { arity: 2 }
  250. CrossJoin type=differential // { arity: 1 }
  251. implementation
  252. %0:t2[×]Uef » %1[×]ef
  253. ArrangeBy keys=[[]] // { arity: 0 }
  254. Project () // { arity: 0 }
  255. Filter (#0{f1} = 123) // { arity: 2 }
  256. ReadStorage materialize.public.t2 // { arity: 2 }
  257. ArrangeBy keys=[[]] // { arity: 1 }
  258. Union // { arity: 1 }
  259. Get l0 // { arity: 1 }
  260. Map (null) // { arity: 1 }
  261. Union // { arity: 0 }
  262. Negate // { arity: 0 }
  263. Distinct project=[] // { arity: 0 }
  264. Project () // { arity: 0 }
  265. Get l0 // { arity: 1 }
  266. Constant // { arity: 0 }
  267. - ()
  268. Source materialize.public.t1
  269. Source materialize.public.t2
  270. filter=((#0{f1} = 123))
  271. Target cluster: quickstart
  272. EOF
  273. query T multiline
  274. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT * FROM t1 WHERE t1.f1 = 123 AND EXISTS (SELECT * FROM t2 WHERE t2.f1 = t1.f1);
  275. ----
  276. Explained Query:
  277. CrossJoin type=differential // { arity: 2 }
  278. implementation
  279. %0:t1[×]Uef » %1:t2[×]Uef
  280. ArrangeBy keys=[[]] // { arity: 2 }
  281. Filter (#0{f1} = 123) // { arity: 2 }
  282. ReadStorage materialize.public.t1 // { arity: 2 }
  283. ArrangeBy keys=[[]] // { arity: 0 }
  284. Project () // { arity: 0 }
  285. Filter (#0{f1} = 123) // { arity: 2 }
  286. ReadStorage materialize.public.t2 // { arity: 2 }
  287. Source materialize.public.t1
  288. filter=((#0{f1} = 123))
  289. Source materialize.public.t2
  290. filter=((#0{f1} = 123))
  291. Target cluster: quickstart
  292. EOF
  293. query T multiline
  294. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT * FROM t1 WHERE t1.f1 = 123 AND EXISTS (SELECT * FROM t2 WHERE t2.f1 = t1.f1) AND EXISTS (SELECT * FROM t3 WHERE t3.f1 = t1.f1);
  295. ----
  296. Explained Query:
  297. CrossJoin type=delta // { arity: 2 }
  298. implementation
  299. %0:t1 » %1:t2[×]Uef » %2:t3[×]Uef
  300. %1:t2 » %0:t1[×]Uef » %2:t3[×]Uef
  301. %2:t3 » %0:t1[×]Uef » %1:t2[×]Uef
  302. ArrangeBy keys=[[]] // { arity: 2 }
  303. Filter (#0{f1} = 123) // { arity: 2 }
  304. ReadStorage materialize.public.t1 // { arity: 2 }
  305. ArrangeBy keys=[[]] // { arity: 0 }
  306. Project () // { arity: 0 }
  307. Filter (#0{f1} = 123) // { arity: 2 }
  308. ReadStorage materialize.public.t2 // { arity: 2 }
  309. ArrangeBy keys=[[]] // { arity: 0 }
  310. Project () // { arity: 0 }
  311. Filter (#0{f1} = 123) // { arity: 2 }
  312. ReadStorage materialize.public.t3 // { arity: 2 }
  313. Source materialize.public.t1
  314. filter=((#0{f1} = 123))
  315. Source materialize.public.t2
  316. filter=((#0{f1} = 123))
  317. Source materialize.public.t3
  318. filter=((#0{f1} = 123))
  319. Target cluster: quickstart
  320. EOF
  321. query T multiline
  322. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT * FROM t1, (SELECT t2.f1 FROM t2) AS dt1 WHERE dt1.f1 = t1.f1 AND t1.f1 = 123;
  323. ----
  324. Explained Query:
  325. CrossJoin type=differential // { arity: 3 }
  326. implementation
  327. %0:t1[×]Uef » %1:t2[×]Uef
  328. ArrangeBy keys=[[]] // { arity: 2 }
  329. Filter (#0{f1} = 123) // { arity: 2 }
  330. ReadStorage materialize.public.t1 // { arity: 2 }
  331. ArrangeBy keys=[[]] // { arity: 1 }
  332. Project (#0{f1}) // { arity: 1 }
  333. Filter (#0{f1} = 123) // { arity: 2 }
  334. ReadStorage materialize.public.t2 // { arity: 2 }
  335. Source materialize.public.t1
  336. filter=((#0{f1} = 123))
  337. Source materialize.public.t2
  338. filter=((#0{f1} = 123))
  339. Target cluster: quickstart
  340. EOF
  341. query T multiline
  342. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT * FROM t1 WHERE 123 = (SELECT t2.f1 FROM t2);
  343. ----
  344. Explained Query:
  345. CrossJoin type=differential // { arity: 2 }
  346. implementation
  347. %0:t1[×] » %1[×]
  348. ArrangeBy keys=[[]] // { arity: 2 }
  349. ReadStorage materialize.public.t1 // { arity: 2 }
  350. ArrangeBy keys=[[]] // { arity: 0 }
  351. Union // { arity: 0 }
  352. Project () // { arity: 0 }
  353. Filter (#0{f1} = 123) // { arity: 2 }
  354. ReadStorage materialize.public.t2 // { arity: 2 }
  355. Project () // { arity: 0 }
  356. Filter (#1 = 123) // { arity: 2 }
  357. FlatMap guard_subquery_size(#0{count}) // { arity: 2 }
  358. Reduce aggregates=[count(*)] // { arity: 1 }
  359. Project () // { arity: 0 }
  360. ReadStorage materialize.public.t2 // { arity: 2 }
  361. Source materialize.public.t1
  362. Source materialize.public.t2
  363. Target cluster: quickstart
  364. EOF
  365. query T multiline
  366. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT * FROM t1 WHERE t1.f1 = 123 AND t1.f1 = (SELECT t2.f1 FROM t2);
  367. ----
  368. Explained Query:
  369. CrossJoin type=differential // { arity: 2 }
  370. implementation
  371. %0:t1[×]Uef » %1[×]ef
  372. ArrangeBy keys=[[]] // { arity: 2 }
  373. Filter (#0{f1} = 123) // { arity: 2 }
  374. ReadStorage materialize.public.t1 // { arity: 2 }
  375. ArrangeBy keys=[[]] // { arity: 0 }
  376. Union // { arity: 0 }
  377. Project () // { arity: 0 }
  378. Filter (#0{f1} = 123) // { arity: 2 }
  379. ReadStorage materialize.public.t2 // { arity: 2 }
  380. Project () // { arity: 0 }
  381. Filter (#1 = 123) // { arity: 2 }
  382. FlatMap guard_subquery_size(#0{count}) // { arity: 2 }
  383. Reduce aggregates=[count(*)] // { arity: 1 }
  384. Project () // { arity: 0 }
  385. ReadStorage materialize.public.t2 // { arity: 2 }
  386. Source materialize.public.t1
  387. filter=((#0{f1} = 123))
  388. Source materialize.public.t2
  389. Target cluster: quickstart
  390. EOF
  391. #
  392. # Multipart keys
  393. #
  394. statement ok
  395. CREATE TABLE t4 (f1 INTEGER, f2 INTEGER, PRIMARY KEY (f1, f2));
  396. query T multiline
  397. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT * FROM t4 AS a1, t4 AS a2 WHERE a1.f1 = 123 AND a1.f2 = 234 AND a1.f1 = a2.f1 AND a1.f2 = a2.f2;
  398. ----
  399. Explained Query (fast path):
  400. Project (#0{f1}, #1{f2}, #0{f1}, #1{f2})
  401. Filter (#0{f1} = 123) AND (#1{f2} = 234)
  402. PeekPersist materialize.public.t4 [value=(123, 234)]
  403. Target cluster: quickstart
  404. EOF
  405. query T multiline
  406. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT * FROM t4 AS a1 LEFT JOIN t4 AS a2 USING (f1, f2) WHERE a1.f1 = 123 AND a1.f2 = 234;
  407. ----
  408. Explained Query (fast path):
  409. Filter (#0{f1} = 123) AND (#1{f2} = 234)
  410. PeekPersist materialize.public.t4 [value=(123, 234)]
  411. Target cluster: quickstart
  412. EOF
  413. #
  414. # Propagation in opposite direction
  415. #
  416. query T multiline
  417. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT * FROM t4 AS a1 LEFT JOIN t4 AS a2 USING (f1, f2) WHERE a1.f1 = 123 AND a2.f2 = 234;
  418. ----
  419. Explained Query (fast path):
  420. Filter (#0{f1} = 123) AND (#1{f2} = 234)
  421. PeekPersist materialize.public.t4 [value=(123, 234)]
  422. Target cluster: quickstart
  423. EOF
  424. #
  425. # Detect impossible conditions
  426. #
  427. query T multiline
  428. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT * FROM t1 LEFT JOIN t2 USING (f1) WHERE t1.f1 = 123 AND t2.f1 = 234;
  429. ----
  430. Explained Query (fast path):
  431. Constant <empty>
  432. Target cluster: quickstart
  433. EOF
  434. #
  435. # The following impossible condition is removed by `CanonicalizeMfp::remove_impossible_or_args`
  436. #
  437. query T multiline
  438. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT * FROM t1 FULL OUTER JOIN t2 USING (f1) WHERE t1.f1 = 123 AND t2.f1 = 234;
  439. ----
  440. Explained Query (fast path):
  441. Constant <empty>
  442. Target cluster: quickstart
  443. EOF
  444. # Inequality between columns
  445. query T multiline
  446. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT * FROM t1, t2 WHERE t1.f1 = 123 AND t1.f1 > t2.f1;
  447. ----
  448. Explained Query:
  449. CrossJoin type=differential // { arity: 4 }
  450. implementation
  451. %0:t1[×]Uef » %1:t2[×]eif
  452. ArrangeBy keys=[[]] // { arity: 2 }
  453. Filter (#0{f1} = 123) // { arity: 2 }
  454. ReadStorage materialize.public.t1 // { arity: 2 }
  455. ArrangeBy keys=[[]] // { arity: 2 }
  456. Filter (123 > #0{f1}) // { arity: 2 }
  457. ReadStorage materialize.public.t2 // { arity: 2 }
  458. Source materialize.public.t1
  459. filter=((#0{f1} = 123))
  460. Source materialize.public.t2
  461. filter=((123 > #0{f1}))
  462. Target cluster: quickstart
  463. EOF
  464. statement ok
  465. create table double_table(double_col DOUBLE);
  466. statement ok
  467. create table int_table(int_col integer NOT NULL);
  468. # TODO: get rid of the unnecessary !isnull at the end of this plan
  469. query T multiline
  470. EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR select * from int_table, double_table where int_table.int_col = double_table.double_col;
  471. ----
  472. Explained Query:
  473. Join on=(#1{double_col} = integer_to_double(#0{int_col})) type=differential // { arity: 2 }
  474. implementation
  475. %0:int_table[integer_to_double(#0{int_col})]K » %1:double_table[#0{double_col}]K
  476. ArrangeBy keys=[[integer_to_double(#0{int_col})]] // { arity: 1 }
  477. ReadStorage materialize.public.int_table // { arity: 1 }
  478. ArrangeBy keys=[[#0{double_col}]] // { arity: 1 }
  479. Filter (#0{double_col}) IS NOT NULL // { arity: 1 }
  480. ReadStorage materialize.public.double_table // { arity: 1 }
  481. Source materialize.public.double_table
  482. filter=((#0{double_col}) IS NOT NULL)
  483. Source materialize.public.int_table
  484. Target cluster: quickstart
  485. EOF
  486. # WITH MUTUALLY RECURSIVE support
  487. # -------------------------------
  488. # Single binding, value knowledge
  489. query T multiline
  490. EXPLAIN OPTIMIZED PLAN WITH(arity, types, humanized expressions) AS VERBOSE TEXT FOR
  491. WITH MUTUALLY RECURSIVE
  492. c0(f1 integer, f2 integer) AS (
  493. SELECT * FROM (
  494. SELECT * FROM t1
  495. UNION
  496. SELECT * FROM c0
  497. ) WHERE f1 = 3 AND f2 = 5
  498. )
  499. SELECT f1, f2, f1 + f2 FROM c0;
  500. ----
  501. Explained Query:
  502. With Mutually Recursive
  503. cte l0 =
  504. Map (3, 5) // { arity: 2, types: "(integer, integer)" }
  505. Distinct project=[] // { arity: 0, types: "()" }
  506. Union // { arity: 0, types: "()" }
  507. Project () // { arity: 0, types: "()" }
  508. Filter (#0{f1} = 3) AND (#1{f2} = 5) // { arity: 2, types: "(integer, integer)" }
  509. ReadStorage materialize.public.t1 // { arity: 2, types: "(integer, integer?)" }
  510. Project () // { arity: 0, types: "()" }
  511. Get l0 // { arity: 2, types: "(integer, integer)" }
  512. Return // { arity: 3, types: "(integer, integer, integer)" }
  513. Map (8) // { arity: 3, types: "(integer, integer, integer)" }
  514. Get l0 // { arity: 2, types: "(integer, integer)" }
  515. Source materialize.public.t1
  516. filter=((#0{f1} = 3) AND (#1{f2} = 5))
  517. Target cluster: quickstart
  518. EOF
  519. # Single binding, NOT NULL knowledge
  520. query T multiline
  521. EXPLAIN OPTIMIZED PLAN WITH(arity, types, humanized expressions) AS VERBOSE TEXT FOR
  522. WITH MUTUALLY RECURSIVE
  523. c0(f1 integer, f2 integer) AS (
  524. SELECT * FROM (
  525. SELECT * FROM t1
  526. UNION
  527. SELECT * FROM c0
  528. ) WHERE f1 IS NOT NULL AND f2 IS NOT NULL
  529. )
  530. SELECT f1, f2, f1 IS NOT NULL, f2 IS NULL FROM c0;
  531. ----
  532. Explained Query:
  533. With Mutually Recursive
  534. cte l0 =
  535. Distinct project=[#0{f1}, #1{f2}] // { arity: 2, types: "(integer, integer)" }
  536. Union // { arity: 2, types: "(integer, integer)" }
  537. Filter (#1{f2}) IS NOT NULL // { arity: 2, types: "(integer, integer)" }
  538. ReadStorage materialize.public.t1 // { arity: 2, types: "(integer, integer?)" }
  539. Get l0 // { arity: 2, types: "(integer, integer)" }
  540. Return // { arity: 4, types: "(integer, integer, boolean, boolean)" }
  541. Map (true, false) // { arity: 4, types: "(integer, integer, boolean, boolean)" }
  542. Get l0 // { arity: 2, types: "(integer, integer)" }
  543. Source materialize.public.t1
  544. filter=((#1{f2}) IS NOT NULL)
  545. Target cluster: quickstart
  546. EOF
  547. # Single binding, NOT NULL knowledge inside a UNION branch
  548. query T multiline
  549. EXPLAIN OPTIMIZED PLAN WITH(arity, types, humanized expressions) AS VERBOSE TEXT FOR
  550. WITH MUTUALLY RECURSIVE
  551. c0(f1 integer, f2 integer) AS (
  552. SELECT * FROM (
  553. SELECT * FROM t1
  554. UNION
  555. SELECT * FROM c0 WHERE f1 IS NOT NULL AND f2 IS NOT NULL
  556. )
  557. )
  558. SELECT f1, f2, f1 IS NOT NULL, f2 IS NULL FROM c0;
  559. ----
  560. Explained Query:
  561. With Mutually Recursive
  562. cte l0 =
  563. Distinct project=[#0{f1}, #1{f2}] // { arity: 2, types: "(integer, integer?)" }
  564. Union // { arity: 2, types: "(integer, integer?)" }
  565. ReadStorage materialize.public.t1 // { arity: 2, types: "(integer, integer?)" }
  566. Filter (#1{f2}) IS NOT NULL // { arity: 2, types: "(integer, integer)" }
  567. Get l0 // { arity: 2, types: "(integer, integer?)" }
  568. Return // { arity: 4, types: "(integer, integer?, boolean, boolean)" }
  569. Project (#0{f1}, #1{f2}, #3, #2) // { arity: 4, types: "(integer, integer?, boolean, boolean)" }
  570. Map ((#1{f2}) IS NULL, true) // { arity: 4, types: "(integer, integer?, boolean, boolean)" }
  571. Get l0 // { arity: 2, types: "(integer, integer?)" }
  572. Source materialize.public.t1
  573. Target cluster: quickstart
  574. EOF
  575. # Multiple bindings, value knowledge
  576. query T multiline
  577. EXPLAIN OPTIMIZED PLAN WITH(arity, types, humanized expressions) AS VERBOSE TEXT FOR
  578. WITH MUTUALLY RECURSIVE
  579. it(count integer) AS (
  580. SELECT 1 UNION SELECT * FROM it WHERE count = 1
  581. ),
  582. c0(count integer, f1 integer, f2 integer) AS (
  583. SELECT * FROM (
  584. SELECT count * 2, f1, f2 FROM it, t1
  585. UNION
  586. SELECT * FROM c0
  587. )
  588. )
  589. SELECT * FROM c0;
  590. ----
  591. Explained Query:
  592. With Mutually Recursive
  593. cte l0 =
  594. Map (1) // { arity: 1, types: "(integer)" }
  595. Distinct project=[] monotonic // { arity: 0, types: "()" }
  596. Union // { arity: 0, types: "()" }
  597. Project () // { arity: 0, types: "()" }
  598. Get l0 // { arity: 1, types: "(integer)" }
  599. Constant // { arity: 0, types: "()" }
  600. - ()
  601. cte l1 =
  602. Project (#2, #0{f1}, #1{f2}) // { arity: 3, types: "(integer, integer, integer?)" }
  603. Map (2) // { arity: 3, types: "(integer, integer?, integer)" }
  604. Distinct project=[#0{f1}, #1{f2}] // { arity: 2, types: "(integer, integer?)" }
  605. Union // { arity: 2, types: "(integer, integer?)" }
  606. CrossJoin type=differential // { arity: 2, types: "(integer, integer?)" }
  607. ArrangeBy keys=[[]] // { arity: 0, types: "()" }
  608. Project () // { arity: 0, types: "()" }
  609. Get l0 // { arity: 1, types: "(integer)" }
  610. ArrangeBy keys=[[]] // { arity: 2, types: "(integer, integer?)" }
  611. ReadStorage materialize.public.t1 // { arity: 2, types: "(integer, integer?)" }
  612. Project (#1{f1}, #2{f2}) // { arity: 2, types: "(integer, integer?)" }
  613. Get l1 // { arity: 3, types: "(integer, integer, integer?)" }
  614. Return // { arity: 3, types: "(integer, integer, integer?)" }
  615. Get l1 // { arity: 3, types: "(integer, integer, integer?)" }
  616. Source materialize.public.t1
  617. Target cluster: quickstart
  618. EOF
  619. # Multiple bindings, NOT NULL knowledge
  620. #
  621. # This is currently masked by identical work done by the "non_nullable"
  622. # transform. I had to swap the order of "non_nullable" and "column_knowledge" to
  623. # see this transform in action in https://optimizer-trace.dev.materialize.com/.
  624. query T multiline
  625. EXPLAIN OPTIMIZED PLAN WITH(arity, types, humanized expressions) AS VERBOSE TEXT FOR
  626. WITH MUTUALLY RECURSIVE
  627. it(count integer) AS (
  628. SELECT 1 UNION SELECT * FROM it WHERE count IS NOT NULL
  629. ),
  630. c0(count_is_null boolean, f1 integer, f2 integer) AS (
  631. SELECT * FROM (
  632. SELECT count IS NULL, f1, f2 FROM it, t1
  633. UNION
  634. SELECT * FROM c0
  635. )
  636. )
  637. SELECT * FROM c0;
  638. ----
  639. Explained Query:
  640. With Mutually Recursive
  641. cte l0 =
  642. Map (1) // { arity: 1, types: "(integer)" }
  643. Distinct project=[] monotonic // { arity: 0, types: "()" }
  644. Union // { arity: 0, types: "()" }
  645. Project () // { arity: 0, types: "()" }
  646. Get l0 // { arity: 1, types: "(integer)" }
  647. Constant // { arity: 0, types: "()" }
  648. - ()
  649. cte l1 =
  650. Project (#2, #0{f1}, #1{f2}) // { arity: 3, types: "(boolean, integer, integer?)" }
  651. Map (false) // { arity: 3, types: "(integer, integer?, boolean)" }
  652. Distinct project=[#0{f1}, #1{f2}] // { arity: 2, types: "(integer, integer?)" }
  653. Union // { arity: 2, types: "(integer, integer?)" }
  654. CrossJoin type=differential // { arity: 2, types: "(integer, integer?)" }
  655. ArrangeBy keys=[[]] // { arity: 0, types: "()" }
  656. Project () // { arity: 0, types: "()" }
  657. Get l0 // { arity: 1, types: "(integer)" }
  658. ArrangeBy keys=[[]] // { arity: 2, types: "(integer, integer?)" }
  659. ReadStorage materialize.public.t1 // { arity: 2, types: "(integer, integer?)" }
  660. Project (#1{f1}, #2{f2}) // { arity: 2, types: "(integer, integer?)" }
  661. Get l1 // { arity: 3, types: "(boolean, integer, integer?)" }
  662. Return // { arity: 3, types: "(boolean, integer, integer?)" }
  663. Get l1 // { arity: 3, types: "(boolean, integer, integer?)" }
  664. Source materialize.public.t1
  665. Target cluster: quickstart
  666. EOF
  667. statement ok
  668. SELECT mz_internal.mz_minimal_name_qualification(COALESCE(pg_catalog.string_to_array(pg_catalog."current_role"(), pg_catalog."user"()), COALESCE(mz_internal.mz_normalize_object_name(NULL), pg_catalog.regexp_match(CAST(0 AS text), CAST(0 AS text)))), mz_catalog.mz_version()) AS c1;