relax_must_consolidate.slt 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228
  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. #
  10. # Test relaxation of the must_consolidate flag in LIR refinements
  11. # for single-time dataflows (aka monotonic one-shot `SELECT`s).
  12. # PR https://github.com/MaterializeInc/materialize/pull/19680
  13. #
  14. statement ok
  15. CREATE TABLE t (a int, b int);
  16. statement ok
  17. INSERT INTO t VALUES (9, 1), (8, 2), (7, 3), (6, 4), (5, 5);
  18. statement ok
  19. DELETE FROM t WHERE b % 2 = 0;
  20. # Get that is non-monotonic, must_consolidate
  21. query II
  22. SELECT MIN(b), MAX(a)
  23. FROM (
  24. SELECT a, b FROM t
  25. );
  26. ----
  27. 1
  28. 9
  29. query T multiline
  30. EXPLAIN PHYSICAL PLAN AS VERBOSE TEXT FOR
  31. SELECT MIN(b), MAX(a)
  32. FROM (
  33. SELECT a, b
  34. FROM t
  35. );
  36. ----
  37. Explained Query:
  38. With
  39. cte l0 =
  40. Reduce::Hierarchical
  41. aggr_funcs=[min, max]
  42. skips=[0, 0]
  43. monotonic
  44. must_consolidate
  45. val_plan
  46. project=(#1, #0)
  47. key_plan
  48. project=()
  49. Get::PassArrangements materialize.public.t
  50. raw=true
  51. Return
  52. Union
  53. ArrangeBy
  54. input_key=[]
  55. raw=true
  56. Get::PassArrangements l0
  57. raw=false
  58. arrangements[0]={ key=[], permutation=id, thinning=(#0, #1) }
  59. Mfp
  60. project=(#0, #1)
  61. map=(null, null)
  62. Union consolidate_output=true
  63. Negate
  64. Get::Arrangement l0
  65. project=()
  66. key=
  67. raw=false
  68. arrangements[0]={ key=[], permutation=id, thinning=(#0, #1) }
  69. Constant
  70. - ()
  71. Source materialize.public.t
  72. Target cluster: quickstart
  73. EOF
  74. # Mfp on non-monotonic Get, must_consolidate
  75. query II
  76. SELECT MIN(a), MAX(b)
  77. FROM (
  78. SELECT b, a
  79. FROM t
  80. WHERE a % 2 = 1
  81. );
  82. ----
  83. 5
  84. 5
  85. query T multiline
  86. EXPLAIN PHYSICAL PLAN AS VERBOSE TEXT FOR
  87. SELECT MIN(a), MAX(b)
  88. FROM (
  89. SELECT b, a
  90. FROM t
  91. WHERE a % 2 = 1
  92. );
  93. ----
  94. Explained Query:
  95. With
  96. cte l0 =
  97. Reduce::Hierarchical
  98. aggr_funcs=[min, max]
  99. skips=[0, 0]
  100. monotonic
  101. must_consolidate
  102. val_plan=id
  103. key_plan
  104. project=()
  105. Get::Collection materialize.public.t
  106. raw=true
  107. Return
  108. Union
  109. ArrangeBy
  110. input_key=[]
  111. raw=true
  112. Get::PassArrangements l0
  113. raw=false
  114. arrangements[0]={ key=[], permutation=id, thinning=(#0, #1) }
  115. Mfp
  116. project=(#0, #1)
  117. map=(null, null)
  118. Union consolidate_output=true
  119. Negate
  120. Get::Arrangement l0
  121. project=()
  122. key=
  123. raw=false
  124. arrangements[0]={ key=[], permutation=id, thinning=(#0, #1) }
  125. Constant
  126. - ()
  127. Source materialize.public.t
  128. filter=((1 = (#0{a} % 2)))
  129. Target cluster: quickstart
  130. EOF
  131. # FlatMap on non-monotonic Get, must_consolidate
  132. query II
  133. SELECT MIN(a), MAX(b)
  134. FROM (
  135. SELECT b, generate_series(1, a) AS a
  136. FROM t
  137. );
  138. ----
  139. 1
  140. 5
  141. query T multiline
  142. EXPLAIN PHYSICAL PLAN AS VERBOSE TEXT FOR
  143. SELECT MIN(a), MAX(b)
  144. FROM (
  145. SELECT b, generate_series(1, a) AS a
  146. FROM t
  147. );
  148. ----
  149. Explained Query:
  150. With
  151. cte l0 =
  152. Reduce::Hierarchical
  153. aggr_funcs=[min, max]
  154. skips=[0, 0]
  155. monotonic
  156. must_consolidate
  157. val_plan
  158. project=(#1, #0)
  159. key_plan
  160. project=()
  161. FlatMap generate_series(1, #0{a}, 1)
  162. mfp_after
  163. project=(#1, #2)
  164. Get::PassArrangements materialize.public.t
  165. raw=true
  166. Return
  167. Union
  168. ArrangeBy
  169. input_key=[]
  170. raw=true
  171. Get::PassArrangements l0
  172. raw=false
  173. arrangements[0]={ key=[], permutation=id, thinning=(#0, #1) }
  174. Mfp
  175. project=(#0, #1)
  176. map=(null, null)
  177. Union consolidate_output=true
  178. Negate
  179. Get::Arrangement l0
  180. project=()
  181. key=
  182. raw=false
  183. arrangements[0]={ key=[], permutation=id, thinning=(#0, #1) }
  184. Constant
  185. - ()
  186. Source materialize.public.t
  187. Target cluster: quickstart
  188. EOF
  189. # Union of non-monotonic Get's, must_consolidate
  190. query II
  191. SELECT MIN(b), MAX(a)
  192. FROM (
  193. SELECT a, b
  194. FROM t
  195. WHERE a % 2 = 1
  196. UNION ALL
  197. SELECT a, b
  198. FROM t
  199. WHERE a % 2 = 0
  200. );
  201. ----
  202. 1
  203. 9
  204. query T multiline
  205. EXPLAIN PHYSICAL PLAN AS VERBOSE TEXT FOR
  206. SELECT MIN(b), MAX(a)
  207. FROM (
  208. SELECT a, b
  209. FROM t
  210. WHERE a % 2 = 1
  211. UNION ALL
  212. SELECT a, b
  213. FROM t
  214. WHERE a % 2 = 0
  215. );
  216. ----
  217. Explained Query:
  218. With
  219. cte l0 =
  220. Reduce::Hierarchical
  221. aggr_funcs=[min, max]
  222. skips=[0, 0]
  223. monotonic
  224. must_consolidate
  225. val_plan
  226. project=(#1, #0)
  227. key_plan
  228. project=()
  229. Union
  230. Get::Collection materialize.public.t
  231. project=(#0, #1)
  232. filter=((1 = #2))
  233. raw=true
  234. Get::Collection materialize.public.t
  235. project=(#0, #1)
  236. filter=((0 = #2))
  237. raw=true
  238. Return
  239. Union
  240. ArrangeBy
  241. input_key=[]
  242. raw=true
  243. Get::PassArrangements l0
  244. raw=false
  245. arrangements[0]={ key=[], permutation=id, thinning=(#0, #1) }
  246. Mfp
  247. project=(#0, #1)
  248. map=(null, null)
  249. Union consolidate_output=true
  250. Negate
  251. Get::Arrangement l0
  252. project=()
  253. key=
  254. raw=false
  255. arrangements[0]={ key=[], permutation=id, thinning=(#0, #1) }
  256. Constant
  257. - ()
  258. Source materialize.public.t
  259. project=(#0..=#2)
  260. map=((#0{a} % 2))
  261. Target cluster: quickstart
  262. EOF
  263. # Threshold, no must_consolidate
  264. query II
  265. SELECT MIN(b), MAX(a)
  266. FROM (
  267. SELECT a, b
  268. FROM t
  269. WHERE a % 2 = 1
  270. EXCEPT ALL
  271. SELECT a, b
  272. FROM t
  273. WHERE a % 2 = 0
  274. );
  275. ----
  276. 1
  277. 9
  278. query T multiline
  279. EXPLAIN PHYSICAL PLAN AS VERBOSE TEXT FOR
  280. SELECT MIN(b), MAX(a)
  281. FROM (
  282. SELECT a, b
  283. FROM t
  284. WHERE a % 2 = 1
  285. EXCEPT ALL
  286. SELECT a, b
  287. FROM t
  288. WHERE a % 2 = 0
  289. );
  290. ----
  291. Explained Query:
  292. With
  293. cte l0 =
  294. Reduce::Hierarchical
  295. aggr_funcs=[min, max]
  296. skips=[0, 0]
  297. monotonic
  298. val_plan
  299. project=(#1, #0)
  300. key_plan
  301. project=()
  302. input_key=#0, #1
  303. Threshold::Basic ensure_arrangement={ key=[#0, #1], permutation=id, thinning=() }
  304. ArrangeBy
  305. raw=false
  306. arrangements[0]={ key=[#0, #1], permutation=id, thinning=() }
  307. types=[integer, integer?]
  308. Union consolidate_output=true
  309. Get::Collection materialize.public.t
  310. project=(#0, #1)
  311. filter=((1 = #2))
  312. raw=true
  313. Negate
  314. Get::Collection materialize.public.t
  315. project=(#0, #1)
  316. filter=((0 = #2))
  317. raw=true
  318. Return
  319. Union
  320. ArrangeBy
  321. input_key=[]
  322. raw=true
  323. Get::PassArrangements l0
  324. raw=false
  325. arrangements[0]={ key=[], permutation=id, thinning=(#0, #1) }
  326. Mfp
  327. project=(#0, #1)
  328. map=(null, null)
  329. Union consolidate_output=true
  330. Negate
  331. Get::Arrangement l0
  332. project=()
  333. key=
  334. raw=false
  335. arrangements[0]={ key=[], permutation=id, thinning=(#0, #1) }
  336. Constant
  337. - ()
  338. Source materialize.public.t
  339. project=(#0..=#2)
  340. map=((#0{a} % 2))
  341. Target cluster: quickstart
  342. EOF
  343. # Join on non-monotonic Get's, must_consolidate
  344. statement ok
  345. CREATE INDEX t_idx ON t(b);
  346. query II
  347. SELECT MIN(a), MAX(b)
  348. FROM (
  349. SELECT *
  350. FROM (
  351. SELECT a, b
  352. FROM t
  353. WHERE a % 2 = 1
  354. ) JOIN (
  355. SELECT a, b
  356. FROM t
  357. WHERE a = 5
  358. ) USING (a, b)
  359. );
  360. ----
  361. 5
  362. 5
  363. query T multiline
  364. EXPLAIN PHYSICAL PLAN AS VERBOSE TEXT FOR
  365. SELECT MIN(a), MAX(b)
  366. FROM (
  367. SELECT *
  368. FROM (
  369. SELECT a, b
  370. FROM t
  371. WHERE a % 2 = 1
  372. ) JOIN (
  373. SELECT a, b
  374. FROM t
  375. WHERE a = 5
  376. ) USING (a, b)
  377. );
  378. ----
  379. Explained Query:
  380. With
  381. cte l0 =
  382. Get::PassArrangements materialize.public.t
  383. raw=false
  384. arrangements[0]={ key=[#1{b}], permutation={#0: #1, #1: #0}, thinning=(#0) }
  385. types=[integer?, integer?]
  386. cte l1 =
  387. Reduce::Hierarchical
  388. aggr_funcs=[max]
  389. skips=[0]
  390. monotonic
  391. must_consolidate
  392. val_plan=id
  393. key_plan
  394. project=()
  395. Join::Linear
  396. linear_stage[0]
  397. closure
  398. project=(#0)
  399. filter=((#0{b}) IS NOT NULL AND (#1{a} = 5) AND (1 = (#1{a} % 2)) AND (#2{a} = 5))
  400. lookup={ relation=1, key=[#1{b}] }
  401. stream={ key=[#1{b}], thinning=(#0) }
  402. source={ relation=0, key=[#1{b}] }
  403. Get::PassArrangements l0
  404. raw=false
  405. arrangements[0]={ key=[#1{b}], permutation={#0: #1, #1: #0}, thinning=(#0) }
  406. types=[integer?, integer?]
  407. Get::PassArrangements l0
  408. raw=false
  409. arrangements[0]={ key=[#1{b}], permutation={#0: #1, #1: #0}, thinning=(#0) }
  410. types=[integer?, integer?]
  411. Return
  412. Union
  413. Get::Arrangement l1
  414. project=(#1, #0)
  415. map=(5)
  416. key=
  417. raw=false
  418. arrangements[0]={ key=[], permutation=id, thinning=(#0) }
  419. Mfp
  420. project=(#0, #1)
  421. map=(null, null)
  422. Union consolidate_output=true
  423. Negate
  424. Get::Arrangement l1
  425. project=()
  426. key=
  427. raw=false
  428. arrangements[0]={ key=[], permutation=id, thinning=(#0) }
  429. Constant
  430. - ()
  431. Used Indexes:
  432. - materialize.public.t_idx (differential join)
  433. Target cluster: quickstart
  434. EOF
  435. statement ok
  436. DROP INDEX t_idx;
  437. # Join on `ArrangeBy`s that arrange in-query, unfortunately must_consolidate
  438. # TODO(vmarcos): We set must_consolidate here because we do not know if the
  439. # `raw` form will be used. If a join had a way to not use the `raw` collection,
  440. # but only the arrangement built as part of the query (e.g., by attaching to its
  441. # stream instead), then we would have the opportunity to turn must_consolidate
  442. # off. The present analysis would need to be slightly extended then to detect if:
  443. # (a) The input to `ArrangeBy` is not arranged; (b) The `raw` form is set to
  444. # `false`; and (c) An arranged `form` is requested.
  445. query II
  446. SELECT MIN(a), MAX(b)
  447. FROM (
  448. SELECT *
  449. FROM (
  450. SELECT a, b
  451. FROM t
  452. WHERE a % 2 = 1
  453. ) JOIN (
  454. SELECT a, b
  455. FROM t
  456. WHERE a = 5
  457. ) USING (a, b)
  458. );
  459. ----
  460. 5
  461. 5
  462. query T multiline
  463. EXPLAIN PHYSICAL PLAN AS VERBOSE TEXT FOR
  464. SELECT MIN(a), MAX(b)
  465. FROM (
  466. SELECT *
  467. FROM (
  468. SELECT a, b
  469. FROM t
  470. WHERE a % 2 = 1
  471. ) JOIN (
  472. SELECT a, b
  473. FROM t
  474. WHERE a = 5
  475. ) USING (a, b)
  476. );
  477. ----
  478. Explained Query:
  479. With
  480. cte l0 =
  481. Reduce::Hierarchical
  482. aggr_funcs=[max]
  483. skips=[0]
  484. monotonic
  485. must_consolidate
  486. val_plan=id
  487. key_plan
  488. project=()
  489. Join::Linear
  490. linear_stage[0]
  491. lookup={ relation=1, key=[#0{b}] }
  492. stream={ key=[#0{b}], thinning=() }
  493. source={ relation=0, key=[#0{b}] }
  494. ArrangeBy
  495. raw=true
  496. arrangements[0]={ key=[#0{b}], permutation=id, thinning=() }
  497. types=[integer]
  498. Get::Collection materialize.public.t
  499. project=(#1)
  500. filter=((1 = (#0{a} % 2)))
  501. raw=true
  502. ArrangeBy
  503. raw=true
  504. arrangements[0]={ key=[#0{b}], permutation=id, thinning=() }
  505. types=[integer]
  506. Get::Collection materialize.public.t
  507. project=(#1)
  508. raw=true
  509. Return
  510. Union
  511. Get::Arrangement l0
  512. project=(#1, #0)
  513. map=(5)
  514. key=
  515. raw=false
  516. arrangements[0]={ key=[], permutation=id, thinning=(#0) }
  517. Mfp
  518. project=(#0, #1)
  519. map=(null, null)
  520. Union consolidate_output=true
  521. Negate
  522. Get::Arrangement l0
  523. project=()
  524. key=
  525. raw=false
  526. arrangements[0]={ key=[], permutation=id, thinning=(#0) }
  527. Constant
  528. - ()
  529. Source materialize.public.t
  530. filter=((#0{a} = 5) AND (#1{b}) IS NOT NULL)
  531. Target cluster: quickstart
  532. EOF
  533. # Reduce, with aggregates, is an enforcer, no must_consolidate
  534. query II
  535. SELECT MIN(b), MAX(sum_a)
  536. FROM (
  537. SELECT b, SUM(a) AS sum_a
  538. FROM t
  539. GROUP BY b
  540. );
  541. ----
  542. 1
  543. 9
  544. query T multiline
  545. EXPLAIN PHYSICAL PLAN AS VERBOSE TEXT FOR
  546. SELECT MIN(b), MAX(sum_a)
  547. FROM (
  548. SELECT b, SUM(a) AS sum_a
  549. FROM t
  550. GROUP BY b
  551. );
  552. ----
  553. Explained Query:
  554. With
  555. cte l0 =
  556. Reduce::Hierarchical
  557. aggr_funcs=[min, max]
  558. skips=[0, 0]
  559. monotonic
  560. val_plan=id
  561. key_plan
  562. project=()
  563. input_key=#0
  564. Reduce::Accumulable
  565. simple_aggrs[0]=(0, 0, sum(#0{a}))
  566. val_plan
  567. project=(#0)
  568. key_plan
  569. project=(#1)
  570. Get::PassArrangements materialize.public.t
  571. raw=true
  572. Return
  573. Union
  574. ArrangeBy
  575. input_key=[]
  576. raw=true
  577. Get::PassArrangements l0
  578. raw=false
  579. arrangements[0]={ key=[], permutation=id, thinning=(#0, #1) }
  580. Mfp
  581. project=(#0, #1)
  582. map=(null, null)
  583. Union consolidate_output=true
  584. Negate
  585. Get::Arrangement l0
  586. project=()
  587. key=
  588. raw=false
  589. arrangements[0]={ key=[], permutation=id, thinning=(#0, #1) }
  590. Constant
  591. - ()
  592. Source materialize.public.t
  593. Target cluster: quickstart
  594. EOF
  595. # Reduce, no aggregates, is an enforcer, no must_consolidate
  596. query II
  597. SELECT MIN(a), MAX(b)
  598. FROM (
  599. SELECT DISTINCT b, a FROM t
  600. );
  601. ----
  602. 5
  603. 5
  604. query T multiline
  605. EXPLAIN PHYSICAL PLAN AS VERBOSE TEXT FOR
  606. SELECT MIN(a), MAX(b)
  607. FROM (
  608. SELECT DISTINCT b, a FROM t
  609. );
  610. ----
  611. Explained Query:
  612. With
  613. cte l0 =
  614. Reduce::Hierarchical
  615. aggr_funcs=[min, max]
  616. skips=[0, 0]
  617. monotonic
  618. val_plan
  619. project=(#1, #0)
  620. key_plan
  621. project=()
  622. input_key=#0, #1
  623. Reduce::Distinct
  624. val_plan
  625. project=()
  626. key_plan
  627. project=(#1, #0)
  628. Get::PassArrangements materialize.public.t
  629. raw=true
  630. Return
  631. Union
  632. ArrangeBy
  633. input_key=[]
  634. raw=true
  635. Get::PassArrangements l0
  636. raw=false
  637. arrangements[0]={ key=[], permutation=id, thinning=(#0, #1) }
  638. Mfp
  639. project=(#0, #1)
  640. map=(null, null)
  641. Union consolidate_output=true
  642. Negate
  643. Get::Arrangement l0
  644. project=()
  645. key=
  646. raw=false
  647. arrangements[0]={ key=[], permutation=id, thinning=(#0, #1) }
  648. Constant
  649. - ()
  650. Source materialize.public.t
  651. Target cluster: quickstart
  652. EOF
  653. # Get, Union, FlatMap chained from Reduce enforcer, no must_consolidate
  654. statement ok
  655. CREATE VIEW single_time_monotonic_t AS
  656. SELECT b, a, COUNT(*) AS c FROM t GROUP BY b, a;
  657. query III
  658. SELECT * FROM single_time_monotonic_t;
  659. ----
  660. 1
  661. 9
  662. 1
  663. 3
  664. 7
  665. 1
  666. 5
  667. 5
  668. 1
  669. query II
  670. WITH input AS (
  671. SELECT a, b, c
  672. FROM single_time_monotonic_t
  673. WHERE a % 2 = 1
  674. UNION ALL
  675. SELECT a, b, c
  676. FROM single_time_monotonic_t
  677. WHERE c % 2 = 1
  678. )
  679. SELECT MIN(a), MAX(b)
  680. FROM (
  681. SELECT b, generate_series(1, a) AS a
  682. FROM input
  683. WHERE a + 1 = 6 AND c + 1 = 2
  684. );
  685. ----
  686. 1
  687. 5
  688. query T multiline
  689. EXPLAIN PHYSICAL PLAN AS VERBOSE TEXT FOR
  690. WITH input AS (
  691. SELECT a, b, c
  692. FROM single_time_monotonic_t
  693. WHERE a % 2 = 1
  694. UNION ALL
  695. SELECT a, b, c
  696. FROM single_time_monotonic_t
  697. WHERE c % 2 = 1
  698. )
  699. SELECT MIN(a), MAX(b)
  700. FROM (
  701. SELECT b, generate_series(1, a) AS a
  702. FROM input
  703. WHERE a + 1 = 6 AND c + 1 = 2
  704. );
  705. ----
  706. Explained Query:
  707. With
  708. cte l0 =
  709. Reduce::Accumulable
  710. simple_aggrs[0]=(0, 0, count(*))
  711. val_plan
  712. project=(#2)
  713. map=(true)
  714. key_plan
  715. project=(#1, #0)
  716. mfp_after
  717. filter=((2 = (#2{c} + 1)))
  718. Get::Collection materialize.public.t
  719. raw=true
  720. cte l1 =
  721. Reduce::Hierarchical
  722. aggr_funcs=[min, max]
  723. skips=[0, 0]
  724. monotonic
  725. val_plan
  726. project=(#1, #0)
  727. key_plan
  728. project=()
  729. FlatMap generate_series(1, #1{a}, 1)
  730. mfp_after
  731. project=(#0, #2)
  732. Union
  733. Get::Arrangement l0
  734. project=(#0, #1)
  735. filter=((1 = (#1{a} % 2)))
  736. key=#0, #1
  737. raw=false
  738. arrangements[0]={ key=[#0, #1], permutation=id, thinning=(#2) }
  739. Get::Arrangement l0
  740. project=(#0, #1)
  741. filter=((1 = (#2{c} % 2)))
  742. key=#0, #1
  743. raw=false
  744. arrangements[0]={ key=[#0, #1], permutation=id, thinning=(#2) }
  745. Return
  746. Union
  747. ArrangeBy
  748. input_key=[]
  749. raw=true
  750. Get::PassArrangements l1
  751. raw=false
  752. arrangements[0]={ key=[], permutation=id, thinning=(#0, #1) }
  753. Mfp
  754. project=(#0, #1)
  755. map=(null, null)
  756. Union consolidate_output=true
  757. Negate
  758. Get::Arrangement l1
  759. project=()
  760. key=
  761. raw=false
  762. arrangements[0]={ key=[], permutation=id, thinning=(#0, #1) }
  763. Constant
  764. - ()
  765. Source materialize.public.t
  766. filter=((6 = (#0 + 1)))
  767. Target cluster: quickstart
  768. EOF
  769. # Top-1 is an enforcer, no must_consolidate
  770. query II
  771. SELECT MIN(b), MAX(a)
  772. FROM (
  773. SELECT DISTINCT ON(a) a, b
  774. FROM t
  775. ORDER BY a, b DESC
  776. );
  777. ----
  778. 1
  779. 9
  780. query T multiline
  781. EXPLAIN PHYSICAL PLAN AS VERBOSE TEXT FOR
  782. SELECT MIN(b), MAX(a)
  783. FROM (
  784. SELECT DISTINCT ON(a) a, b
  785. FROM t
  786. ORDER BY a, b DESC
  787. );
  788. ----
  789. Explained Query:
  790. With
  791. cte l0 =
  792. Reduce::Hierarchical
  793. aggr_funcs=[min, max]
  794. skips=[0, 0]
  795. monotonic
  796. val_plan
  797. project=(#1, #0)
  798. key_plan
  799. project=()
  800. TopK::MonotonicTop1 group_by=[#0] order_by=[#1 desc nulls_first] must_consolidate
  801. Get::PassArrangements materialize.public.t
  802. raw=true
  803. Return
  804. Union
  805. ArrangeBy
  806. input_key=[]
  807. raw=true
  808. Get::PassArrangements l0
  809. raw=false
  810. arrangements[0]={ key=[], permutation=id, thinning=(#0, #1) }
  811. Mfp
  812. project=(#0, #1)
  813. map=(null, null)
  814. Union consolidate_output=true
  815. Negate
  816. Get::Arrangement l0
  817. project=()
  818. key=
  819. raw=false
  820. arrangements[0]={ key=[], permutation=id, thinning=(#0, #1) }
  821. Constant
  822. - ()
  823. Source materialize.public.t
  824. Target cluster: quickstart
  825. EOF
  826. # Top-k is an enforcer, no must_consolidate
  827. query II
  828. SELECT MIN(b), MAX(a)
  829. FROM (
  830. SELECT a, b
  831. FROM t
  832. ORDER BY b DESC
  833. LIMIT 2
  834. );
  835. ----
  836. 3
  837. 7
  838. query T multiline
  839. EXPLAIN PHYSICAL PLAN AS VERBOSE TEXT FOR
  840. SELECT MIN(b), MAX(a)
  841. FROM (
  842. SELECT a, b
  843. FROM t
  844. ORDER BY b DESC
  845. LIMIT 2
  846. );
  847. ----
  848. Explained Query:
  849. With
  850. cte l0 =
  851. Reduce::Hierarchical
  852. aggr_funcs=[min, max]
  853. skips=[0, 0]
  854. monotonic
  855. val_plan
  856. project=(#1, #0)
  857. key_plan
  858. project=()
  859. TopK::MonotonicTopK order_by=[#1 desc nulls_first] limit=2 must_consolidate
  860. Get::PassArrangements materialize.public.t
  861. raw=true
  862. Return
  863. Union
  864. ArrangeBy
  865. input_key=[]
  866. raw=true
  867. Get::PassArrangements l0
  868. raw=false
  869. arrangements[0]={ key=[], permutation=id, thinning=(#0, #1) }
  870. Mfp
  871. project=(#0, #1)
  872. map=(null, null)
  873. Union consolidate_output=true
  874. Negate
  875. Get::Arrangement l0
  876. project=()
  877. key=
  878. raw=false
  879. arrangements[0]={ key=[], permutation=id, thinning=(#0, #1) }
  880. Constant
  881. - ()
  882. Source materialize.public.t
  883. Target cluster: quickstart
  884. EOF
  885. # Top-1 can have no must_consolidate, not only min/max
  886. query II
  887. SELECT DISTINCT ON(max_a) max_a, b
  888. FROM (
  889. SELECT b, MAX(a) AS max_a
  890. FROM t
  891. GROUP BY b
  892. )
  893. ORDER BY max_a, b DESC;
  894. ----
  895. 5
  896. 5
  897. 7
  898. 3
  899. 9
  900. 1
  901. query T multiline
  902. EXPLAIN PHYSICAL PLAN AS VERBOSE TEXT FOR
  903. SELECT DISTINCT ON(max_a) max_a, b
  904. FROM (
  905. SELECT b, MAX(a) AS max_a
  906. FROM t
  907. GROUP BY b
  908. )
  909. ORDER BY max_a, b DESC;
  910. ----
  911. Explained Query:
  912. Finish order_by=[#0 asc nulls_last, #1 desc nulls_first] output=[#0, #1]
  913. TopK::MonotonicTop1 group_by=[#0] order_by=[#1 desc nulls_first]
  914. Mfp
  915. project=(#1, #0)
  916. input_key=#0
  917. Reduce::Hierarchical
  918. aggr_funcs=[max]
  919. skips=[0]
  920. monotonic
  921. must_consolidate
  922. val_plan
  923. project=(#0)
  924. key_plan
  925. project=(#1)
  926. Get::PassArrangements materialize.public.t
  927. raw=true
  928. Source materialize.public.t
  929. Target cluster: quickstart
  930. EOF
  931. # Top-k can have no must_consolidate, not only min/max.
  932. # In addition, the lack of need for must_consolidate
  933. # propagates through Mfp to a higher-level min/max.
  934. query I
  935. SELECT MAX(max_a)
  936. FROM (
  937. SELECT max_a, b
  938. FROM (
  939. SELECT b, MAX(a) AS max_a
  940. FROM t
  941. GROUP BY b
  942. )
  943. ORDER BY b DESC
  944. LIMIT 2
  945. );
  946. ----
  947. 7
  948. query T multiline
  949. EXPLAIN PHYSICAL PLAN AS VERBOSE TEXT FOR
  950. SELECT MAX(max_a)
  951. FROM (
  952. SELECT max_a, b
  953. FROM (
  954. SELECT b, MAX(a) AS max_a
  955. FROM t
  956. GROUP BY b
  957. )
  958. ORDER BY b DESC
  959. LIMIT 2
  960. );
  961. ----
  962. Explained Query:
  963. With
  964. cte l0 =
  965. Reduce::Hierarchical
  966. aggr_funcs=[max]
  967. skips=[0]
  968. monotonic
  969. val_plan=id
  970. key_plan
  971. project=()
  972. Mfp
  973. project=(#1)
  974. TopK::MonotonicTopK order_by=[#0 desc nulls_first] limit=2
  975. ArrangeBy
  976. input_key=[#0]
  977. raw=true
  978. Reduce::Hierarchical
  979. aggr_funcs=[max]
  980. skips=[0]
  981. monotonic
  982. must_consolidate
  983. val_plan
  984. project=(#0)
  985. key_plan
  986. project=(#1)
  987. Get::PassArrangements materialize.public.t
  988. raw=true
  989. Return
  990. Union
  991. ArrangeBy
  992. input_key=[]
  993. raw=true
  994. Get::PassArrangements l0
  995. raw=false
  996. arrangements[0]={ key=[], permutation=id, thinning=(#0) }
  997. Mfp
  998. project=(#0)
  999. map=(null)
  1000. Union consolidate_output=true
  1001. Negate
  1002. Get::Arrangement l0
  1003. project=()
  1004. key=
  1005. raw=false
  1006. arrangements[0]={ key=[], permutation=id, thinning=(#0) }
  1007. Constant
  1008. - ()
  1009. Source materialize.public.t
  1010. Target cluster: quickstart
  1011. EOF
  1012. # Monotonic constant, no must_consolidate
  1013. query I
  1014. SELECT MAX(a)
  1015. FROM (
  1016. SELECT generate_series(1, 20000) AS a
  1017. );
  1018. ----
  1019. 20000
  1020. query T multiline
  1021. EXPLAIN PHYSICAL PLAN AS VERBOSE TEXT FOR
  1022. SELECT MAX(a)
  1023. FROM (
  1024. SELECT generate_series(1, 20000) AS a
  1025. );
  1026. ----
  1027. Explained Query:
  1028. With
  1029. cte l0 =
  1030. Reduce::Hierarchical
  1031. aggr_funcs=[max]
  1032. skips=[0]
  1033. monotonic
  1034. val_plan=id
  1035. key_plan
  1036. project=()
  1037. FlatMap generate_series(1, 20000, 1)
  1038. Constant
  1039. - ()
  1040. Return
  1041. Union
  1042. ArrangeBy
  1043. input_key=[]
  1044. raw=true
  1045. Get::PassArrangements l0
  1046. raw=false
  1047. arrangements[0]={ key=[], permutation=id, thinning=(#0) }
  1048. Mfp
  1049. project=(#0)
  1050. map=(null)
  1051. Union consolidate_output=true
  1052. Negate
  1053. Get::Arrangement l0
  1054. project=()
  1055. key=
  1056. raw=false
  1057. arrangements[0]={ key=[], permutation=id, thinning=(#0) }
  1058. Constant
  1059. - ()
  1060. Target cluster: quickstart
  1061. EOF
  1062. # Recursive context: No refinement of monotonic operators in recursive terms,
  1063. # so must_consolidate does not even apply to those. For operators outside that
  1064. # consume from a recursive term, must_consolidate is set as we cannot guarantee
  1065. # monotonicity for now even if the term is morally monotonic.
  1066. query I
  1067. WITH MUTUALLY RECURSIVE input(a int) AS (
  1068. SELECT generate_series(1, 40000) AS a
  1069. UNION
  1070. SELECT DISTINCT ON(a) a
  1071. FROM input
  1072. WHERE a > 20000
  1073. )
  1074. SELECT MAX(a)
  1075. FROM input;
  1076. ----
  1077. 40000
  1078. query T multiline
  1079. EXPLAIN PHYSICAL PLAN AS VERBOSE TEXT FOR
  1080. WITH MUTUALLY RECURSIVE input(a int) AS (
  1081. SELECT generate_series(1, 40000) AS a
  1082. UNION
  1083. SELECT DISTINCT ON(a) a
  1084. FROM input
  1085. WHERE a > 20000
  1086. )
  1087. SELECT MAX(a)
  1088. FROM input;
  1089. ----
  1090. Explained Query:
  1091. With Mutually Recursive
  1092. cte l0 =
  1093. ArrangeBy
  1094. input_key=[#0]
  1095. raw=true
  1096. Reduce::Distinct
  1097. val_plan
  1098. project=()
  1099. key_plan=id
  1100. Union
  1101. FlatMap generate_series(1, 40000, 1)
  1102. Constant
  1103. - ()
  1104. TopK::Basic group_by=[#0] limit=1
  1105. Get::Collection l0
  1106. filter=((#0{a} > 20000))
  1107. raw=true
  1108. Return
  1109. With
  1110. cte l1 =
  1111. Reduce::Hierarchical
  1112. aggr_funcs=[max]
  1113. skips=[0]
  1114. monotonic
  1115. must_consolidate
  1116. val_plan=id
  1117. key_plan
  1118. project=()
  1119. Get::PassArrangements l0
  1120. raw=true
  1121. Return
  1122. Union
  1123. ArrangeBy
  1124. input_key=[]
  1125. raw=true
  1126. Get::PassArrangements l1
  1127. raw=false
  1128. arrangements[0]={ key=[], permutation=id, thinning=(#0) }
  1129. Mfp
  1130. project=(#0)
  1131. map=(null)
  1132. Union consolidate_output=true
  1133. Negate
  1134. Get::Arrangement l1
  1135. project=()
  1136. key=
  1137. raw=false
  1138. arrangements[0]={ key=[], permutation=id, thinning=(#0) }
  1139. Constant
  1140. - ()
  1141. Target cluster: quickstart
  1142. EOF