diff --git a/pkg/sql/opt/exec/execbuilder/testdata/tpch_vec b/pkg/sql/opt/exec/execbuilder/testdata/tpch_vec index 878b2c0c45ca..6859b6dedc08 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/tpch_vec +++ b/pkg/sql/opt/exec/execbuilder/testdata/tpch_vec @@ -20925,48 +20925,31 @@ EXPLAIN (VEC) SELECT sum(l_extendedprice* (1 - l_discount)) AS revenue FROM line └ *colexec.orderedAggregator └ *colexecproj.projMultFloat64Float64Op └ *colexecprojconst.projMinusFloat64ConstFloat64Op - └ *colexec.caseOp - ├ *colexec.bufferOp - │ └ *colexecjoin.hashJoiner - │ ├ *colexecsel.selEQBytesBytesConstOp - │ │ └ *colexec.selectInOpBytes - │ │ └ *colfetcher.ColBatchScan - │ └ *colexecsel.selGEInt64Int64ConstOp - │ └ *colfetcher.ColBatchScan - ├ *colexecbase.constBoolOp - │ └ *colexec.orProjOp - │ ├ *colexec.bufferOp - │ ├ *colexec.andProjOp - │ │ ├ *colexec.andProjOp - │ │ │ ├ *colexec.andProjOp - │ │ │ │ ├ *colexec.andProjOp - │ │ │ │ │ ├ *colexecprojconst.projEQBytesBytesConstOp - │ │ │ │ │ └ *colexec.projectInOpBytes - │ │ │ │ └ *colexecprojconst.projGEFloat64Float64ConstOp - │ │ │ └ *colexecprojconst.projLEFloat64Float64ConstOp - │ │ └ *colexecprojconst.projLEInt64Int64ConstOp - │ └ *colexec.andProjOp - │ ├ *colexec.andProjOp - │ │ ├ *colexec.andProjOp - │ │ │ ├ *colexec.andProjOp - │ │ │ │ ├ *colexecprojconst.projEQBytesBytesConstOp - │ │ │ │ └ *colexec.projectInOpBytes - │ │ │ └ *colexecprojconst.projGEFloat64Float64ConstOp - │ │ └ *colexecprojconst.projLEFloat64Float64ConstOp - │ └ *colexecprojconst.projLEInt64Int64ConstOp - ├ *colexecbase.constBoolOp - │ └ *colexec.andProjOp - │ ├ *colexec.bufferOp - │ ├ *colexec.andProjOp - │ │ ├ *colexec.andProjOp - │ │ │ ├ *colexec.andProjOp - │ │ │ │ ├ *colexecprojconst.projEQBytesBytesConstOp - │ │ │ │ └ *colexec.projectInOpBytes - │ │ │ └ *colexecprojconst.projGEFloat64Float64ConstOp - │ │ └ *colexecprojconst.projLEFloat64Float64ConstOp - │ └ *colexecprojconst.projLEInt64Int64ConstOp - └ *colexecbase.constBoolOp - └ *colexec.bufferOp + └ *colexec.UnorderedDistinct + └ *colexec.SerialUnorderedSynchronizer + ├ *rowexec.joinReader + │ └ *rowexec.joinReader + │ └ *colexec.selectInOpBytes + │ └ *colexecsel.selEQBytesBytesConstOp + │ └ *colexecsel.selLEInt64Int64ConstOp + │ └ *colexecsel.selGEInt64Int64ConstOp + │ └ *colfetcher.ColBatchScan + └ *colexec.UnorderedDistinct + └ *colexec.SerialUnorderedSynchronizer + ├ *rowexec.joinReader + │ └ *rowexec.joinReader + │ └ *colexec.selectInOpBytes + │ └ *colexecsel.selEQBytesBytesConstOp + │ └ *colexecsel.selLEInt64Int64ConstOp + │ └ *colexecsel.selGEInt64Int64ConstOp + │ └ *colfetcher.ColBatchScan + └ *rowexec.joinReader + └ *rowexec.joinReader + └ *colexec.selectInOpBytes + └ *colexecsel.selEQBytesBytesConstOp + └ *colexecsel.selLEInt64Int64ConstOp + └ *colexecsel.selGEInt64Int64ConstOp + └ *colfetcher.ColBatchScan # Query 20 query T diff --git a/pkg/sql/opt/memo/testdata/stats/join b/pkg/sql/opt/memo/testdata/stats/join index 875d1da25421..5f82f52256eb 100644 --- a/pkg/sql/opt/memo/testdata/stats/join +++ b/pkg/sql/opt/memo/testdata/stats/join @@ -1648,20 +1648,92 @@ ALTER TABLE uv INJECT STATISTICS '[ opt SELECT * FROM xysd, uv WHERE (s = 'foo' AND u = 3 AND v = 4) OR (s = 'bar' AND u = 5 AND v = 6) ---- -inner-join (cross) +project ├── columns: x:1(int!null) y:2(int) s:3(string!null) d:4(decimal!null) u:7(int!null) v:8(int!null) ├── stats: [rows=59573.61, distinct(3)=2, null(3)=0, distinct(7)=2, null(7)=0, distinct(8)=2, null(8)=0, distinct(7,8)=2.18365, null(7,8)=0] ├── fd: (1)-->(2-4), (3,4)-->(1,2) - ├── scan uv - │ ├── columns: u:7(int) v:8(int!null) - │ └── stats: [rows=10000, distinct(7)=500, null(7)=0, distinct(8)=100, null(8)=0, distinct(7,8)=550, null(7,8)=0] - ├── scan xysd - │ ├── columns: x:1(int!null) y:2(int) s:3(string) d:4(decimal!null) - │ ├── stats: [rows=5000, distinct(1)=5000, null(1)=0, distinct(3)=10, null(3)=0, distinct(4)=500, null(4)=0] - │ ├── key: (1) - │ └── fd: (1)-->(2-4), (3,4)~~>(1,2) - └── filters - └── (((s:3 = 'foo') AND (u:7 = 3)) AND (v:8 = 4)) OR (((s:3 = 'bar') AND (u:7 = 5)) AND (v:8 = 6)) [type=bool, outer=(3,7,8), constraints=(/3: [/'bar' - /'bar'] [/'foo' - /'foo']; /7: [/3 - /3] [/5 - /5]; /8: [/4 - /4] [/6 - /6])] + └── distinct-on + ├── columns: x:1(int!null) y:2(int) s:3(string!null) d:4(decimal!null) u:7(int!null) v:8(int!null) rowid:9(int!null) + ├── grouping columns: x:1(int!null) rowid:9(int!null) + ├── stats: [rows=16383.64, distinct(1,9)=16383.6, null(1,9)=0] + ├── key: (1,9) + ├── fd: (1,9)-->(2-4,7,8) + ├── union-all + │ ├── columns: x:1(int!null) y:2(int) s:3(string!null) d:4(decimal!null) u:7(int!null) v:8(int!null) rowid:9(int!null) + │ ├── left columns: x:12(int) y:13(int) s:14(string) d:15(decimal) u:18(int) v:19(int) rowid:20(int) + │ ├── right columns: x:23(int) y:24(int) s:25(string) d:26(decimal) u:29(int) v:30(int) rowid:31(int) + │ ├── stats: [rows=16383.64, distinct(1,9)=16383.6, null(1,9)=0] + │ ├── inner-join (cross) + │ │ ├── columns: x:12(int!null) y:13(int) s:14(string!null) d:15(decimal!null) u:18(int!null) v:19(int!null) rowid:20(int!null) + │ │ ├── stats: [rows=8191.818, distinct(12,20)=8191.82, null(12,20)=0] + │ │ ├── key: (12,20) + │ │ ├── fd: ()-->(14,18,19), (12)-->(13,15), (15)-->(12,13) + │ │ ├── index-join xysd + │ │ │ ├── columns: x:12(int!null) y:13(int) s:14(string!null) d:15(decimal!null) + │ │ │ ├── stats: [rows=500, distinct(12)=500, null(12)=0, distinct(14)=1, null(14)=0] + │ │ │ ├── key: (12) + │ │ │ ├── fd: ()-->(14), (12)-->(13,15), (15)-->(12,13) + │ │ │ └── scan xysd@xysd_s_d_key + │ │ │ ├── columns: x:12(int!null) s:14(string!null) d:15(decimal!null) + │ │ │ ├── constraint: /-14/15: [/'foo' - /'foo'] + │ │ │ ├── stats: [rows=500, distinct(14)=1, null(14)=0] + │ │ │ ├── key: (12) + │ │ │ └── fd: ()-->(14), (12)-->(15), (15)-->(12) + │ │ ├── select + │ │ │ ├── columns: u:18(int!null) v:19(int!null) rowid:20(int!null) + │ │ │ ├── stats: [rows=16.38364, distinct(18)=1, null(18)=0, distinct(19)=1, null(19)=0, distinct(20)=16.3836, null(20)=0, distinct(18,19)=1, null(18,19)=0] + │ │ │ ├── key: (20) + │ │ │ ├── fd: ()-->(18,19) + │ │ │ ├── scan uv + │ │ │ │ ├── columns: u:18(int) v:19(int!null) rowid:20(int!null) + │ │ │ │ ├── stats: [rows=10000, distinct(18)=500, null(18)=0, distinct(19)=100, null(19)=0, distinct(20)=10000, null(20)=0, distinct(18,19)=550, null(18,19)=0] + │ │ │ │ ├── key: (20) + │ │ │ │ └── fd: (20)-->(18,19) + │ │ │ └── filters + │ │ │ ├── u:18 = 3 [type=bool, outer=(18), constraints=(/18: [/3 - /3]; tight), fd=()-->(18)] + │ │ │ └── v:19 = 4 [type=bool, outer=(19), constraints=(/19: [/4 - /4]; tight), fd=()-->(19)] + │ │ └── filters (true) + │ └── inner-join (cross) + │ ├── columns: x:23(int!null) y:24(int) s:25(string!null) d:26(decimal!null) u:29(int!null) v:30(int!null) rowid:31(int!null) + │ ├── stats: [rows=8191.818, distinct(23,31)=8191.82, null(23,31)=0] + │ ├── key: (23,31) + │ ├── fd: ()-->(25,29,30), (23)-->(24,26), (26)-->(23,24) + │ ├── index-join xysd + │ │ ├── columns: x:23(int!null) y:24(int) s:25(string!null) d:26(decimal!null) + │ │ ├── stats: [rows=500, distinct(23)=500, null(23)=0, distinct(25)=1, null(25)=0] + │ │ ├── key: (23) + │ │ ├── fd: ()-->(25), (23)-->(24,26), (26)-->(23,24) + │ │ └── scan xysd@xysd_s_d_key + │ │ ├── columns: x:23(int!null) s:25(string!null) d:26(decimal!null) + │ │ ├── constraint: /-25/26: [/'bar' - /'bar'] + │ │ ├── stats: [rows=500, distinct(25)=1, null(25)=0] + │ │ ├── key: (23) + │ │ └── fd: ()-->(25), (23)-->(26), (26)-->(23) + │ ├── select + │ │ ├── columns: u:29(int!null) v:30(int!null) rowid:31(int!null) + │ │ ├── stats: [rows=16.38364, distinct(29)=1, null(29)=0, distinct(30)=1, null(30)=0, distinct(31)=16.3836, null(31)=0, distinct(29,30)=1, null(29,30)=0] + │ │ ├── key: (31) + │ │ ├── fd: ()-->(29,30) + │ │ ├── scan uv + │ │ │ ├── columns: u:29(int) v:30(int!null) rowid:31(int!null) + │ │ │ ├── stats: [rows=10000, distinct(29)=500, null(29)=0, distinct(30)=100, null(30)=0, distinct(31)=10000, null(31)=0, distinct(29,30)=550, null(29,30)=0] + │ │ │ ├── key: (31) + │ │ │ └── fd: (31)-->(29,30) + │ │ └── filters + │ │ ├── u:29 = 5 [type=bool, outer=(29), constraints=(/29: [/5 - /5]; tight), fd=()-->(29)] + │ │ └── v:30 = 6 [type=bool, outer=(30), constraints=(/30: [/6 - /6]; tight), fd=()-->(30)] + │ └── filters (true) + └── aggregations + ├── const-agg [as=y:2, type=int, outer=(2)] + │ └── y:2 [type=int] + ├── const-agg [as=s:3, type=string, outer=(3)] + │ └── s:3 [type=string] + ├── const-agg [as=d:4, type=decimal, outer=(4)] + │ └── d:4 [type=decimal] + ├── const-agg [as=u:7, type=int, outer=(7)] + │ └── u:7 [type=int] + └── const-agg [as=v:8, type=int, outer=(8)] + └── v:8 [type=int] # Test selectivity of ORed join predicates # Estimate of # rows should be low, and nowhere near the no-stats diff --git a/pkg/sql/opt/memo/testdata/stats_quality/tpch/q19 b/pkg/sql/opt/memo/testdata/stats_quality/tpch/q19 index b3f6b29d1b1f..24f96fd2f6d3 100644 --- a/pkg/sql/opt/memo/testdata/stats_quality/tpch/q19 +++ b/pkg/sql/opt/memo/testdata/stats_quality/tpch/q19 @@ -67,67 +67,233 @@ scalar-group-by │ ├── columns: column30:30(float!null) │ ├── immutable │ ├── stats: [rows=185.5999, distinct(30)=185.559, null(30)=0] - │ ├── inner-join (hash) - │ │ ├── save-table-name: q19_inner_join_3 + │ ├── project + │ │ ├── save-table-name: q19_project_3 │ │ ├── columns: l_partkey:2(int!null) l_quantity:5(float!null) l_extendedprice:6(float!null) l_discount:7(float!null) l_shipinstruct:14(char!null) l_shipmode:15(char!null) p_partkey:19(int!null) p_brand:22(char!null) p_size:24(int!null) p_container:25(char!null) - │ │ ├── multiplicity: left-rows(zero-or-one), right-rows(zero-or-more) │ │ ├── stats: [rows=185.5999, distinct(2)=185.6, null(2)=0, distinct(5)=5.55556, null(5)=0, distinct(6)=185.55, null(6)=0, distinct(7)=11, null(7)=0, distinct(14)=1, null(14)=0, distinct(15)=2, null(15)=0, distinct(19)=185.6, null(19)=0, distinct(22)=3, null(22)=0, distinct(24)=16.6667, null(24)=0, distinct(25)=12, null(25)=0, distinct(6,7)=185.559, null(6,7)=0, distinct(22,24,25)=185.6, null(22,24,25)=0] │ │ ├── fd: ()-->(14), (19)-->(22,24,25), (2)==(19), (19)==(2) - │ │ ├── select - │ │ │ ├── save-table-name: q19_select_4 - │ │ │ ├── columns: l_partkey:2(int!null) l_quantity:5(float!null) l_extendedprice:6(float!null) l_discount:7(float!null) l_shipinstruct:14(char!null) l_shipmode:15(char!null) - │ │ │ ├── stats: [rows=416015.1, distinct(2)=176353, null(2)=0, distinct(5)=50, null(5)=0, distinct(6)=344687, null(6)=0, distinct(7)=11, null(7)=0, distinct(14)=1, null(14)=0, distinct(15)=2, null(15)=0, distinct(6,7)=416015, null(6,7)=0, distinct(14,15)=2, null(14,15)=0] - │ │ │ │ histogram(14)= 0 4.1602e+05 - │ │ │ │ <--- 'DELIVER IN PERSON' - │ │ │ │ histogram(15)= 0 2.0613e+05 0 2.0988e+05 - │ │ │ │ <---- 'AIR' ----- 'AIR REG' - │ │ │ ├── fd: ()-->(14) - │ │ │ ├── scan lineitem - │ │ │ │ ├── save-table-name: q19_scan_5 - │ │ │ │ ├── columns: l_partkey:2(int!null) l_quantity:5(float!null) l_extendedprice:6(float!null) l_discount:7(float!null) l_shipinstruct:14(char!null) l_shipmode:15(char!null) - │ │ │ │ └── stats: [rows=6001215, distinct(2)=199241, null(2)=0, distinct(5)=50, null(5)=0, distinct(6)=925955, null(6)=0, distinct(7)=11, null(7)=0, distinct(14)=4, null(14)=0, distinct(15)=7, null(15)=0, distinct(6,7)=6.00122e+06, null(6,7)=0, distinct(14,15)=28, null(14,15)=0] - │ │ │ │ histogram(2)= 0 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 1200 29406 600 29406 600 29406 600 29406 600 28806 1200 28806 1200 29406 600 29406 600 29406 600 29406 600 28806 1200 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 1200 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 1200 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 28806 1200 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 1200 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 29406 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 29406 1200 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 30006 600 - │ │ │ │ <--- 1 ------- 1010 ------- 2021 ------- 2991 ------- 3884 ------- 5037 ------- 6245 ------- 7212 ------- 8245 ------- 9154 ------- 10259 ------- 11255 ------- 12046 ------- 13289 ------- 14181 ------- 15137 ------- 16032 ------- 17172 ------- 18410 ------- 19491 ------- 20333 ------- 21223 ------- 22309 ------- 23246 ------- 24374 ------- 25350 ------- 26537 ------- 27310 ------- 28392 ------- 29739 ------- 30950 ------- 31941 ------- 33097 ------- 33985 ------- 34802 ------- 35684 ------- 36612 ------- 37384 ------- 38411 ------- 39549 ------- 40551 ------- 41405 ------- 42339 ------- 43330 ------- 44225 ------- 45263 ------- 46110 ------- 47040 ------- 48028 ------- 48915 ------- 49799 ------- 50642 ------- 51505 ------- 52630 ------- 53961 ------- 54897 ------- 55868 ------- 56689 ------- 57415 ------- 58518 ------- 59669 ------- 60830 ------- 61995 ------- 63158 ------- 63865 ------- 64886 ------- 65607 ------- 66597 ------- 67661 ------- 68633 ------- 69805 ------- 70863 ------- 71876 ------- 73029 ------- 74162 ------- 74986 ------- 76076 ------- 76985 ------- 77776 ------- 78508 ------- 79548 ------- 80396 ------- 81456 ------- 82333 ------- 83231 ------- 84386 ------- 85300 ------- 86272 ------- 87463 ------- 88529 ------- 89522 ------- 90306 ------- 91426 ------- 92473 ------- 93517 ------- 94593 ------- 95575 ------- 96574 ------- 97504 ------- 98485 ------- 99367 ------- 100491 ------- 101417 ------- 102577 ------- 103708 ------- 104704 ------- 105507 ------- 106609 ------- 107562 ------- 108737 ------- 109864 ------- 110773 ------- 111601 ------- 112703 ------- 113643 ------- 114751 ------- 115554 ------- 116375 ------- 117312 ------- 118175 ------- 119101 ------- 120011 ------- 120960 ------- 121864 ------- 122791 ------- 123795 ------- 124770 ------- 125769 ------- 126755 ------- 127543 ------- 128685 ------- 129867 ------- 130997 ------- 131919 ------- 133103 ------- 134064 ------- 134881 ------- 135973 ------- 136848 ------- 137915 ------- 139143 ------- 140073 ------- 141060 ------- 141836 ------- 142825 ------- 143705 ------- 144771 ------- 146062 ------- 147034 ------- 147999 ------- 148876 ------- 149779 ------- 151087 ------- 152065 ------- 153127 ------- 154130 ------- 155112 ------- 156203 ------- 157156 ------- 158209 ------- 159141 ------- 160322 ------- 161399 ------- 162398 ------- 163341 ------- 164401 ------- 165792 ------- 166940 ------- 167888 ------- 168873 ------- 169587 ------- 170828 ------- 172084 ------- 172929 ------- 174080 ------- 175179 ------- 176285 ------- 177380 ------- 178290 ------- 179162 ------- 180295 ------- 181480 ------- 182534 ------- 183776 ------- 184856 ------- 185893 ------- 186994 ------- 187717 ------- 188760 ------- 189696 ------- 190738 ------- 191579 ------- 192799 ------- 193728 ------- 194863 ------- 195849 ------- 196821 ------- 197744 ------- 198749 ------- 199990 - │ │ │ │ histogram(5)= 0 1.1342e+05 5.766e+06 1.2182e+05 - │ │ │ │ <----- 1.0 ---------------- 50.0 -- - │ │ │ │ histogram(6)= 0 600 6e+06 600 - │ │ │ │ <--- 929.02 ------- 104249.0 - │ │ │ │ histogram(7)= 0 5.4971e+05 4.9108e+06 5.4071e+05 - │ │ │ │ <----- 0.0 ----------------- 0.1 --- - │ │ │ │ histogram(14)= 0 1.5093e+06 2.949e+06 1.5429e+06 - │ │ │ │ <--- 'COLLECT COD' ----------- 'TAKE BACK RETURN' - │ │ │ │ histogram(15)= 0 8.3897e+05 4.2711e+06 8.9118e+05 - │ │ │ │ <---- 'AIR' -------------- 'TRUCK' - - │ │ │ └── filters - │ │ │ ├── l_shipmode:15 IN ('AIR', 'AIR REG') [type=bool, outer=(15), constraints=(/15: [/'AIR' - /'AIR'] [/'AIR REG' - /'AIR REG']; tight)] - │ │ │ └── l_shipinstruct:14 = 'DELIVER IN PERSON' [type=bool, outer=(14), constraints=(/14: [/'DELIVER IN PERSON' - /'DELIVER IN PERSON']; tight), fd=()-->(14)] - │ │ ├── select - │ │ │ ├── save-table-name: q19_select_6 - │ │ │ ├── columns: p_partkey:19(int!null) p_brand:22(char!null) p_size:24(int!null) p_container:25(char!null) - │ │ │ ├── stats: [rows=200000, distinct(19)=199241, null(19)=0, distinct(22)=25, null(22)=0, distinct(24)=50, null(24)=0, distinct(25)=40, null(25)=0, distinct(22,24,25)=50000, null(22,24,25)=0] - │ │ │ │ histogram(24)= 0 4240 1.9186e+05 3900 - │ │ │ │ <--- 1 ------------- 50 - │ │ │ ├── key: (19) - │ │ │ ├── fd: (19)-->(22,24,25) - │ │ │ ├── scan part - │ │ │ │ ├── save-table-name: q19_scan_7 - │ │ │ │ ├── columns: p_partkey:19(int!null) p_brand:22(char!null) p_size:24(int!null) p_container:25(char!null) - │ │ │ │ ├── stats: [rows=200000, distinct(19)=199241, null(19)=0, distinct(22)=25, null(22)=0, distinct(24)=50, null(24)=0, distinct(25)=40, null(25)=0, distinct(22,24,25)=50000, null(22,24,25)=0] - │ │ │ │ │ histogram(19)= 0 3.9982 929.57 3.9982 1135.5 3.9982 923.58 3.9982 1036.5 3.9982 964.56 3.9982 953.56 3.9982 899.59 3.9982 1152.5 3.9982 1118.5 3.9982 1137.5 3.9982 1129.5 3.9982 1136.5 3.9982 983.55 3.9982 983.55 3.9982 1028.5 3.9982 1007.5 3.9982 1036.5 3.9982 884.59 3.9982 985.55 3.9982 970.55 3.9982 1036.5 3.9982 943.57 3.9982 1020.5 3.9982 1001.5 3.9982 1001.5 3.9982 954.56 3.9982 1036.5 3.9982 990.54 3.9982 928.57 3.9982 1010.5 3.9982 892.59 3.9982 960.56 3.9982 1059.5 3.9982 947.56 3.9982 906.58 3.9982 935.57 3.9982 860.6 3.9982 971.55 3.9982 1067.5 3.9982 994.54 3.9982 961.56 3.9982 943.57 3.9982 901.59 3.9982 972.55 3.9982 956.56 3.9982 1106.5 3.9982 1152.5 3.9982 967.55 3.9982 943.57 3.9982 916.58 3.9982 1076.5 3.9982 933.57 3.9982 1108.5 3.9982 1081.5 3.9982 975.55 3.9982 1021.5 3.9982 1034.5 3.9982 905.58 3.9982 902.58 3.9982 966.56 3.9982 1080.5 3.9982 927.57 3.9982 936.57 3.9982 1008.5 3.9982 1033.5 3.9982 903.58 3.9982 944.57 3.9982 908.58 3.9982 1008.5 3.9982 1059.5 3.9982 1079.5 3.9982 911.58 3.9982 1107.5 3.9982 992.54 3.9982 975.55 3.9982 1156.5 3.9982 1042.5 3.9982 1072.5 3.9982 916.58 3.9982 1022.5 3.9982 999.54 3.9982 966.56 3.9982 936.57 3.9982 934.57 3.9982 969.55 3.9982 1136.5 3.9982 997.54 3.9982 991.54 3.9982 1002.5 3.9982 1047.5 3.9982 1059.5 3.9982 972.55 3.9982 918.58 3.9982 959.56 3.9982 1083.5 3.9982 934.57 3.9982 900.59 3.9982 970.55 3.9982 952.56 3.9982 1063.5 3.9982 870.6 3.9982 958.56 3.9982 1029.5 3.9982 943.57 3.9982 872.6 3.9982 972.55 3.9982 1009.5 3.9982 875.6 3.9982 1127.5 3.9982 987.55 3.9982 1156.5 3.9982 971.55 3.9982 1155.5 3.9982 930.57 3.9982 1051.5 3.9982 1044.5 3.9982 867.6 3.9982 898.59 3.9982 926.57 3.9982 965.56 3.9982 1027.5 3.9982 993.54 3.9982 927.57 3.9982 973.55 3.9982 934.57 3.9982 951.56 3.9982 1007.5 3.9982 1124.5 3.9982 936.57 3.9982 1050.5 3.9982 1075.5 3.9982 1028.5 3.9982 872.6 3.9982 960.56 3.9982 1014.5 3.9982 1017.5 3.9982 860.6 3.9982 1039.5 3.9982 1059.5 3.9982 921.58 3.9982 936.57 3.9982 1024.5 3.9982 970.55 3.9982 1047.5 3.9982 917.58 3.9982 948.56 3.9982 978.55 3.9982 993.54 3.9982 1121.5 3.9982 944.57 3.9982 1005.5 3.9982 1037.5 3.9982 1261.4 3.9982 1062.5 3.9982 925.57 3.9982 976.55 3.9982 892.59 3.9982 972.55 3.9982 1135.5 3.9982 1044.5 3.9982 959.56 3.9982 990.54 3.9982 993.54 3.9982 1130.5 3.9982 919.58 3.9982 1025.5 3.9982 1001.5 3.9982 974.55 3.9982 1061.5 3.9982 1166.5 3.9982 1017.5 3.9982 1063.5 3.9982 1188.5 3.9982 964.56 3.9982 1047.5 3.9982 1210.4 3.9982 1087.5 3.9982 1151.5 3.9982 1096.5 3.9982 957.56 3.9982 1073.5 3.9982 925.57 3.9982 1051.5 3.9982 930.57 3.9982 1005.5 3.9982 977.55 3.9982 963.56 3.9982 1005.5 3.9982 954.56 3.9982 1025.5 3.9982 1039.5 3.9982 985.55 3.9982 923.58 3.9982 1087.5 3.9982 958.56 3.9982 1066.5 3.9982 1110.5 3.9982 934.57 3.9982 946.56 3.9982 - │ │ │ │ │ <---- 23 --------- 901 --------- 2150 -------- 3016 -------- 4093 -------- 5038 -------- 5962 -------- 6778 -------- 8056 -------- 9277 -------- 10530 -------- 11769 -------- 13020 -------- 14001 -------- 14982 -------- 16046 -------- 17072 -------- 18149 -------- 18935 -------- 19920 -------- 20876 -------- 21953 -------- 22859 -------- 23908 -------- 24923 -------- 25938 -------- 26865 -------- 27943 -------- 28938 -------- 29813 -------- 30844 -------- 31647 -------- 32585 -------- 33704 -------- 34617 -------- 35448 -------- 36338 ------- 37071 -------- 38029 -------- 39162 -------- 40163 -------- 41103 -------- 42008 -------- 42828 -------- 43789 -------- 44720 -------- 45920 -------- 47197 -------- 48149 -------- 49054 -------- 49906 -------- 51054 -------- 51940 -------- 53144 -------- 54301 -------- 55267 -------- 56318 -------- 57393 -------- 58223 -------- 59046 -------- 59995 -------- 61150 -------- 62024 -------- 62915 -------- 63943 -------- 65015 -------- 65840 -------- 66748 -------- 67584 -------- 68611 -------- 69729 -------- 70883 -------- 71725 -------- 72926 -------- 73924 -------- 74891 -------- 76176 -------- 77264 -------- 78405 -------- 79257 -------- 80310 -------- 81321 -------- 82270 -------- 83162 -------- 84049 -------- 85004 -------- 86255 -------- 87262 -------- 88259 -------- 89276 -------- 90374 -------- 91493 -------- 92454 -------- 93310 -------- 94246 -------- 95407 -------- 96295 -------- 97113 -------- 98069 -------- 98991 -------- 100116 ------- 100871 -------- 101805 -------- 102871 -------- 103776 ------- 104536 -------- 105497 -------- 106526 ------- 107293 -------- 108529 -------- 109518 -------- 110802 -------- 111761 -------- 113044 -------- 113923 -------- 115027 -------- 116119 ------- 116867 -------- 117681 -------- 118553 -------- 119501 -------- 120563 -------- 121563 -------- 122437 -------- 123400 -------- 124288 -------- 125209 -------- 126234 -------- 127465 -------- 128356 -------- 129458 -------- 130604 -------- 131668 ------- 132428 -------- 133365 -------- 134403 -------- 135446 ------- 136179 -------- 137262 -------- 138380 -------- 139242 -------- 140134 -------- 141190 -------- 142146 -------- 143244 -------- 144097 -------- 145011 -------- 145982 -------- 146981 -------- 148207 -------- 149115 -------- 150119 -------- 151183 -------- 152627 -------- 153735 -------- 154585 -------- 155535 -------- 156315 -------- 157258 -------- 158494 -------- 159570 -------- 160487 -------- 161464 -------- 162446 -------- 163673 -------- 164509 -------- 165550 -------- 166548 -------- 167495 -------- 168601 -------- 169889 -------- 170916 -------- 172026 -------- 173351 -------- 174278 -------- 175359 -------- 176720 -------- 177872 -------- 179135 -------- 180304 -------- 181217 -------- 182345 -------- 183194 -------- 184282 -------- 185142 -------- 186147 -------- 187099 -------- 188024 -------- 189029 -------- 189936 -------- 190977 -------- 192044 -------- 193012 -------- 193858 -------- 195011 -------- 195927 -------- 197043 -------- 198236 -------- 199104 -------- 199995 - │ │ │ │ │ histogram(22)= 0 7640 1.843e+05 8060 - │ │ │ │ │ <--- 'Brand#11' ----------- 'Brand#55' - │ │ │ │ │ histogram(24)= 0 4240 1.9186e+05 3900 - │ │ │ │ │ <--- 1 ------------- 50 - │ │ │ │ │ histogram(25)= 0 5460 1.8978e+05 4760 - │ │ │ │ │ <--- 'JUMBO BAG' ------------ 'WRAP PKG' - │ │ │ │ ├── key: (19) - │ │ │ │ └── fd: (19)-->(22,24,25) - │ │ │ └── filters - │ │ │ └── p_size:24 >= 1 [type=bool, outer=(24), constraints=(/24: [/1 - ]; tight)] - │ │ └── filters - │ │ ├── p_partkey:19 = l_partkey:2 [type=bool, outer=(2,19), constraints=(/2: (/NULL - ]; /19: (/NULL - ]), fd=(2)==(19), (19)==(2)] - │ │ └── ((((((p_brand:22 = 'Brand#12') AND (p_container:25 IN ('SM BOX', 'SM CASE', 'SM PACK', 'SM PKG'))) AND (l_quantity:5 >= 1.0)) AND (l_quantity:5 <= 11.0)) AND (p_size:24 <= 5)) OR (((((p_brand:22 = 'Brand#23') AND (p_container:25 IN ('MED BAG', 'MED BOX', 'MED PACK', 'MED PKG'))) AND (l_quantity:5 >= 10.0)) AND (l_quantity:5 <= 20.0)) AND (p_size:24 <= 10))) OR (((((p_brand:22 = 'Brand#34') AND (p_container:25 IN ('LG BOX', 'LG CASE', 'LG PACK', 'LG PKG'))) AND (l_quantity:5 >= 20.0)) AND (l_quantity:5 <= 30.0)) AND (p_size:24 <= 15)) [type=bool, outer=(5,22,24,25), constraints=(/5: [/1.0 - /30.0]; /22: [/'Brand#12' - /'Brand#12'] [/'Brand#23' - /'Brand#23'] [/'Brand#34' - /'Brand#34']; /24: (/NULL - /15]; /25: [/'LG BOX' - /'LG BOX'] [/'LG CASE' - /'LG CASE'] [/'LG PACK' - /'LG PACK'] [/'LG PKG' - /'LG PKG'] [/'MED BAG' - /'MED BAG'] [/'MED BOX' - /'MED BOX'] [/'MED PACK' - /'MED PACK'] [/'MED PKG' - /'MED PKG'] [/'SM BOX' - /'SM BOX'] [/'SM CASE' - /'SM CASE'] [/'SM PACK' - /'SM PACK'] [/'SM PKG' - /'SM PKG'])] + │ │ └── distinct-on + │ │ ├── save-table-name: q19_distinct_on_4 + │ │ ├── columns: l_orderkey:1(int!null) l_partkey:2(int!null) l_linenumber:4(int!null) l_quantity:5(float!null) l_extendedprice:6(float!null) l_discount:7(float!null) l_shipinstruct:14(char!null) l_shipmode:15(char!null) p_partkey:19(int!null) p_brand:22(char!null) p_size:24(int!null) p_container:25(char!null) + │ │ ├── grouping columns: l_orderkey:1(int!null) l_linenumber:4(int!null) p_partkey:19(int!null) + │ │ ├── stats: [rows=182.3692, distinct(1)=182.304, null(1)=0, distinct(2)=182.369, null(2)=0, distinct(4)=13.9999, null(4)=0, distinct(5)=182.369, null(5)=0, distinct(6)=182.369, null(6)=0, distinct(7)=182.369, null(7)=0, distinct(14)=182.369, null(14)=0, distinct(15)=182.369, null(15)=0, distinct(19)=163.44, null(19)=0, distinct(22)=182.369, null(22)=0, distinct(24)=182.369, null(24)=0, distinct(25)=182.369, null(25)=0, distinct(1,4,19)=182.369, null(1,4,19)=0] + │ │ ├── key: (1,4,19) + │ │ ├── fd: (2)==(19), (19)==(2), (1,4,19)-->(2,5-7,14,15,22,24,25) + │ │ ├── union-all + │ │ │ ├── save-table-name: q19_union_all_5 + │ │ │ ├── columns: l_orderkey:1(int!null) l_partkey:2(int!null) l_linenumber:4(int!null) l_quantity:5(float!null) l_extendedprice:6(float!null) l_discount:7(float!null) l_shipinstruct:14(char!null) l_shipmode:15(char!null) p_partkey:19(int!null) p_brand:22(char!null) p_size:24(int!null) p_container:25(char!null) + │ │ │ ├── left columns: l_orderkey:32(int) l_partkey:33(int) l_linenumber:35(int) l_quantity:36(float) l_extendedprice:37(float) l_discount:38(float) l_shipinstruct:45(char) l_shipmode:46(char) p_partkey:50(int) p_brand:53(char) p_size:55(int) p_container:56(char) + │ │ │ ├── right columns: l_orderkey:61(int) l_partkey:62(int) l_linenumber:64(int) l_quantity:65(float) l_extendedprice:66(float) l_discount:67(float) l_shipinstruct:74(char) l_shipmode:75(char) p_partkey:79(int) p_brand:82(char) p_size:84(int) p_container:85(char) + │ │ │ ├── stats: [rows=182.3692, distinct(1)=182.304, null(1)=0, distinct(2)=163.44, null(2)=0, distinct(4)=13.9999, null(4)=0, distinct(5)=16.3504, null(5)=0, distinct(6)=182.302, null(6)=0, distinct(7)=21.9927, null(7)=0, distinct(14)=2, null(14)=0, distinct(15)=4, null(15)=0, distinct(19)=163.44, null(19)=0, distinct(22)=3, null(22)=0, distinct(24)=21.6667, null(24)=0, distinct(25)=12, null(25)=0, distinct(1,4,19)=182.369, null(1,4,19)=0] + │ │ │ ├── fd: (2)==(19), (19)==(2) + │ │ │ ├── inner-join (lookup lineitem) + │ │ │ │ ├── save-table-name: q19_lookup_join_6 + │ │ │ │ ├── columns: l_orderkey:32(int!null) l_partkey:33(int!null) l_linenumber:35(int!null) l_quantity:36(float!null) l_extendedprice:37(float!null) l_discount:38(float!null) l_shipinstruct:45(char!null) l_shipmode:46(char!null) p_partkey:50(int!null) p_brand:53(char!null) p_size:55(int!null) p_container:56(char!null) + │ │ │ │ ├── key columns: [32 35] = [32 35] + │ │ │ │ ├── lookup columns are key + │ │ │ │ ├── stats: [rows=99.88038, distinct(32)=99.8241, null(32)=0, distinct(33)=80.9514, null(33)=0, distinct(35)=7, null(35)=0, distinct(36)=10.7949, null(36)=0, distinct(37)=99.823, null(37)=0, distinct(38)=10.9987, null(38)=0, distinct(45)=1, null(45)=0, distinct(46)=2, null(46)=0, distinct(50)=80.9514, null(50)=0, distinct(53)=1, null(53)=0, distinct(55)=5, null(55)=0, distinct(56)=4, null(56)=0, distinct(32,35,50)=99.8804, null(32,35,50)=0] + │ │ │ │ ├── key: (32,35) + │ │ │ │ ├── fd: ()-->(45,53), (32,35)-->(33,36-38,46), (50)-->(55,56), (33)==(50), (50)==(33) + │ │ │ │ ├── inner-join (lookup lineitem@l_pk) + │ │ │ │ │ ├── save-table-name: q19_lookup_join_7 + │ │ │ │ │ ├── columns: l_orderkey:32(int!null) l_partkey:33(int!null) l_linenumber:35(int!null) p_partkey:50(int!null) p_brand:53(char!null) p_size:55(int!null) p_container:56(char!null) + │ │ │ │ │ ├── key columns: [50] = [33] + │ │ │ │ │ ├── stats: [rows=2438.288, distinct(32)=2436.35, null(32)=0, distinct(33)=80.9514, null(33)=0, distinct(35)=7, null(35)=0, distinct(50)=80.9514, null(50)=0, distinct(53)=1, null(53)=0, distinct(55)=5, null(55)=0, distinct(56)=4, null(56)=0] + │ │ │ │ │ ├── key: (32,35) + │ │ │ │ │ ├── fd: ()-->(53), (50)-->(55,56), (32,35)-->(33), (33)==(50), (50)==(33) + │ │ │ │ │ ├── select + │ │ │ │ │ │ ├── save-table-name: q19_select_8 + │ │ │ │ │ │ ├── columns: p_partkey:50(int!null) p_brand:53(char!null) p_size:55(int!null) p_container:56(char!null) + │ │ │ │ │ │ ├── stats: [rows=80.95144, distinct(50)=80.9514, null(50)=0, distinct(53)=1, null(53)=0, distinct(55)=5, null(55)=0, distinct(56)=4, null(56)=0, distinct(53,55,56)=20, null(53,55,56)=0] + │ │ │ │ │ │ │ histogram(53)= 0 80.951 + │ │ │ │ │ │ │ <--- 'Brand#12' + │ │ │ │ │ │ │ histogram(55)= 0 16.968 47.988 15.996 + │ │ │ │ │ │ │ <---- 1 ----------- 5 -- + │ │ │ │ │ │ │ histogram(56)= 0 20.238 0 20.238 0 20.238 0 20.238 + │ │ │ │ │ │ │ <--- 'SM BOX' --- 'SM CASE' --- 'SM PACK' --- 'SM PKG' + │ │ │ │ │ │ ├── key: (50) + │ │ │ │ │ │ ├── fd: ()-->(53), (50)-->(55,56) + │ │ │ │ │ │ ├── scan part + │ │ │ │ │ │ │ ├── save-table-name: q19_scan_9 + │ │ │ │ │ │ │ ├── columns: p_partkey:50(int!null) p_brand:53(char!null) p_size:55(int!null) p_container:56(char!null) + │ │ │ │ │ │ │ ├── stats: [rows=200000, distinct(50)=199241, null(50)=0, distinct(53)=25, null(53)=0, distinct(55)=50, null(55)=0, distinct(56)=40, null(56)=0, distinct(53,55,56)=50000, null(53,55,56)=0] + │ │ │ │ │ │ │ │ histogram(50)= 0 3.9982 929.57 3.9982 1135.5 3.9982 923.58 3.9982 1036.5 3.9982 964.56 3.9982 953.56 3.9982 899.59 3.9982 1152.5 3.9982 1118.5 3.9982 1137.5 3.9982 1129.5 3.9982 1136.5 3.9982 983.55 3.9982 983.55 3.9982 1028.5 3.9982 1007.5 3.9982 1036.5 3.9982 884.59 3.9982 985.55 3.9982 970.55 3.9982 1036.5 3.9982 943.57 3.9982 1020.5 3.9982 1001.5 3.9982 1001.5 3.9982 954.56 3.9982 1036.5 3.9982 990.54 3.9982 928.57 3.9982 1010.5 3.9982 892.59 3.9982 960.56 3.9982 1059.5 3.9982 947.56 3.9982 906.58 3.9982 935.57 3.9982 860.6 3.9982 971.55 3.9982 1067.5 3.9982 994.54 3.9982 961.56 3.9982 943.57 3.9982 901.59 3.9982 972.55 3.9982 956.56 3.9982 1106.5 3.9982 1152.5 3.9982 967.55 3.9982 943.57 3.9982 916.58 3.9982 1076.5 3.9982 933.57 3.9982 1108.5 3.9982 1081.5 3.9982 975.55 3.9982 1021.5 3.9982 1034.5 3.9982 905.58 3.9982 902.58 3.9982 966.56 3.9982 1080.5 3.9982 927.57 3.9982 936.57 3.9982 1008.5 3.9982 1033.5 3.9982 903.58 3.9982 944.57 3.9982 908.58 3.9982 1008.5 3.9982 1059.5 3.9982 1079.5 3.9982 911.58 3.9982 1107.5 3.9982 992.54 3.9982 975.55 3.9982 1156.5 3.9982 1042.5 3.9982 1072.5 3.9982 916.58 3.9982 1022.5 3.9982 999.54 3.9982 966.56 3.9982 936.57 3.9982 934.57 3.9982 969.55 3.9982 1136.5 3.9982 997.54 3.9982 991.54 3.9982 1002.5 3.9982 1047.5 3.9982 1059.5 3.9982 972.55 3.9982 918.58 3.9982 959.56 3.9982 1083.5 3.9982 934.57 3.9982 900.59 3.9982 970.55 3.9982 952.56 3.9982 1063.5 3.9982 870.6 3.9982 958.56 3.9982 1029.5 3.9982 943.57 3.9982 872.6 3.9982 972.55 3.9982 1009.5 3.9982 875.6 3.9982 1127.5 3.9982 987.55 3.9982 1156.5 3.9982 971.55 3.9982 1155.5 3.9982 930.57 3.9982 1051.5 3.9982 1044.5 3.9982 867.6 3.9982 898.59 3.9982 926.57 3.9982 965.56 3.9982 1027.5 3.9982 993.54 3.9982 927.57 3.9982 973.55 3.9982 934.57 3.9982 951.56 3.9982 1007.5 3.9982 1124.5 3.9982 936.57 3.9982 1050.5 3.9982 1075.5 3.9982 1028.5 3.9982 872.6 3.9982 960.56 3.9982 1014.5 3.9982 1017.5 3.9982 860.6 3.9982 1039.5 3.9982 1059.5 3.9982 921.58 3.9982 936.57 3.9982 1024.5 3.9982 970.55 3.9982 1047.5 3.9982 917.58 3.9982 948.56 3.9982 978.55 3.9982 993.54 3.9982 1121.5 3.9982 944.57 3.9982 1005.5 3.9982 1037.5 3.9982 1261.4 3.9982 1062.5 3.9982 925.57 3.9982 976.55 3.9982 892.59 3.9982 972.55 3.9982 1135.5 3.9982 1044.5 3.9982 959.56 3.9982 990.54 3.9982 993.54 3.9982 1130.5 3.9982 919.58 3.9982 1025.5 3.9982 1001.5 3.9982 974.55 3.9982 1061.5 3.9982 1166.5 3.9982 1017.5 3.9982 1063.5 3.9982 1188.5 3.9982 964.56 3.9982 1047.5 3.9982 1210.4 3.9982 1087.5 3.9982 1151.5 3.9982 1096.5 3.9982 957.56 3.9982 1073.5 3.9982 925.57 3.9982 1051.5 3.9982 930.57 3.9982 1005.5 3.9982 977.55 3.9982 963.56 3.9982 1005.5 3.9982 954.56 3.9982 1025.5 3.9982 1039.5 3.9982 985.55 3.9982 923.58 3.9982 1087.5 3.9982 958.56 3.9982 1066.5 3.9982 1110.5 3.9982 934.57 3.9982 946.56 3.9982 + │ │ │ │ │ │ │ │ <---- 23 --------- 901 --------- 2150 -------- 3016 -------- 4093 -------- 5038 -------- 5962 -------- 6778 -------- 8056 -------- 9277 -------- 10530 -------- 11769 -------- 13020 -------- 14001 -------- 14982 -------- 16046 -------- 17072 -------- 18149 -------- 18935 -------- 19920 -------- 20876 -------- 21953 -------- 22859 -------- 23908 -------- 24923 -------- 25938 -------- 26865 -------- 27943 -------- 28938 -------- 29813 -------- 30844 -------- 31647 -------- 32585 -------- 33704 -------- 34617 -------- 35448 -------- 36338 ------- 37071 -------- 38029 -------- 39162 -------- 40163 -------- 41103 -------- 42008 -------- 42828 -------- 43789 -------- 44720 -------- 45920 -------- 47197 -------- 48149 -------- 49054 -------- 49906 -------- 51054 -------- 51940 -------- 53144 -------- 54301 -------- 55267 -------- 56318 -------- 57393 -------- 58223 -------- 59046 -------- 59995 -------- 61150 -------- 62024 -------- 62915 -------- 63943 -------- 65015 -------- 65840 -------- 66748 -------- 67584 -------- 68611 -------- 69729 -------- 70883 -------- 71725 -------- 72926 -------- 73924 -------- 74891 -------- 76176 -------- 77264 -------- 78405 -------- 79257 -------- 80310 -------- 81321 -------- 82270 -------- 83162 -------- 84049 -------- 85004 -------- 86255 -------- 87262 -------- 88259 -------- 89276 -------- 90374 -------- 91493 -------- 92454 -------- 93310 -------- 94246 -------- 95407 -------- 96295 -------- 97113 -------- 98069 -------- 98991 -------- 100116 ------- 100871 -------- 101805 -------- 102871 -------- 103776 ------- 104536 -------- 105497 -------- 106526 ------- 107293 -------- 108529 -------- 109518 -------- 110802 -------- 111761 -------- 113044 -------- 113923 -------- 115027 -------- 116119 ------- 116867 -------- 117681 -------- 118553 -------- 119501 -------- 120563 -------- 121563 -------- 122437 -------- 123400 -------- 124288 -------- 125209 -------- 126234 -------- 127465 -------- 128356 -------- 129458 -------- 130604 -------- 131668 ------- 132428 -------- 133365 -------- 134403 -------- 135446 ------- 136179 -------- 137262 -------- 138380 -------- 139242 -------- 140134 -------- 141190 -------- 142146 -------- 143244 -------- 144097 -------- 145011 -------- 145982 -------- 146981 -------- 148207 -------- 149115 -------- 150119 -------- 151183 -------- 152627 -------- 153735 -------- 154585 -------- 155535 -------- 156315 -------- 157258 -------- 158494 -------- 159570 -------- 160487 -------- 161464 -------- 162446 -------- 163673 -------- 164509 -------- 165550 -------- 166548 -------- 167495 -------- 168601 -------- 169889 -------- 170916 -------- 172026 -------- 173351 -------- 174278 -------- 175359 -------- 176720 -------- 177872 -------- 179135 -------- 180304 -------- 181217 -------- 182345 -------- 183194 -------- 184282 -------- 185142 -------- 186147 -------- 187099 -------- 188024 -------- 189029 -------- 189936 -------- 190977 -------- 192044 -------- 193012 -------- 193858 -------- 195011 -------- 195927 -------- 197043 -------- 198236 -------- 199104 -------- 199995 + │ │ │ │ │ │ │ │ histogram(53)= 0 7640 1.843e+05 8060 + │ │ │ │ │ │ │ │ <--- 'Brand#11' ----------- 'Brand#55' + │ │ │ │ │ │ │ │ histogram(55)= 0 4240 1.9186e+05 3900 + │ │ │ │ │ │ │ │ <--- 1 ------------- 50 + │ │ │ │ │ │ │ │ histogram(56)= 0 5460 1.8978e+05 4760 + │ │ │ │ │ │ │ │ <--- 'JUMBO BAG' ------------ 'WRAP PKG' + │ │ │ │ │ │ │ ├── key: (50) + │ │ │ │ │ │ │ └── fd: (50)-->(53,55,56) + │ │ │ │ │ │ └── filters + │ │ │ │ │ │ ├── (p_size:55 >= 1) AND (p_size:55 <= 5) [type=bool, outer=(55), constraints=(/55: [/1 - /5]; tight)] + │ │ │ │ │ │ ├── p_brand:53 = 'Brand#12' [type=bool, outer=(53), constraints=(/53: [/'Brand#12' - /'Brand#12']; tight), fd=()-->(53)] + │ │ │ │ │ │ └── p_container:56 IN ('SM BOX', 'SM CASE', 'SM PACK', 'SM PKG') [type=bool, outer=(56), constraints=(/56: [/'SM BOX' - /'SM BOX'] [/'SM CASE' - /'SM CASE'] [/'SM PACK' - /'SM PACK'] [/'SM PKG' - /'SM PKG']; tight)] + │ │ │ │ │ └── filters (true) + │ │ │ │ └── filters + │ │ │ │ ├── (l_quantity:36 >= 1.0) AND (l_quantity:36 <= 11.0) [type=bool, outer=(36), constraints=(/36: [/1.0 - /11.0]; tight)] + │ │ │ │ ├── l_shipmode:46 IN ('AIR', 'AIR REG') [type=bool, outer=(46), constraints=(/46: [/'AIR' - /'AIR'] [/'AIR REG' - /'AIR REG']; tight)] + │ │ │ │ └── l_shipinstruct:45 = 'DELIVER IN PERSON' [type=bool, outer=(45), constraints=(/45: [/'DELIVER IN PERSON' - /'DELIVER IN PERSON']; tight), fd=()-->(45)] + │ │ │ └── project + │ │ │ ├── save-table-name: q19_project_10 + │ │ │ ├── columns: l_orderkey:61(int!null) l_partkey:62(int!null) l_linenumber:64(int!null) l_quantity:65(float!null) l_extendedprice:66(float!null) l_discount:67(float!null) l_shipinstruct:74(char!null) l_shipmode:75(char!null) p_partkey:79(int!null) p_brand:82(char!null) p_size:84(int!null) p_container:85(char!null) + │ │ │ ├── stats: [rows=82.48887, distinct(61)=82.4798, null(61)=0, distinct(62)=82.4889, null(62)=0, distinct(64)=6.99995, null(64)=0, distinct(65)=5.55556, null(65)=0, distinct(66)=82.479, null(66)=0, distinct(67)=10.9939, null(67)=0, distinct(74)=1, null(74)=0, distinct(75)=2, null(75)=0, distinct(79)=82.4889, null(79)=0, distinct(82)=2, null(82)=0, distinct(84)=16.6667, null(84)=0, distinct(85)=8, null(85)=0, distinct(61,64,79)=82.4889, null(61,64,79)=0, distinct(82,84,85)=82.4889, null(82,84,85)=0] + │ │ │ ├── key: (61,64) + │ │ │ ├── fd: ()-->(74), (61,64)-->(62,65-67,75), (79)-->(82,84,85), (62)==(79), (79)==(62) + │ │ │ └── distinct-on + │ │ │ ├── save-table-name: q19_distinct_on_11 + │ │ │ ├── columns: l_orderkey:61(int!null) l_partkey:62(int!null) l_linenumber:64(int!null) l_quantity:65(float!null) l_extendedprice:66(float!null) l_discount:67(float!null) l_shipinstruct:74(char!null) l_shipmode:75(char!null) p_partkey:79(int!null) p_brand:82(char!null) p_size:84(int!null) p_container:85(char!null) + │ │ │ ├── grouping columns: l_orderkey:61(int!null) l_linenumber:64(int!null) p_partkey:79(int!null) + │ │ │ ├── stats: [rows=486.9996, distinct(61)=486.233, null(61)=0, distinct(62)=487, null(62)=0, distinct(64)=14, null(64)=0, distinct(65)=487, null(65)=0, distinct(66)=487, null(66)=0, distinct(67)=487, null(67)=0, distinct(74)=487, null(74)=0, distinct(75)=487, null(75)=0, distinct(79)=401.84, null(79)=0, distinct(82)=487, null(82)=0, distinct(84)=487, null(84)=0, distinct(85)=487, null(85)=0, distinct(61,64,79)=487, null(61,64,79)=0] + │ │ │ ├── key: (61,64,79) + │ │ │ ├── fd: (62)==(79), (79)==(62), (61,64,79)-->(62,65-67,74,75,82,84,85) + │ │ │ ├── union-all + │ │ │ │ ├── save-table-name: q19_union_all_12 + │ │ │ │ ├── columns: l_orderkey:61(int!null) l_partkey:62(int!null) l_linenumber:64(int!null) l_quantity:65(float!null) l_extendedprice:66(float!null) l_discount:67(float!null) l_shipinstruct:74(char!null) l_shipmode:75(char!null) p_partkey:79(int!null) p_brand:82(char!null) p_size:84(int!null) p_container:85(char!null) + │ │ │ │ ├── left columns: l_orderkey:90(int) l_partkey:91(int) l_linenumber:93(int) l_quantity:94(float) l_extendedprice:95(float) l_discount:96(float) l_shipinstruct:103(char) l_shipmode:104(char) p_partkey:108(int) p_brand:111(char) p_size:113(int) p_container:114(char) + │ │ │ │ ├── right columns: l_orderkey:119(int) l_partkey:120(int) l_linenumber:122(int) l_quantity:123(float) l_extendedprice:124(float) l_discount:125(float) l_shipinstruct:132(char) l_shipmode:133(char) p_partkey:137(int) p_brand:140(char) p_size:142(int) p_container:143(char) + │ │ │ │ ├── stats: [rows=486.9996, distinct(61)=486.233, null(61)=0, distinct(62)=401.84, null(62)=0, distinct(64)=14, null(64)=0, distinct(65)=19.5918, null(65)=0, distinct(66)=486.22, null(66)=0, distinct(67)=22, null(67)=0, distinct(74)=2, null(74)=0, distinct(75)=4, null(75)=0, distinct(79)=401.84, null(79)=0, distinct(82)=2, null(82)=0, distinct(84)=25, null(84)=0, distinct(85)=8, null(85)=0, distinct(61,64,79)=487, null(61,64,79)=0] + │ │ │ │ ├── fd: (62)==(79), (79)==(62) + │ │ │ │ ├── inner-join (lookup lineitem) + │ │ │ │ │ ├── save-table-name: q19_lookup_join_13 + │ │ │ │ │ ├── columns: l_orderkey:90(int!null) l_partkey:91(int!null) l_linenumber:93(int!null) l_quantity:94(float!null) l_extendedprice:95(float!null) l_discount:96(float!null) l_shipinstruct:103(char!null) l_shipmode:104(char!null) p_partkey:108(int!null) p_brand:111(char!null) p_size:113(int!null) p_container:114(char!null) + │ │ │ │ │ ├── key columns: [90 93] = [90 93] + │ │ │ │ │ ├── lookup columns are key + │ │ │ │ │ ├── stats: [rows=291.9642, distinct(90)=291.434, null(90)=0, distinct(91)=240.909, null(91)=0, distinct(93)=7, null(93)=0, distinct(94)=9.79592, null(94)=0, distinct(95)=291.425, null(95)=0, distinct(96)=11, null(96)=0, distinct(103)=1, null(103)=0, distinct(104)=2, null(104)=0, distinct(108)=240.909, null(108)=0, distinct(111)=1, null(111)=0, distinct(113)=15, null(113)=0, distinct(114)=4, null(114)=0, distinct(90,93,108)=291.964, null(90,93,108)=0] + │ │ │ │ │ ├── key: (90,93) + │ │ │ │ │ ├── fd: ()-->(103,111), (90,93)-->(91,94-96,104), (108)-->(113,114), (91)==(108), (108)==(91) + │ │ │ │ │ ├── inner-join (lookup lineitem@l_pk) + │ │ │ │ │ │ ├── save-table-name: q19_lookup_join_14 + │ │ │ │ │ │ ├── columns: l_orderkey:90(int!null) l_partkey:91(int!null) l_linenumber:93(int!null) p_partkey:108(int!null) p_brand:111(char!null) p_size:113(int!null) p_container:114(char!null) + │ │ │ │ │ │ ├── key columns: [108] = [91] + │ │ │ │ │ │ ├── stats: [rows=7256.302, distinct(90)=7239.11, null(90)=0, distinct(91)=240.909, null(91)=0, distinct(93)=7, null(93)=0, distinct(108)=240.909, null(108)=0, distinct(111)=1, null(111)=0, distinct(113)=15, null(113)=0, distinct(114)=4, null(114)=0] + │ │ │ │ │ │ ├── key: (90,93) + │ │ │ │ │ │ ├── fd: ()-->(111), (108)-->(113,114), (90,93)-->(91), (91)==(108), (108)==(91) + │ │ │ │ │ │ ├── select + │ │ │ │ │ │ │ ├── save-table-name: q19_select_15 + │ │ │ │ │ │ │ ├── columns: p_partkey:108(int!null) p_brand:111(char!null) p_size:113(int!null) p_container:114(char!null) + │ │ │ │ │ │ │ ├── stats: [rows=240.91, distinct(108)=240.909, null(108)=0, distinct(111)=1, null(111)=0, distinct(113)=15, null(113)=0, distinct(114)=4, null(114)=0, distinct(111,113,114)=60, null(111,113,114)=0] + │ │ │ │ │ │ │ │ histogram(111)= 0 240.91 + │ │ │ │ │ │ │ │ <--- 'Brand#34' + │ │ │ │ │ │ │ │ histogram(113)= 0 16.968 207.95 15.996 + │ │ │ │ │ │ │ │ <---- 1 ----------- 15 - + │ │ │ │ │ │ │ │ histogram(114)= 0 60.228 0 60.228 0 60.228 0 60.228 + │ │ │ │ │ │ │ │ <--- 'LG BOX' --- 'LG CASE' --- 'LG PACK' --- 'LG PKG' + │ │ │ │ │ │ │ ├── key: (108) + │ │ │ │ │ │ │ ├── fd: ()-->(111), (108)-->(113,114) + │ │ │ │ │ │ │ ├── scan part + │ │ │ │ │ │ │ │ ├── save-table-name: q19_scan_16 + │ │ │ │ │ │ │ │ ├── columns: p_partkey:108(int!null) p_brand:111(char!null) p_size:113(int!null) p_container:114(char!null) + │ │ │ │ │ │ │ │ ├── stats: [rows=200000, distinct(108)=199241, null(108)=0, distinct(111)=25, null(111)=0, distinct(113)=50, null(113)=0, distinct(114)=40, null(114)=0, distinct(111,113,114)=50000, null(111,113,114)=0] + │ │ │ │ │ │ │ │ │ histogram(108)= 0 3.9982 929.57 3.9982 1135.5 3.9982 923.58 3.9982 1036.5 3.9982 964.56 3.9982 953.56 3.9982 899.59 3.9982 1152.5 3.9982 1118.5 3.9982 1137.5 3.9982 1129.5 3.9982 1136.5 3.9982 983.55 3.9982 983.55 3.9982 1028.5 3.9982 1007.5 3.9982 1036.5 3.9982 884.59 3.9982 985.55 3.9982 970.55 3.9982 1036.5 3.9982 943.57 3.9982 1020.5 3.9982 1001.5 3.9982 1001.5 3.9982 954.56 3.9982 1036.5 3.9982 990.54 3.9982 928.57 3.9982 1010.5 3.9982 892.59 3.9982 960.56 3.9982 1059.5 3.9982 947.56 3.9982 906.58 3.9982 935.57 3.9982 860.6 3.9982 971.55 3.9982 1067.5 3.9982 994.54 3.9982 961.56 3.9982 943.57 3.9982 901.59 3.9982 972.55 3.9982 956.56 3.9982 1106.5 3.9982 1152.5 3.9982 967.55 3.9982 943.57 3.9982 916.58 3.9982 1076.5 3.9982 933.57 3.9982 1108.5 3.9982 1081.5 3.9982 975.55 3.9982 1021.5 3.9982 1034.5 3.9982 905.58 3.9982 902.58 3.9982 966.56 3.9982 1080.5 3.9982 927.57 3.9982 936.57 3.9982 1008.5 3.9982 1033.5 3.9982 903.58 3.9982 944.57 3.9982 908.58 3.9982 1008.5 3.9982 1059.5 3.9982 1079.5 3.9982 911.58 3.9982 1107.5 3.9982 992.54 3.9982 975.55 3.9982 1156.5 3.9982 1042.5 3.9982 1072.5 3.9982 916.58 3.9982 1022.5 3.9982 999.54 3.9982 966.56 3.9982 936.57 3.9982 934.57 3.9982 969.55 3.9982 1136.5 3.9982 997.54 3.9982 991.54 3.9982 1002.5 3.9982 1047.5 3.9982 1059.5 3.9982 972.55 3.9982 918.58 3.9982 959.56 3.9982 1083.5 3.9982 934.57 3.9982 900.59 3.9982 970.55 3.9982 952.56 3.9982 1063.5 3.9982 870.6 3.9982 958.56 3.9982 1029.5 3.9982 943.57 3.9982 872.6 3.9982 972.55 3.9982 1009.5 3.9982 875.6 3.9982 1127.5 3.9982 987.55 3.9982 1156.5 3.9982 971.55 3.9982 1155.5 3.9982 930.57 3.9982 1051.5 3.9982 1044.5 3.9982 867.6 3.9982 898.59 3.9982 926.57 3.9982 965.56 3.9982 1027.5 3.9982 993.54 3.9982 927.57 3.9982 973.55 3.9982 934.57 3.9982 951.56 3.9982 1007.5 3.9982 1124.5 3.9982 936.57 3.9982 1050.5 3.9982 1075.5 3.9982 1028.5 3.9982 872.6 3.9982 960.56 3.9982 1014.5 3.9982 1017.5 3.9982 860.6 3.9982 1039.5 3.9982 1059.5 3.9982 921.58 3.9982 936.57 3.9982 1024.5 3.9982 970.55 3.9982 1047.5 3.9982 917.58 3.9982 948.56 3.9982 978.55 3.9982 993.54 3.9982 1121.5 3.9982 944.57 3.9982 1005.5 3.9982 1037.5 3.9982 1261.4 3.9982 1062.5 3.9982 925.57 3.9982 976.55 3.9982 892.59 3.9982 972.55 3.9982 1135.5 3.9982 1044.5 3.9982 959.56 3.9982 990.54 3.9982 993.54 3.9982 1130.5 3.9982 919.58 3.9982 1025.5 3.9982 1001.5 3.9982 974.55 3.9982 1061.5 3.9982 1166.5 3.9982 1017.5 3.9982 1063.5 3.9982 1188.5 3.9982 964.56 3.9982 1047.5 3.9982 1210.4 3.9982 1087.5 3.9982 1151.5 3.9982 1096.5 3.9982 957.56 3.9982 1073.5 3.9982 925.57 3.9982 1051.5 3.9982 930.57 3.9982 1005.5 3.9982 977.55 3.9982 963.56 3.9982 1005.5 3.9982 954.56 3.9982 1025.5 3.9982 1039.5 3.9982 985.55 3.9982 923.58 3.9982 1087.5 3.9982 958.56 3.9982 1066.5 3.9982 1110.5 3.9982 934.57 3.9982 946.56 3.9982 + │ │ │ │ │ │ │ │ │ <---- 23 --------- 901 --------- 2150 -------- 3016 -------- 4093 -------- 5038 -------- 5962 -------- 6778 -------- 8056 -------- 9277 -------- 10530 -------- 11769 -------- 13020 -------- 14001 -------- 14982 -------- 16046 -------- 17072 -------- 18149 -------- 18935 -------- 19920 -------- 20876 -------- 21953 -------- 22859 -------- 23908 -------- 24923 -------- 25938 -------- 26865 -------- 27943 -------- 28938 -------- 29813 -------- 30844 -------- 31647 -------- 32585 -------- 33704 -------- 34617 -------- 35448 -------- 36338 ------- 37071 -------- 38029 -------- 39162 -------- 40163 -------- 41103 -------- 42008 -------- 42828 -------- 43789 -------- 44720 -------- 45920 -------- 47197 -------- 48149 -------- 49054 -------- 49906 -------- 51054 -------- 51940 -------- 53144 -------- 54301 -------- 55267 -------- 56318 -------- 57393 -------- 58223 -------- 59046 -------- 59995 -------- 61150 -------- 62024 -------- 62915 -------- 63943 -------- 65015 -------- 65840 -------- 66748 -------- 67584 -------- 68611 -------- 69729 -------- 70883 -------- 71725 -------- 72926 -------- 73924 -------- 74891 -------- 76176 -------- 77264 -------- 78405 -------- 79257 -------- 80310 -------- 81321 -------- 82270 -------- 83162 -------- 84049 -------- 85004 -------- 86255 -------- 87262 -------- 88259 -------- 89276 -------- 90374 -------- 91493 -------- 92454 -------- 93310 -------- 94246 -------- 95407 -------- 96295 -------- 97113 -------- 98069 -------- 98991 -------- 100116 ------- 100871 -------- 101805 -------- 102871 -------- 103776 ------- 104536 -------- 105497 -------- 106526 ------- 107293 -------- 108529 -------- 109518 -------- 110802 -------- 111761 -------- 113044 -------- 113923 -------- 115027 -------- 116119 ------- 116867 -------- 117681 -------- 118553 -------- 119501 -------- 120563 -------- 121563 -------- 122437 -------- 123400 -------- 124288 -------- 125209 -------- 126234 -------- 127465 -------- 128356 -------- 129458 -------- 130604 -------- 131668 ------- 132428 -------- 133365 -------- 134403 -------- 135446 ------- 136179 -------- 137262 -------- 138380 -------- 139242 -------- 140134 -------- 141190 -------- 142146 -------- 143244 -------- 144097 -------- 145011 -------- 145982 -------- 146981 -------- 148207 -------- 149115 -------- 150119 -------- 151183 -------- 152627 -------- 153735 -------- 154585 -------- 155535 -------- 156315 -------- 157258 -------- 158494 -------- 159570 -------- 160487 -------- 161464 -------- 162446 -------- 163673 -------- 164509 -------- 165550 -------- 166548 -------- 167495 -------- 168601 -------- 169889 -------- 170916 -------- 172026 -------- 173351 -------- 174278 -------- 175359 -------- 176720 -------- 177872 -------- 179135 -------- 180304 -------- 181217 -------- 182345 -------- 183194 -------- 184282 -------- 185142 -------- 186147 -------- 187099 -------- 188024 -------- 189029 -------- 189936 -------- 190977 -------- 192044 -------- 193012 -------- 193858 -------- 195011 -------- 195927 -------- 197043 -------- 198236 -------- 199104 -------- 199995 + │ │ │ │ │ │ │ │ │ histogram(111)= 0 7640 1.843e+05 8060 + │ │ │ │ │ │ │ │ │ <--- 'Brand#11' ----------- 'Brand#55' + │ │ │ │ │ │ │ │ │ histogram(113)= 0 4240 1.9186e+05 3900 + │ │ │ │ │ │ │ │ │ <--- 1 ------------- 50 + │ │ │ │ │ │ │ │ │ histogram(114)= 0 5460 1.8978e+05 4760 + │ │ │ │ │ │ │ │ │ <--- 'JUMBO BAG' ------------ 'WRAP PKG' + │ │ │ │ │ │ │ │ ├── key: (108) + │ │ │ │ │ │ │ │ └── fd: (108)-->(111,113,114) + │ │ │ │ │ │ │ └── filters + │ │ │ │ │ │ │ ├── (p_size:113 >= 1) AND (p_size:113 <= 15) [type=bool, outer=(113), constraints=(/113: [/1 - /15]; tight)] + │ │ │ │ │ │ │ ├── p_brand:111 = 'Brand#34' [type=bool, outer=(111), constraints=(/111: [/'Brand#34' - /'Brand#34']; tight), fd=()-->(111)] + │ │ │ │ │ │ │ └── p_container:114 IN ('LG BOX', 'LG CASE', 'LG PACK', 'LG PKG') [type=bool, outer=(114), constraints=(/114: [/'LG BOX' - /'LG BOX'] [/'LG CASE' - /'LG CASE'] [/'LG PACK' - /'LG PACK'] [/'LG PKG' - /'LG PKG']; tight)] + │ │ │ │ │ │ └── filters (true) + │ │ │ │ │ └── filters + │ │ │ │ │ ├── (l_quantity:94 >= 20.0) AND (l_quantity:94 <= 30.0) [type=bool, outer=(94), constraints=(/94: [/20.0 - /30.0]; tight)] + │ │ │ │ │ ├── l_shipmode:104 IN ('AIR', 'AIR REG') [type=bool, outer=(104), constraints=(/104: [/'AIR' - /'AIR'] [/'AIR REG' - /'AIR REG']; tight)] + │ │ │ │ │ └── l_shipinstruct:103 = 'DELIVER IN PERSON' [type=bool, outer=(103), constraints=(/103: [/'DELIVER IN PERSON' - /'DELIVER IN PERSON']; tight), fd=()-->(103)] + │ │ │ │ └── inner-join (lookup lineitem) + │ │ │ │ ├── save-table-name: q19_lookup_join_17 + │ │ │ │ ├── columns: l_orderkey:119(int!null) l_partkey:120(int!null) l_linenumber:122(int!null) l_quantity:123(float!null) l_extendedprice:124(float!null) l_discount:125(float!null) l_shipinstruct:132(char!null) l_shipmode:133(char!null) p_partkey:137(int!null) p_brand:140(char!null) p_size:142(int!null) p_container:143(char!null) + │ │ │ │ ├── key columns: [119 122] = [119 122] + │ │ │ │ ├── lookup columns are key + │ │ │ │ ├── stats: [rows=195.0355, distinct(119)=194.799, null(119)=0, distinct(120)=160.93, null(120)=0, distinct(122)=7, null(122)=0, distinct(123)=9.79592, null(123)=0, distinct(124)=194.795, null(124)=0, distinct(125)=11, null(125)=0, distinct(132)=1, null(132)=0, distinct(133)=2, null(133)=0, distinct(137)=160.93, null(137)=0, distinct(140)=1, null(140)=0, distinct(142)=10, null(142)=0, distinct(143)=4, null(143)=0, distinct(119,122,137)=195.035, null(119,122,137)=0] + │ │ │ │ ├── key: (119,122) + │ │ │ │ ├── fd: ()-->(132,140), (119,122)-->(120,123-125,133), (137)-->(142,143), (120)==(137), (137)==(120) + │ │ │ │ ├── inner-join (lookup lineitem@l_pk) + │ │ │ │ │ ├── save-table-name: q19_lookup_join_18 + │ │ │ │ │ ├── columns: l_orderkey:119(int!null) l_partkey:120(int!null) l_linenumber:122(int!null) p_partkey:137(int!null) p_brand:140(char!null) p_size:142(int!null) p_container:143(char!null) + │ │ │ │ │ ├── key columns: [137] = [120] + │ │ │ │ │ ├── stats: [rows=4847.295, distinct(119)=4839.62, null(119)=0, distinct(120)=160.93, null(120)=0, distinct(122)=7, null(122)=0, distinct(137)=160.93, null(137)=0, distinct(140)=1, null(140)=0, distinct(142)=10, null(142)=0, distinct(143)=4, null(143)=0] + │ │ │ │ │ ├── key: (119,122) + │ │ │ │ │ ├── fd: ()-->(140), (137)-->(142,143), (119,122)-->(120), (120)==(137), (137)==(120) + │ │ │ │ │ ├── select + │ │ │ │ │ │ ├── save-table-name: q19_select_19 + │ │ │ │ │ │ ├── columns: p_partkey:137(int!null) p_brand:140(char!null) p_size:142(int!null) p_container:143(char!null) + │ │ │ │ │ │ ├── stats: [rows=160.9307, distinct(137)=160.93, null(137)=0, distinct(140)=1, null(140)=0, distinct(142)=10, null(142)=0, distinct(143)=4, null(143)=0, distinct(140,142,143)=40, null(140,142,143)=0] + │ │ │ │ │ │ │ histogram(140)= 0 160.93 + │ │ │ │ │ │ │ <--- 'Brand#23' + │ │ │ │ │ │ │ histogram(142)= 0 16.968 127.97 15.996 + │ │ │ │ │ │ │ <---- 1 ----------- 10 - + │ │ │ │ │ │ │ histogram(143)= 0 40.233 0 40.233 0 40.233 0 40.233 + │ │ │ │ │ │ │ <--- 'MED BAG' --- 'MED BOX' --- 'MED PACK' --- 'MED PKG' + │ │ │ │ │ │ ├── key: (137) + │ │ │ │ │ │ ├── fd: ()-->(140), (137)-->(142,143) + │ │ │ │ │ │ ├── scan part + │ │ │ │ │ │ │ ├── save-table-name: q19_scan_20 + │ │ │ │ │ │ │ ├── columns: p_partkey:137(int!null) p_brand:140(char!null) p_size:142(int!null) p_container:143(char!null) + │ │ │ │ │ │ │ ├── stats: [rows=200000, distinct(137)=199241, null(137)=0, distinct(140)=25, null(140)=0, distinct(142)=50, null(142)=0, distinct(143)=40, null(143)=0, distinct(140,142,143)=50000, null(140,142,143)=0] + │ │ │ │ │ │ │ │ histogram(137)= 0 3.9982 929.57 3.9982 1135.5 3.9982 923.58 3.9982 1036.5 3.9982 964.56 3.9982 953.56 3.9982 899.59 3.9982 1152.5 3.9982 1118.5 3.9982 1137.5 3.9982 1129.5 3.9982 1136.5 3.9982 983.55 3.9982 983.55 3.9982 1028.5 3.9982 1007.5 3.9982 1036.5 3.9982 884.59 3.9982 985.55 3.9982 970.55 3.9982 1036.5 3.9982 943.57 3.9982 1020.5 3.9982 1001.5 3.9982 1001.5 3.9982 954.56 3.9982 1036.5 3.9982 990.54 3.9982 928.57 3.9982 1010.5 3.9982 892.59 3.9982 960.56 3.9982 1059.5 3.9982 947.56 3.9982 906.58 3.9982 935.57 3.9982 860.6 3.9982 971.55 3.9982 1067.5 3.9982 994.54 3.9982 961.56 3.9982 943.57 3.9982 901.59 3.9982 972.55 3.9982 956.56 3.9982 1106.5 3.9982 1152.5 3.9982 967.55 3.9982 943.57 3.9982 916.58 3.9982 1076.5 3.9982 933.57 3.9982 1108.5 3.9982 1081.5 3.9982 975.55 3.9982 1021.5 3.9982 1034.5 3.9982 905.58 3.9982 902.58 3.9982 966.56 3.9982 1080.5 3.9982 927.57 3.9982 936.57 3.9982 1008.5 3.9982 1033.5 3.9982 903.58 3.9982 944.57 3.9982 908.58 3.9982 1008.5 3.9982 1059.5 3.9982 1079.5 3.9982 911.58 3.9982 1107.5 3.9982 992.54 3.9982 975.55 3.9982 1156.5 3.9982 1042.5 3.9982 1072.5 3.9982 916.58 3.9982 1022.5 3.9982 999.54 3.9982 966.56 3.9982 936.57 3.9982 934.57 3.9982 969.55 3.9982 1136.5 3.9982 997.54 3.9982 991.54 3.9982 1002.5 3.9982 1047.5 3.9982 1059.5 3.9982 972.55 3.9982 918.58 3.9982 959.56 3.9982 1083.5 3.9982 934.57 3.9982 900.59 3.9982 970.55 3.9982 952.56 3.9982 1063.5 3.9982 870.6 3.9982 958.56 3.9982 1029.5 3.9982 943.57 3.9982 872.6 3.9982 972.55 3.9982 1009.5 3.9982 875.6 3.9982 1127.5 3.9982 987.55 3.9982 1156.5 3.9982 971.55 3.9982 1155.5 3.9982 930.57 3.9982 1051.5 3.9982 1044.5 3.9982 867.6 3.9982 898.59 3.9982 926.57 3.9982 965.56 3.9982 1027.5 3.9982 993.54 3.9982 927.57 3.9982 973.55 3.9982 934.57 3.9982 951.56 3.9982 1007.5 3.9982 1124.5 3.9982 936.57 3.9982 1050.5 3.9982 1075.5 3.9982 1028.5 3.9982 872.6 3.9982 960.56 3.9982 1014.5 3.9982 1017.5 3.9982 860.6 3.9982 1039.5 3.9982 1059.5 3.9982 921.58 3.9982 936.57 3.9982 1024.5 3.9982 970.55 3.9982 1047.5 3.9982 917.58 3.9982 948.56 3.9982 978.55 3.9982 993.54 3.9982 1121.5 3.9982 944.57 3.9982 1005.5 3.9982 1037.5 3.9982 1261.4 3.9982 1062.5 3.9982 925.57 3.9982 976.55 3.9982 892.59 3.9982 972.55 3.9982 1135.5 3.9982 1044.5 3.9982 959.56 3.9982 990.54 3.9982 993.54 3.9982 1130.5 3.9982 919.58 3.9982 1025.5 3.9982 1001.5 3.9982 974.55 3.9982 1061.5 3.9982 1166.5 3.9982 1017.5 3.9982 1063.5 3.9982 1188.5 3.9982 964.56 3.9982 1047.5 3.9982 1210.4 3.9982 1087.5 3.9982 1151.5 3.9982 1096.5 3.9982 957.56 3.9982 1073.5 3.9982 925.57 3.9982 1051.5 3.9982 930.57 3.9982 1005.5 3.9982 977.55 3.9982 963.56 3.9982 1005.5 3.9982 954.56 3.9982 1025.5 3.9982 1039.5 3.9982 985.55 3.9982 923.58 3.9982 1087.5 3.9982 958.56 3.9982 1066.5 3.9982 1110.5 3.9982 934.57 3.9982 946.56 3.9982 + │ │ │ │ │ │ │ │ <---- 23 --------- 901 --------- 2150 -------- 3016 -------- 4093 -------- 5038 -------- 5962 -------- 6778 -------- 8056 -------- 9277 -------- 10530 -------- 11769 -------- 13020 -------- 14001 -------- 14982 -------- 16046 -------- 17072 -------- 18149 -------- 18935 -------- 19920 -------- 20876 -------- 21953 -------- 22859 -------- 23908 -------- 24923 -------- 25938 -------- 26865 -------- 27943 -------- 28938 -------- 29813 -------- 30844 -------- 31647 -------- 32585 -------- 33704 -------- 34617 -------- 35448 -------- 36338 ------- 37071 -------- 38029 -------- 39162 -------- 40163 -------- 41103 -------- 42008 -------- 42828 -------- 43789 -------- 44720 -------- 45920 -------- 47197 -------- 48149 -------- 49054 -------- 49906 -------- 51054 -------- 51940 -------- 53144 -------- 54301 -------- 55267 -------- 56318 -------- 57393 -------- 58223 -------- 59046 -------- 59995 -------- 61150 -------- 62024 -------- 62915 -------- 63943 -------- 65015 -------- 65840 -------- 66748 -------- 67584 -------- 68611 -------- 69729 -------- 70883 -------- 71725 -------- 72926 -------- 73924 -------- 74891 -------- 76176 -------- 77264 -------- 78405 -------- 79257 -------- 80310 -------- 81321 -------- 82270 -------- 83162 -------- 84049 -------- 85004 -------- 86255 -------- 87262 -------- 88259 -------- 89276 -------- 90374 -------- 91493 -------- 92454 -------- 93310 -------- 94246 -------- 95407 -------- 96295 -------- 97113 -------- 98069 -------- 98991 -------- 100116 ------- 100871 -------- 101805 -------- 102871 -------- 103776 ------- 104536 -------- 105497 -------- 106526 ------- 107293 -------- 108529 -------- 109518 -------- 110802 -------- 111761 -------- 113044 -------- 113923 -------- 115027 -------- 116119 ------- 116867 -------- 117681 -------- 118553 -------- 119501 -------- 120563 -------- 121563 -------- 122437 -------- 123400 -------- 124288 -------- 125209 -------- 126234 -------- 127465 -------- 128356 -------- 129458 -------- 130604 -------- 131668 ------- 132428 -------- 133365 -------- 134403 -------- 135446 ------- 136179 -------- 137262 -------- 138380 -------- 139242 -------- 140134 -------- 141190 -------- 142146 -------- 143244 -------- 144097 -------- 145011 -------- 145982 -------- 146981 -------- 148207 -------- 149115 -------- 150119 -------- 151183 -------- 152627 -------- 153735 -------- 154585 -------- 155535 -------- 156315 -------- 157258 -------- 158494 -------- 159570 -------- 160487 -------- 161464 -------- 162446 -------- 163673 -------- 164509 -------- 165550 -------- 166548 -------- 167495 -------- 168601 -------- 169889 -------- 170916 -------- 172026 -------- 173351 -------- 174278 -------- 175359 -------- 176720 -------- 177872 -------- 179135 -------- 180304 -------- 181217 -------- 182345 -------- 183194 -------- 184282 -------- 185142 -------- 186147 -------- 187099 -------- 188024 -------- 189029 -------- 189936 -------- 190977 -------- 192044 -------- 193012 -------- 193858 -------- 195011 -------- 195927 -------- 197043 -------- 198236 -------- 199104 -------- 199995 + │ │ │ │ │ │ │ │ histogram(140)= 0 7640 1.843e+05 8060 + │ │ │ │ │ │ │ │ <--- 'Brand#11' ----------- 'Brand#55' + │ │ │ │ │ │ │ │ histogram(142)= 0 4240 1.9186e+05 3900 + │ │ │ │ │ │ │ │ <--- 1 ------------- 50 + │ │ │ │ │ │ │ │ histogram(143)= 0 5460 1.8978e+05 4760 + │ │ │ │ │ │ │ │ <--- 'JUMBO BAG' ------------ 'WRAP PKG' + │ │ │ │ │ │ │ ├── key: (137) + │ │ │ │ │ │ │ └── fd: (137)-->(140,142,143) + │ │ │ │ │ │ └── filters + │ │ │ │ │ │ ├── (p_size:142 >= 1) AND (p_size:142 <= 10) [type=bool, outer=(142), constraints=(/142: [/1 - /10]; tight)] + │ │ │ │ │ │ ├── p_brand:140 = 'Brand#23' [type=bool, outer=(140), constraints=(/140: [/'Brand#23' - /'Brand#23']; tight), fd=()-->(140)] + │ │ │ │ │ │ └── p_container:143 IN ('MED BAG', 'MED BOX', 'MED PACK', 'MED PKG') [type=bool, outer=(143), constraints=(/143: [/'MED BAG' - /'MED BAG'] [/'MED BOX' - /'MED BOX'] [/'MED PACK' - /'MED PACK'] [/'MED PKG' - /'MED PKG']; tight)] + │ │ │ │ │ └── filters (true) + │ │ │ │ └── filters + │ │ │ │ ├── (l_quantity:123 >= 10.0) AND (l_quantity:123 <= 20.0) [type=bool, outer=(123), constraints=(/123: [/10.0 - /20.0]; tight)] + │ │ │ │ ├── l_shipmode:133 IN ('AIR', 'AIR REG') [type=bool, outer=(133), constraints=(/133: [/'AIR' - /'AIR'] [/'AIR REG' - /'AIR REG']; tight)] + │ │ │ │ └── l_shipinstruct:132 = 'DELIVER IN PERSON' [type=bool, outer=(132), constraints=(/132: [/'DELIVER IN PERSON' - /'DELIVER IN PERSON']; tight), fd=()-->(132)] + │ │ │ └── aggregations + │ │ │ ├── const-agg [as=l_partkey:62, type=int, outer=(62)] + │ │ │ │ └── l_partkey:62 [type=int] + │ │ │ ├── const-agg [as=l_quantity:65, type=float, outer=(65)] + │ │ │ │ └── l_quantity:65 [type=float] + │ │ │ ├── const-agg [as=l_extendedprice:66, type=float, outer=(66)] + │ │ │ │ └── l_extendedprice:66 [type=float] + │ │ │ ├── const-agg [as=l_discount:67, type=float, outer=(67)] + │ │ │ │ └── l_discount:67 [type=float] + │ │ │ ├── const-agg [as=l_shipinstruct:74, type=char, outer=(74)] + │ │ │ │ └── l_shipinstruct:74 [type=char] + │ │ │ ├── const-agg [as=l_shipmode:75, type=char, outer=(75)] + │ │ │ │ └── l_shipmode:75 [type=char] + │ │ │ ├── const-agg [as=p_brand:82, type=char, outer=(82)] + │ │ │ │ └── p_brand:82 [type=char] + │ │ │ ├── const-agg [as=p_size:84, type=int, outer=(84)] + │ │ │ │ └── p_size:84 [type=int] + │ │ │ └── const-agg [as=p_container:85, type=char, outer=(85)] + │ │ │ └── p_container:85 [type=char] + │ │ └── aggregations + │ │ ├── const-agg [as=l_partkey:2, type=int, outer=(2)] + │ │ │ └── l_partkey:2 [type=int] + │ │ ├── const-agg [as=l_quantity:5, type=float, outer=(5)] + │ │ │ └── l_quantity:5 [type=float] + │ │ ├── const-agg [as=l_extendedprice:6, type=float, outer=(6)] + │ │ │ └── l_extendedprice:6 [type=float] + │ │ ├── const-agg [as=l_discount:7, type=float, outer=(7)] + │ │ │ └── l_discount:7 [type=float] + │ │ ├── const-agg [as=l_shipinstruct:14, type=char, outer=(14)] + │ │ │ └── l_shipinstruct:14 [type=char] + │ │ ├── const-agg [as=l_shipmode:15, type=char, outer=(15)] + │ │ │ └── l_shipmode:15 [type=char] + │ │ ├── const-agg [as=p_brand:22, type=char, outer=(22)] + │ │ │ └── p_brand:22 [type=char] + │ │ ├── const-agg [as=p_size:24, type=int, outer=(24)] + │ │ │ └── p_size:24 [type=int] + │ │ └── const-agg [as=p_container:25, type=char, outer=(25)] + │ │ └── p_container:25 [type=char] │ └── projections │ └── l_extendedprice:6 * (1.0 - l_discount:7) [as=column30:30, type=float, outer=(6,7), immutable] └── aggregations @@ -148,7 +314,7 @@ column_names row_count distinct_count null_count column_names row_count_est row_count_err distinct_count_est distinct_count_err null_count_est null_count_err {column30} 186.00 1.54 186.00 1.54 0.00 1.00 -----Stats for q19_inner_join_3---- +----Stats for q19_project_3---- column_names row_count distinct_count null_count {l_discount} 121 11 0 {l_extendedprice} 121 118 0 @@ -173,41 +339,287 @@ column_names row_count_est row_count_err distinct_count_est distinct_co {p_partkey} 186.00 1.54 186.00 1.81 0.00 1.00 {p_size} 186.00 1.54 17.00 1.21 0.00 1.00 -----Stats for q19_select_4---- +----Stats for q19_distinct_on_4---- column_names row_count distinct_count null_count -{l_discount} 214377 11 0 -{l_extendedprice} 214377 188952 0 -{l_partkey} 214377 131422 0 -{l_quantity} 214377 50 0 -{l_shipinstruct} 214377 1 0 -{l_shipmode} 214377 1 0 +{l_discount} 121 11 0 +{l_extendedprice} 121 118 0 +{l_linenumber} 121 7 0 +{l_orderkey} 121 121 0 +{l_partkey} 121 103 0 +{l_quantity} 121 29 0 +{l_shipinstruct} 121 1 0 +{l_shipmode} 121 1 0 +{p_brand} 121 3 0 +{p_container} 121 12 0 +{p_partkey} 121 103 0 +{p_size} 121 14 0 +~~~~ +column_names row_count_est row_count_err distinct_count_est distinct_count_err null_count_est null_count_err +{l_discount} 182.00 1.50 182.00 16.55 <== 0.00 1.00 +{l_extendedprice} 182.00 1.50 182.00 1.54 0.00 1.00 +{l_linenumber} 182.00 1.50 14.00 2.00 <== 0.00 1.00 +{l_orderkey} 182.00 1.50 182.00 1.50 0.00 1.00 +{l_partkey} 182.00 1.50 182.00 1.77 0.00 1.00 +{l_quantity} 182.00 1.50 182.00 6.28 <== 0.00 1.00 +{l_shipinstruct} 182.00 1.50 182.00 182.00 <== 0.00 1.00 +{l_shipmode} 182.00 1.50 182.00 182.00 <== 0.00 1.00 +{p_brand} 182.00 1.50 182.00 60.67 <== 0.00 1.00 +{p_container} 182.00 1.50 182.00 15.17 <== 0.00 1.00 +{p_partkey} 182.00 1.50 163.00 1.58 0.00 1.00 +{p_size} 182.00 1.50 182.00 13.00 <== 0.00 1.00 + +----Stats for q19_union_all_5---- +column_names row_count distinct_count null_count +{l_discount} 121 11 0 +{l_extendedprice} 121 118 0 +{l_linenumber} 121 7 0 +{l_orderkey} 121 121 0 +{l_partkey} 121 103 0 +{l_quantity} 121 29 0 +{l_shipinstruct} 121 1 0 +{l_shipmode} 121 1 0 +{p_brand} 121 3 0 +{p_container} 121 12 0 +{p_partkey} 121 103 0 +{p_size} 121 14 0 +~~~~ +column_names row_count_est row_count_err distinct_count_est distinct_count_err null_count_est null_count_err +{l_discount} 182.00 1.50 22.00 2.00 <== 0.00 1.00 +{l_extendedprice} 182.00 1.50 182.00 1.54 0.00 1.00 +{l_linenumber} 182.00 1.50 14.00 2.00 <== 0.00 1.00 +{l_orderkey} 182.00 1.50 182.00 1.50 0.00 1.00 +{l_partkey} 182.00 1.50 163.00 1.58 0.00 1.00 +{l_quantity} 182.00 1.50 16.00 1.81 0.00 1.00 +{l_shipinstruct} 182.00 1.50 2.00 2.00 <== 0.00 1.00 +{l_shipmode} 182.00 1.50 4.00 4.00 <== 0.00 1.00 +{p_brand} 182.00 1.50 3.00 1.00 0.00 1.00 +{p_container} 182.00 1.50 12.00 1.00 0.00 1.00 +{p_partkey} 182.00 1.50 163.00 1.58 0.00 1.00 +{p_size} 182.00 1.50 22.00 1.57 0.00 1.00 + +----Stats for q19_lookup_join_6---- +column_names row_count distinct_count null_count +{l_discount} 25 9 0 +{l_extendedprice} 25 23 0 +{l_linenumber} 25 7 0 +{l_orderkey} 25 25 0 +{l_partkey} 25 21 0 +{l_quantity} 25 10 0 +{l_shipinstruct} 25 1 0 +{l_shipmode} 25 1 0 +{p_brand} 25 1 0 +{p_container} 25 4 0 +{p_partkey} 25 21 0 +{p_size} 25 5 0 +~~~~ +column_names row_count_est row_count_err distinct_count_est distinct_count_err null_count_est null_count_err +{l_discount} 100.00 4.00 <== 11.00 1.22 0.00 1.00 +{l_extendedprice} 100.00 4.00 <== 100.00 4.35 <== 0.00 1.00 +{l_linenumber} 100.00 4.00 <== 7.00 1.00 0.00 1.00 +{l_orderkey} 100.00 4.00 <== 100.00 4.00 <== 0.00 1.00 +{l_partkey} 100.00 4.00 <== 81.00 3.86 <== 0.00 1.00 +{l_quantity} 100.00 4.00 <== 11.00 1.10 0.00 1.00 +{l_shipinstruct} 100.00 4.00 <== 1.00 1.00 0.00 1.00 +{l_shipmode} 100.00 4.00 <== 2.00 2.00 <== 0.00 1.00 +{p_brand} 100.00 4.00 <== 1.00 1.00 0.00 1.00 +{p_container} 100.00 4.00 <== 4.00 1.00 0.00 1.00 +{p_partkey} 100.00 4.00 <== 81.00 3.86 <== 0.00 1.00 +{p_size} 100.00 4.00 <== 5.00 1.00 0.00 1.00 + +----Stats for q19_lookup_join_7---- +column_names row_count distinct_count null_count +{l_linenumber} 2622 7 0 +{l_orderkey} 2622 2617 0 +{l_partkey} 2622 88 0 +{p_brand} 2622 1 0 +{p_container} 2622 4 0 +{p_partkey} 2622 88 0 +{p_size} 2622 5 0 +~~~~ +column_names row_count_est row_count_err distinct_count_est distinct_count_err null_count_est null_count_err +{l_linenumber} 2438.00 1.08 7.00 1.00 0.00 1.00 +{l_orderkey} 2438.00 1.08 2436.00 1.07 0.00 1.00 +{l_partkey} 2438.00 1.08 81.00 1.09 0.00 1.00 +{p_brand} 2438.00 1.08 1.00 1.00 0.00 1.00 +{p_container} 2438.00 1.08 4.00 1.00 0.00 1.00 +{p_partkey} 2438.00 1.08 81.00 1.09 0.00 1.00 +{p_size} 2438.00 1.08 5.00 1.00 0.00 1.00 + +----Stats for q19_select_8---- +column_names row_count distinct_count null_count +{p_brand} 88 1 0 +{p_container} 88 4 0 +{p_partkey} 88 88 0 +{p_size} 88 5 0 +~~~~ +column_names row_count_est row_count_err distinct_count_est distinct_count_err null_count_est null_count_err +{p_brand} 81.00 1.09 1.00 1.00 0.00 1.00 +{p_container} 81.00 1.09 4.00 1.00 0.00 1.00 +{p_partkey} 81.00 1.09 81.00 1.09 0.00 1.00 +{p_size} 81.00 1.09 5.00 1.00 0.00 1.00 + +----Stats for q19_scan_9---- +column_names row_count distinct_count null_count +{p_brand} 200000 25 0 +{p_container} 200000 40 0 +{p_partkey} 200000 199241 0 +{p_size} 200000 50 0 +~~~~ +column_names row_count_est row_count_err distinct_count_est distinct_count_err null_count_est null_count_err +{p_brand} 200000.00 1.00 25.00 1.00 0.00 1.00 +{p_container} 200000.00 1.00 40.00 1.00 0.00 1.00 +{p_partkey} 200000.00 1.00 199241.00 1.00 0.00 1.00 +{p_size} 200000.00 1.00 50.00 1.00 0.00 1.00 + +----Stats for q19_project_10---- +column_names row_count distinct_count null_count +{l_discount} 96 11 0 +{l_extendedprice} 96 95 0 +{l_linenumber} 96 7 0 +{l_orderkey} 96 96 0 +{l_partkey} 96 82 0 +{l_quantity} 96 21 0 +{l_shipinstruct} 96 1 0 +{l_shipmode} 96 1 0 +{p_brand} 96 2 0 +{p_container} 96 8 0 +{p_partkey} 96 82 0 +{p_size} 96 14 0 +~~~~ +column_names row_count_est row_count_err distinct_count_est distinct_count_err null_count_est null_count_err +{l_discount} 82.00 1.17 11.00 1.00 0.00 1.00 +{l_extendedprice} 82.00 1.17 82.00 1.16 0.00 1.00 +{l_linenumber} 82.00 1.17 7.00 1.00 0.00 1.00 +{l_orderkey} 82.00 1.17 82.00 1.17 0.00 1.00 +{l_partkey} 82.00 1.17 82.00 1.00 0.00 1.00 +{l_quantity} 82.00 1.17 6.00 3.50 <== 0.00 1.00 +{l_shipinstruct} 82.00 1.17 1.00 1.00 0.00 1.00 +{l_shipmode} 82.00 1.17 2.00 2.00 <== 0.00 1.00 +{p_brand} 82.00 1.17 2.00 1.00 0.00 1.00 +{p_container} 82.00 1.17 8.00 1.00 0.00 1.00 +{p_partkey} 82.00 1.17 82.00 1.00 0.00 1.00 +{p_size} 82.00 1.17 17.00 1.21 0.00 1.00 + +----Stats for q19_distinct_on_11---- +column_names row_count distinct_count null_count +{l_discount} 96 11 0 +{l_extendedprice} 96 95 0 +{l_linenumber} 96 7 0 +{l_orderkey} 96 96 0 +{l_partkey} 96 82 0 +{l_quantity} 96 21 0 +{l_shipinstruct} 96 1 0 +{l_shipmode} 96 1 0 +{p_brand} 96 2 0 +{p_container} 96 8 0 +{p_partkey} 96 82 0 +{p_size} 96 14 0 +~~~~ +column_names row_count_est row_count_err distinct_count_est distinct_count_err null_count_est null_count_err +{l_discount} 487.00 5.07 <== 487.00 44.27 <== 0.00 1.00 +{l_extendedprice} 487.00 5.07 <== 487.00 5.13 <== 0.00 1.00 +{l_linenumber} 487.00 5.07 <== 14.00 2.00 <== 0.00 1.00 +{l_orderkey} 487.00 5.07 <== 486.00 5.06 <== 0.00 1.00 +{l_partkey} 487.00 5.07 <== 487.00 5.94 <== 0.00 1.00 +{l_quantity} 487.00 5.07 <== 487.00 23.19 <== 0.00 1.00 +{l_shipinstruct} 487.00 5.07 <== 487.00 487.00 <== 0.00 1.00 +{l_shipmode} 487.00 5.07 <== 487.00 487.00 <== 0.00 1.00 +{p_brand} 487.00 5.07 <== 487.00 243.50 <== 0.00 1.00 +{p_container} 487.00 5.07 <== 487.00 60.88 <== 0.00 1.00 +{p_partkey} 487.00 5.07 <== 402.00 4.90 <== 0.00 1.00 +{p_size} 487.00 5.07 <== 487.00 34.79 <== 0.00 1.00 + +----Stats for q19_union_all_12---- +column_names row_count distinct_count null_count +{l_discount} 96 11 0 +{l_extendedprice} 96 95 0 +{l_linenumber} 96 7 0 +{l_orderkey} 96 96 0 +{l_partkey} 96 82 0 +{l_quantity} 96 21 0 +{l_shipinstruct} 96 1 0 +{l_shipmode} 96 1 0 +{p_brand} 96 2 0 +{p_container} 96 8 0 +{p_partkey} 96 82 0 +{p_size} 96 14 0 ~~~~ column_names row_count_est row_count_err distinct_count_est distinct_count_err null_count_est null_count_err -{l_discount} 416015.00 1.94 <== 11.00 1.00 0.00 1.00 -{l_extendedprice} 416015.00 1.94 <== 344687.00 1.82 0.00 1.00 -{l_partkey} 416015.00 1.94 <== 176353.00 1.34 0.00 1.00 -{l_quantity} 416015.00 1.94 <== 50.00 1.00 0.00 1.00 -{l_shipinstruct} 416015.00 1.94 <== 1.00 1.00 0.00 1.00 -{l_shipmode} 416015.00 1.94 <== 2.00 2.00 <== 0.00 1.00 - -----Stats for q19_scan_5---- +{l_discount} 487.00 5.07 <== 22.00 2.00 <== 0.00 1.00 +{l_extendedprice} 487.00 5.07 <== 486.00 5.12 <== 0.00 1.00 +{l_linenumber} 487.00 5.07 <== 14.00 2.00 <== 0.00 1.00 +{l_orderkey} 487.00 5.07 <== 486.00 5.06 <== 0.00 1.00 +{l_partkey} 487.00 5.07 <== 402.00 4.90 <== 0.00 1.00 +{l_quantity} 487.00 5.07 <== 20.00 1.05 0.00 1.00 +{l_shipinstruct} 487.00 5.07 <== 2.00 2.00 <== 0.00 1.00 +{l_shipmode} 487.00 5.07 <== 4.00 4.00 <== 0.00 1.00 +{p_brand} 487.00 5.07 <== 2.00 1.00 0.00 1.00 +{p_container} 487.00 5.07 <== 8.00 1.00 0.00 1.00 +{p_partkey} 487.00 5.07 <== 402.00 4.90 <== 0.00 1.00 +{p_size} 487.00 5.07 <== 25.00 1.79 0.00 1.00 + +----Stats for q19_lookup_join_13---- column_names row_count distinct_count null_count -{l_discount} 6001215 11 0 -{l_extendedprice} 6001215 925955 0 -{l_partkey} 6001215 199241 0 -{l_quantity} 6001215 50 0 -{l_shipinstruct} 6001215 4 0 -{l_shipmode} 6001215 7 0 +{l_discount} 56 11 0 +{l_extendedprice} 56 56 0 +{l_linenumber} 56 7 0 +{l_orderkey} 56 56 0 +{l_partkey} 56 48 0 +{l_quantity} 56 11 0 +{l_shipinstruct} 56 1 0 +{l_shipmode} 56 1 0 +{p_brand} 56 1 0 +{p_container} 56 4 0 +{p_partkey} 56 48 0 +{p_size} 56 12 0 ~~~~ column_names row_count_est row_count_err distinct_count_est distinct_count_err null_count_est null_count_err -{l_discount} 6001215.00 1.00 11.00 1.00 0.00 1.00 -{l_extendedprice} 6001215.00 1.00 925955.00 1.00 0.00 1.00 -{l_partkey} 6001215.00 1.00 199241.00 1.00 0.00 1.00 -{l_quantity} 6001215.00 1.00 50.00 1.00 0.00 1.00 -{l_shipinstruct} 6001215.00 1.00 4.00 1.00 0.00 1.00 -{l_shipmode} 6001215.00 1.00 7.00 1.00 0.00 1.00 - -----Stats for q19_select_6---- +{l_discount} 292.00 5.21 <== 11.00 1.00 0.00 1.00 +{l_extendedprice} 292.00 5.21 <== 291.00 5.20 <== 0.00 1.00 +{l_linenumber} 292.00 5.21 <== 7.00 1.00 0.00 1.00 +{l_orderkey} 292.00 5.21 <== 291.00 5.20 <== 0.00 1.00 +{l_partkey} 292.00 5.21 <== 241.00 5.02 <== 0.00 1.00 +{l_quantity} 292.00 5.21 <== 10.00 1.10 0.00 1.00 +{l_shipinstruct} 292.00 5.21 <== 1.00 1.00 0.00 1.00 +{l_shipmode} 292.00 5.21 <== 2.00 2.00 <== 0.00 1.00 +{p_brand} 292.00 5.21 <== 1.00 1.00 0.00 1.00 +{p_container} 292.00 5.21 <== 4.00 1.00 0.00 1.00 +{p_partkey} 292.00 5.21 <== 241.00 5.02 <== 0.00 1.00 +{p_size} 292.00 5.21 <== 15.00 1.25 0.00 1.00 + +----Stats for q19_lookup_join_14---- +column_names row_count distinct_count null_count +{l_linenumber} 7020 7 0 +{l_orderkey} 7020 7016 0 +{l_partkey} 7020 238 0 +{p_brand} 7020 1 0 +{p_container} 7020 4 0 +{p_partkey} 7020 238 0 +{p_size} 7020 15 0 +~~~~ +column_names row_count_est row_count_err distinct_count_est distinct_count_err null_count_est null_count_err +{l_linenumber} 7256.00 1.03 7.00 1.00 0.00 1.00 +{l_orderkey} 7256.00 1.03 7239.00 1.03 0.00 1.00 +{l_partkey} 7256.00 1.03 241.00 1.01 0.00 1.00 +{p_brand} 7256.00 1.03 1.00 1.00 0.00 1.00 +{p_container} 7256.00 1.03 4.00 1.00 0.00 1.00 +{p_partkey} 7256.00 1.03 241.00 1.01 0.00 1.00 +{p_size} 7256.00 1.03 15.00 1.00 0.00 1.00 + +----Stats for q19_select_15---- +column_names row_count distinct_count null_count +{p_brand} 238 1 0 +{p_container} 238 4 0 +{p_partkey} 238 238 0 +{p_size} 238 15 0 +~~~~ +column_names row_count_est row_count_err distinct_count_est distinct_count_err null_count_est null_count_err +{p_brand} 241.00 1.01 1.00 1.00 0.00 1.00 +{p_container} 241.00 1.01 4.00 1.00 0.00 1.00 +{p_partkey} 241.00 1.01 241.00 1.01 0.00 1.00 +{p_size} 241.00 1.01 15.00 1.00 0.00 1.00 + +----Stats for q19_scan_16---- column_names row_count distinct_count null_count {p_brand} 200000 25 0 {p_container} 200000 40 0 @@ -220,7 +632,68 @@ column_names row_count_est row_count_err distinct_count_est distinct_count_ {p_partkey} 200000.00 1.00 199241.00 1.00 0.00 1.00 {p_size} 200000.00 1.00 50.00 1.00 0.00 1.00 -----Stats for q19_scan_7---- +----Stats for q19_lookup_join_17---- +column_names row_count distinct_count null_count +{l_discount} 40 11 0 +{l_extendedprice} 40 39 0 +{l_linenumber} 40 7 0 +{l_orderkey} 40 40 0 +{l_partkey} 40 34 0 +{l_quantity} 40 11 0 +{l_shipinstruct} 40 1 0 +{l_shipmode} 40 1 0 +{p_brand} 40 1 0 +{p_container} 40 4 0 +{p_partkey} 40 34 0 +{p_size} 40 10 0 +~~~~ +column_names row_count_est row_count_err distinct_count_est distinct_count_err null_count_est null_count_err +{l_discount} 195.00 4.88 <== 11.00 1.00 0.00 1.00 +{l_extendedprice} 195.00 4.88 <== 195.00 5.00 <== 0.00 1.00 +{l_linenumber} 195.00 4.88 <== 7.00 1.00 0.00 1.00 +{l_orderkey} 195.00 4.88 <== 195.00 4.88 <== 0.00 1.00 +{l_partkey} 195.00 4.88 <== 161.00 4.74 <== 0.00 1.00 +{l_quantity} 195.00 4.88 <== 10.00 1.10 0.00 1.00 +{l_shipinstruct} 195.00 4.88 <== 1.00 1.00 0.00 1.00 +{l_shipmode} 195.00 4.88 <== 2.00 2.00 <== 0.00 1.00 +{p_brand} 195.00 4.88 <== 1.00 1.00 0.00 1.00 +{p_container} 195.00 4.88 <== 4.00 1.00 0.00 1.00 +{p_partkey} 195.00 4.88 <== 161.00 4.74 <== 0.00 1.00 +{p_size} 195.00 4.88 <== 10.00 1.00 0.00 1.00 + +----Stats for q19_lookup_join_18---- +column_names row_count distinct_count null_count +{l_linenumber} 4659 7 0 +{l_orderkey} 4659 4593 0 +{l_partkey} 4659 159 0 +{p_brand} 4659 1 0 +{p_container} 4659 4 0 +{p_partkey} 4659 159 0 +{p_size} 4659 10 0 +~~~~ +column_names row_count_est row_count_err distinct_count_est distinct_count_err null_count_est null_count_err +{l_linenumber} 4847.00 1.04 7.00 1.00 0.00 1.00 +{l_orderkey} 4847.00 1.04 4840.00 1.05 0.00 1.00 +{l_partkey} 4847.00 1.04 161.00 1.01 0.00 1.00 +{p_brand} 4847.00 1.04 1.00 1.00 0.00 1.00 +{p_container} 4847.00 1.04 4.00 1.00 0.00 1.00 +{p_partkey} 4847.00 1.04 161.00 1.01 0.00 1.00 +{p_size} 4847.00 1.04 10.00 1.00 0.00 1.00 + +----Stats for q19_select_19---- +column_names row_count distinct_count null_count +{p_brand} 159 1 0 +{p_container} 159 4 0 +{p_partkey} 159 159 0 +{p_size} 159 10 0 +~~~~ +column_names row_count_est row_count_err distinct_count_est distinct_count_err null_count_est null_count_err +{p_brand} 161.00 1.01 1.00 1.00 0.00 1.00 +{p_container} 161.00 1.01 4.00 1.00 0.00 1.00 +{p_partkey} 161.00 1.01 161.00 1.01 0.00 1.00 +{p_size} 161.00 1.01 10.00 1.00 0.00 1.00 + +----Stats for q19_scan_20---- column_names row_count distinct_count null_count {p_brand} 200000 25 0 {p_container} 200000 40 0 diff --git a/pkg/sql/opt/xform/join_funcs.go b/pkg/sql/opt/xform/join_funcs.go index d4e09206d753..daa7cae02d7d 100644 --- a/pkg/sql/opt/xform/join_funcs.go +++ b/pkg/sql/opt/xform/join_funcs.go @@ -1528,12 +1528,13 @@ func (c *CustomFuncs) makeFilteredSelectForJoin( return newSelect } -// SplitJoinWithEquijoinDisjuncts checks a join relation for a disjunction of -// equijoin predicates in an InnerJoin, SemiJoin or AntiJoin. If present, and -// the inputs to the join are canonical scans, or Selects from canonical scans, -// it builds two new join relations of the same join type as the original, but -// with one disjunct assigned to firstJoin and the remaining disjuncts assigned -// to secondJoin. +// SplitJoinWithInterestingDisjuncts checks a join relation for a disjunction of +// interesting predicates in an InnerJoin, SemiJoin or AntiJoin. An "interesting +// predicate" is defined as an equijoin predicate or a predicate referencing +// only columns from a single table. If present, and the inputs to the join are +// canonical scans, or Selects from canonical scans, it builds two new join +// relations of the same join type as the original, but with one disjunct +// assigned to firstJoin and the remaining disjuncts assigned to secondJoin. // // In the case of inner join, newRelationCols contains the column ids from the // original Scans in the left and right inputs plus primary key columns from @@ -1544,9 +1545,9 @@ func (c *CustomFuncs) makeFilteredSelectForJoin( // aggCols contains the non-key columns of the left and right inputs. // groupingCols contains the primary key columns of the left and right inputs, // needed for deduplicating results. -// If there is no disjunction of equijoin predicates, or the join type is not +// If there is no disjunction of interesting predicates, or the join type is not // one of the supported join types listed above, ok=false is returned. -func (c *CustomFuncs) SplitJoinWithEquijoinDisjuncts( +func (c *CustomFuncs) SplitJoinWithInterestingDisjuncts( joinRel memo.RelExpr, joinFilters memo.FiltersExpr, ) ( firstJoin memo.RelExpr, @@ -1771,10 +1772,18 @@ func (c *CustomFuncs) CanHoistProjectInput(relation memo.RelExpr) (ok bool) { // findInterestingDisjunctionPairForJoin groups disjunction subexpressions into // an "interesting" pair of join predicates. // -// An "interesting" pair of predicates is one where one predicate is an -// equality predicate which could enable more performant joins than cross join, -// such as hash join or lookup join. At least one predicate in the disjunction -// must be an equality join term referencing both input relations. When there +// An "interesting" pair of predicates is one where one predicate is: +// +// a) a conjunction in which at least one conjunct references only columns +// bound by a single table, thus enabling predicate push-down +// +// OR +// +// b) an equality predicate referencing both input relations which could +// enable more performant joins than cross join, such as hash join or +// lookup join. +// +// At least one predicate in the disjunction must be "interesting". When there // are more than two predicates, the deepest leaf node in the left depth OrExpr // tree is returned as "left" and the remaining predicates are built into a // brand new OrExpr chain and returned as "right". @@ -1783,9 +1792,9 @@ func (c *CustomFuncs) CanHoistProjectInput(relation memo.RelExpr) (ok bool) { // pre-checked to be canonical scans, or Selects from canonical scans, and // leftScan and rightScan refer to those scans. // -// findInterestingDisjunctionPairForJoin returns an ok=false if at least one of -// the ORed predicates is not an equality join term referencing both input -// relations, or if joinRel is not a join relation. +// findInterestingDisjunctionPairForJoin returns an ok=false if there is not at +// least one interesting predicate among the ORed predicates, or if joinRel is +// not a join relation. func (c *CustomFuncs) findInterestingDisjunctionPairForJoin( joinRel memo.RelExpr, filter *memo.FiltersItem, leftScan *memo.ScanExpr, rightScan *memo.ScanExpr, ) (left opt.ScalarExpr, right opt.ScalarExpr, ok bool) { @@ -1796,8 +1805,21 @@ func (c *CustomFuncs) findInterestingDisjunctionPairForJoin( // isJoinPred tests if a predicate is a join predicate which references columns // from both leftRelColSet and rightRelColSet, as indicated in the predicate's // referenced columns, predCols. - isJoinPred := func(predCols, leftRelColSet, rightRelColSet opt.ColSet) bool { - return leftRelColSet.Intersects(predCols) && rightRelColSet.Intersects(predCols) + isJoinPred := func(eqExpr *memo.EqExpr, leftRelColSet, rightRelColSet opt.ColSet) bool { + if leftCol, ok := eqExpr.Left.(*memo.VariableExpr); ok { + if rightCol, ok := eqExpr.Right.(*memo.VariableExpr); ok { + return (leftRelColSet.Contains(leftCol.Col) && rightRelColSet.Contains(rightCol.Col)) || + (leftRelColSet.Contains(rightCol.Col) && rightRelColSet.Contains(leftCol.Col)) + } + } + return false + } + + // boundBySingleTable tests if an expression only references columns from + // either the left or right tables, but not both. + boundBySingleTable := func(expr opt.ScalarExpr, leftRelColSet, rightRelColSet opt.ColSet) bool { + cols := c.OuterCols(expr) + return cols.SubsetOf(leftRelColSet) || cols.SubsetOf(rightRelColSet) } var leftExprs memo.ScalarListExpr @@ -1806,18 +1828,19 @@ func (c *CustomFuncs) findInterestingDisjunctionPairForJoin( rightColSet := c.OutputCols(rightScan) // An ANDed expression is interesting if it has at least one equality join - // predicate. + // predicate or at least one predicate referencing only columns from a single + // table. interesting := false - var hasJoinEquality func(opt.ScalarExpr) bool - hasJoinEquality = func(expr opt.ScalarExpr) bool { + var isInteresting func(opt.ScalarExpr) bool + isInteresting = func(expr opt.ScalarExpr) bool { switch t := expr.(type) { case *memo.AndExpr: - return hasJoinEquality(t.Left) || hasJoinEquality(t.Right) + return isInteresting(t.Left) || isInteresting(t.Right) case *memo.EqExpr: - cols := c.OuterCols(expr) - return isJoinPred(cols, leftColSet, rightColSet) + return isJoinPred(t, leftColSet, rightColSet) || + boundBySingleTable(t, leftColSet, rightColSet) default: - return false + return boundBySingleTable(t, leftColSet, rightColSet) } } @@ -1831,7 +1854,7 @@ func (c *CustomFuncs) findInterestingDisjunctionPairForJoin( collect(t.Right) return default: - interesting = hasJoinEquality(expr) + interesting = isInteresting(expr) } if interesting && len(leftExprs) == 0 { diff --git a/pkg/sql/opt/xform/rules/join.opt b/pkg/sql/opt/xform/rules/join.opt index baa7c58e2094..55e1f7782407 100644 --- a/pkg/sql/opt/xform/rules/join.opt +++ b/pkg/sql/opt/xform/rules/join.opt @@ -134,7 +134,7 @@ # the case of inner join, or in the case or semijoin, the primary key columns # of the left. # -# The call to SplitJoinWithEquijoinDisjuncts adds primary key columns to the +# The call to SplitJoinWithInterestingDisjuncts adds primary key columns to the # original Scan ColSet which the replace pattern removes by adding a Project as # the last operation. # Inclusion of the primary keys is required to prevent the generated Union from @@ -160,7 +160,7 @@ $aggCols $groupingCols $ok - ):(SplitJoinWithEquijoinDisjuncts (Root) $on) + ):(SplitJoinWithInterestingDisjuncts (Root) $on) $ok ) * @@ -203,7 +203,7 @@ $aggCols $groupingCols $ok - ):(SplitJoinWithEquijoinDisjuncts (Root) $on) + ):(SplitJoinWithInterestingDisjuncts (Root) $on) $ok ) * diff --git a/pkg/sql/opt/xform/testdata/external/tpch b/pkg/sql/opt/xform/testdata/external/tpch index 08ae89801b81..8d43f1f7600e 100644 --- a/pkg/sql/opt/xform/testdata/external/tpch +++ b/pkg/sql/opt/xform/testdata/external/tpch @@ -2049,31 +2049,155 @@ scalar-group-by ├── project │ ├── columns: column30:30!null │ ├── immutable - │ ├── inner-join (hash) + │ ├── project │ │ ├── columns: l_partkey:2!null l_quantity:5!null l_extendedprice:6!null l_discount:7!null l_shipinstruct:14!null l_shipmode:15!null p_partkey:19!null p_brand:22!null p_size:24!null p_container:25!null - │ │ ├── multiplicity: left-rows(zero-or-one), right-rows(zero-or-more) │ │ ├── fd: ()-->(14), (19)-->(22,24,25), (2)==(19), (19)==(2) - │ │ ├── select - │ │ │ ├── columns: l_partkey:2!null l_quantity:5!null l_extendedprice:6!null l_discount:7!null l_shipinstruct:14!null l_shipmode:15!null - │ │ │ ├── fd: ()-->(14) - │ │ │ ├── scan lineitem - │ │ │ │ └── columns: l_partkey:2!null l_quantity:5!null l_extendedprice:6!null l_discount:7!null l_shipinstruct:14!null l_shipmode:15!null - │ │ │ └── filters - │ │ │ ├── l_shipmode:15 IN ('AIR', 'AIR REG') [outer=(15), constraints=(/15: [/'AIR' - /'AIR'] [/'AIR REG' - /'AIR REG']; tight)] - │ │ │ └── l_shipinstruct:14 = 'DELIVER IN PERSON' [outer=(14), constraints=(/14: [/'DELIVER IN PERSON' - /'DELIVER IN PERSON']; tight), fd=()-->(14)] - │ │ ├── select - │ │ │ ├── columns: p_partkey:19!null p_brand:22!null p_size:24!null p_container:25!null - │ │ │ ├── key: (19) - │ │ │ ├── fd: (19)-->(22,24,25) - │ │ │ ├── scan part - │ │ │ │ ├── columns: p_partkey:19!null p_brand:22!null p_size:24!null p_container:25!null - │ │ │ │ ├── key: (19) - │ │ │ │ └── fd: (19)-->(22,24,25) - │ │ │ └── filters - │ │ │ └── p_size:24 >= 1 [outer=(24), constraints=(/24: [/1 - ]; tight)] - │ │ └── filters - │ │ ├── p_partkey:19 = l_partkey:2 [outer=(2,19), constraints=(/2: (/NULL - ]; /19: (/NULL - ]), fd=(2)==(19), (19)==(2)] - │ │ └── ((((((p_brand:22 = 'Brand#12') AND (p_container:25 IN ('SM BOX', 'SM CASE', 'SM PACK', 'SM PKG'))) AND (l_quantity:5 >= 1.0)) AND (l_quantity:5 <= 11.0)) AND (p_size:24 <= 5)) OR (((((p_brand:22 = 'Brand#23') AND (p_container:25 IN ('MED BAG', 'MED BOX', 'MED PACK', 'MED PKG'))) AND (l_quantity:5 >= 10.0)) AND (l_quantity:5 <= 20.0)) AND (p_size:24 <= 10))) OR (((((p_brand:22 = 'Brand#34') AND (p_container:25 IN ('LG BOX', 'LG CASE', 'LG PACK', 'LG PKG'))) AND (l_quantity:5 >= 20.0)) AND (l_quantity:5 <= 30.0)) AND (p_size:24 <= 15)) [outer=(5,22,24,25), constraints=(/5: [/1.0 - /30.0]; /22: [/'Brand#12' - /'Brand#12'] [/'Brand#23' - /'Brand#23'] [/'Brand#34' - /'Brand#34']; /24: (/NULL - /15]; /25: [/'LG BOX' - /'LG BOX'] [/'LG CASE' - /'LG CASE'] [/'LG PACK' - /'LG PACK'] [/'LG PKG' - /'LG PKG'] [/'MED BAG' - /'MED BAG'] [/'MED BOX' - /'MED BOX'] [/'MED PACK' - /'MED PACK'] [/'MED PKG' - /'MED PKG'] [/'SM BOX' - /'SM BOX'] [/'SM CASE' - /'SM CASE'] [/'SM PACK' - /'SM PACK'] [/'SM PKG' - /'SM PKG'])] + │ │ └── distinct-on + │ │ ├── columns: l_orderkey:1!null l_partkey:2!null l_linenumber:4!null l_quantity:5!null l_extendedprice:6!null l_discount:7!null l_shipinstruct:14!null l_shipmode:15!null p_partkey:19!null p_brand:22!null p_size:24!null p_container:25!null + │ │ ├── grouping columns: l_orderkey:1!null l_linenumber:4!null p_partkey:19!null + │ │ ├── key: (1,4,19) + │ │ ├── fd: (2)==(19), (19)==(2), (1,4,19)-->(2,5-7,14,15,22,24,25) + │ │ ├── union-all + │ │ │ ├── columns: l_orderkey:1!null l_partkey:2!null l_linenumber:4!null l_quantity:5!null l_extendedprice:6!null l_discount:7!null l_shipinstruct:14!null l_shipmode:15!null p_partkey:19!null p_brand:22!null p_size:24!null p_container:25!null + │ │ │ ├── left columns: l_orderkey:32 l_partkey:33 l_linenumber:35 l_quantity:36 l_extendedprice:37 l_discount:38 l_shipinstruct:45 l_shipmode:46 p_partkey:50 p_brand:53 p_size:55 p_container:56 + │ │ │ ├── right columns: l_orderkey:61 l_partkey:62 l_linenumber:64 l_quantity:65 l_extendedprice:66 l_discount:67 l_shipinstruct:74 l_shipmode:75 p_partkey:79 p_brand:82 p_size:84 p_container:85 + │ │ │ ├── fd: (2)==(19), (19)==(2) + │ │ │ ├── inner-join (lookup lineitem) + │ │ │ │ ├── columns: l_orderkey:32!null l_partkey:33!null l_linenumber:35!null l_quantity:36!null l_extendedprice:37!null l_discount:38!null l_shipinstruct:45!null l_shipmode:46!null p_partkey:50!null p_brand:53!null p_size:55!null p_container:56!null + │ │ │ │ ├── key columns: [32 35] = [32 35] + │ │ │ │ ├── lookup columns are key + │ │ │ │ ├── key: (32,35) + │ │ │ │ ├── fd: ()-->(45,53), (32,35)-->(33,36-38,46), (50)-->(55,56), (33)==(50), (50)==(33) + │ │ │ │ ├── inner-join (lookup lineitem@l_pk) + │ │ │ │ │ ├── columns: l_orderkey:32!null l_partkey:33!null l_linenumber:35!null p_partkey:50!null p_brand:53!null p_size:55!null p_container:56!null + │ │ │ │ │ ├── key columns: [50] = [33] + │ │ │ │ │ ├── key: (32,35) + │ │ │ │ │ ├── fd: ()-->(53), (50)-->(55,56), (32,35)-->(33), (33)==(50), (50)==(33) + │ │ │ │ │ ├── select + │ │ │ │ │ │ ├── columns: p_partkey:50!null p_brand:53!null p_size:55!null p_container:56!null + │ │ │ │ │ │ ├── key: (50) + │ │ │ │ │ │ ├── fd: ()-->(53), (50)-->(55,56) + │ │ │ │ │ │ ├── scan part + │ │ │ │ │ │ │ ├── columns: p_partkey:50!null p_brand:53!null p_size:55!null p_container:56!null + │ │ │ │ │ │ │ ├── key: (50) + │ │ │ │ │ │ │ └── fd: (50)-->(53,55,56) + │ │ │ │ │ │ └── filters + │ │ │ │ │ │ ├── (p_size:55 >= 1) AND (p_size:55 <= 5) [outer=(55), constraints=(/55: [/1 - /5]; tight)] + │ │ │ │ │ │ ├── p_brand:53 = 'Brand#12' [outer=(53), constraints=(/53: [/'Brand#12' - /'Brand#12']; tight), fd=()-->(53)] + │ │ │ │ │ │ └── p_container:56 IN ('SM BOX', 'SM CASE', 'SM PACK', 'SM PKG') [outer=(56), constraints=(/56: [/'SM BOX' - /'SM BOX'] [/'SM CASE' - /'SM CASE'] [/'SM PACK' - /'SM PACK'] [/'SM PKG' - /'SM PKG']; tight)] + │ │ │ │ │ └── filters (true) + │ │ │ │ └── filters + │ │ │ │ ├── (l_quantity:36 >= 1.0) AND (l_quantity:36 <= 11.0) [outer=(36), constraints=(/36: [/1.0 - /11.0]; tight)] + │ │ │ │ ├── l_shipmode:46 IN ('AIR', 'AIR REG') [outer=(46), constraints=(/46: [/'AIR' - /'AIR'] [/'AIR REG' - /'AIR REG']; tight)] + │ │ │ │ └── l_shipinstruct:45 = 'DELIVER IN PERSON' [outer=(45), constraints=(/45: [/'DELIVER IN PERSON' - /'DELIVER IN PERSON']; tight), fd=()-->(45)] + │ │ │ └── project + │ │ │ ├── columns: l_orderkey:61!null l_partkey:62!null l_linenumber:64!null l_quantity:65!null l_extendedprice:66!null l_discount:67!null l_shipinstruct:74!null l_shipmode:75!null p_partkey:79!null p_brand:82!null p_size:84!null p_container:85!null + │ │ │ ├── key: (61,64) + │ │ │ ├── fd: ()-->(74), (61,64)-->(62,65-67,75), (79)-->(82,84,85), (62)==(79), (79)==(62) + │ │ │ └── distinct-on + │ │ │ ├── columns: l_orderkey:61!null l_partkey:62!null l_linenumber:64!null l_quantity:65!null l_extendedprice:66!null l_discount:67!null l_shipinstruct:74!null l_shipmode:75!null p_partkey:79!null p_brand:82!null p_size:84!null p_container:85!null + │ │ │ ├── grouping columns: l_orderkey:61!null l_linenumber:64!null p_partkey:79!null + │ │ │ ├── key: (61,64,79) + │ │ │ ├── fd: (62)==(79), (79)==(62), (61,64,79)-->(62,65-67,74,75,82,84,85) + │ │ │ ├── union-all + │ │ │ │ ├── columns: l_orderkey:61!null l_partkey:62!null l_linenumber:64!null l_quantity:65!null l_extendedprice:66!null l_discount:67!null l_shipinstruct:74!null l_shipmode:75!null p_partkey:79!null p_brand:82!null p_size:84!null p_container:85!null + │ │ │ │ ├── left columns: l_orderkey:90 l_partkey:91 l_linenumber:93 l_quantity:94 l_extendedprice:95 l_discount:96 l_shipinstruct:103 l_shipmode:104 p_partkey:108 p_brand:111 p_size:113 p_container:114 + │ │ │ │ ├── right columns: l_orderkey:119 l_partkey:120 l_linenumber:122 l_quantity:123 l_extendedprice:124 l_discount:125 l_shipinstruct:132 l_shipmode:133 p_partkey:137 p_brand:140 p_size:142 p_container:143 + │ │ │ │ ├── fd: (62)==(79), (79)==(62) + │ │ │ │ ├── inner-join (lookup lineitem) + │ │ │ │ │ ├── columns: l_orderkey:90!null l_partkey:91!null l_linenumber:93!null l_quantity:94!null l_extendedprice:95!null l_discount:96!null l_shipinstruct:103!null l_shipmode:104!null p_partkey:108!null p_brand:111!null p_size:113!null p_container:114!null + │ │ │ │ │ ├── key columns: [90 93] = [90 93] + │ │ │ │ │ ├── lookup columns are key + │ │ │ │ │ ├── key: (90,93) + │ │ │ │ │ ├── fd: ()-->(103,111), (90,93)-->(91,94-96,104), (108)-->(113,114), (91)==(108), (108)==(91) + │ │ │ │ │ ├── inner-join (lookup lineitem@l_pk) + │ │ │ │ │ │ ├── columns: l_orderkey:90!null l_partkey:91!null l_linenumber:93!null p_partkey:108!null p_brand:111!null p_size:113!null p_container:114!null + │ │ │ │ │ │ ├── key columns: [108] = [91] + │ │ │ │ │ │ ├── key: (90,93) + │ │ │ │ │ │ ├── fd: ()-->(111), (108)-->(113,114), (90,93)-->(91), (91)==(108), (108)==(91) + │ │ │ │ │ │ ├── select + │ │ │ │ │ │ │ ├── columns: p_partkey:108!null p_brand:111!null p_size:113!null p_container:114!null + │ │ │ │ │ │ │ ├── key: (108) + │ │ │ │ │ │ │ ├── fd: ()-->(111), (108)-->(113,114) + │ │ │ │ │ │ │ ├── scan part + │ │ │ │ │ │ │ │ ├── columns: p_partkey:108!null p_brand:111!null p_size:113!null p_container:114!null + │ │ │ │ │ │ │ │ ├── key: (108) + │ │ │ │ │ │ │ │ └── fd: (108)-->(111,113,114) + │ │ │ │ │ │ │ └── filters + │ │ │ │ │ │ │ ├── (p_size:113 >= 1) AND (p_size:113 <= 15) [outer=(113), constraints=(/113: [/1 - /15]; tight)] + │ │ │ │ │ │ │ ├── p_brand:111 = 'Brand#34' [outer=(111), constraints=(/111: [/'Brand#34' - /'Brand#34']; tight), fd=()-->(111)] + │ │ │ │ │ │ │ └── p_container:114 IN ('LG BOX', 'LG CASE', 'LG PACK', 'LG PKG') [outer=(114), constraints=(/114: [/'LG BOX' - /'LG BOX'] [/'LG CASE' - /'LG CASE'] [/'LG PACK' - /'LG PACK'] [/'LG PKG' - /'LG PKG']; tight)] + │ │ │ │ │ │ └── filters (true) + │ │ │ │ │ └── filters + │ │ │ │ │ ├── (l_quantity:94 >= 20.0) AND (l_quantity:94 <= 30.0) [outer=(94), constraints=(/94: [/20.0 - /30.0]; tight)] + │ │ │ │ │ ├── l_shipmode:104 IN ('AIR', 'AIR REG') [outer=(104), constraints=(/104: [/'AIR' - /'AIR'] [/'AIR REG' - /'AIR REG']; tight)] + │ │ │ │ │ └── l_shipinstruct:103 = 'DELIVER IN PERSON' [outer=(103), constraints=(/103: [/'DELIVER IN PERSON' - /'DELIVER IN PERSON']; tight), fd=()-->(103)] + │ │ │ │ └── inner-join (lookup lineitem) + │ │ │ │ ├── columns: l_orderkey:119!null l_partkey:120!null l_linenumber:122!null l_quantity:123!null l_extendedprice:124!null l_discount:125!null l_shipinstruct:132!null l_shipmode:133!null p_partkey:137!null p_brand:140!null p_size:142!null p_container:143!null + │ │ │ │ ├── key columns: [119 122] = [119 122] + │ │ │ │ ├── lookup columns are key + │ │ │ │ ├── key: (119,122) + │ │ │ │ ├── fd: ()-->(132,140), (119,122)-->(120,123-125,133), (137)-->(142,143), (120)==(137), (137)==(120) + │ │ │ │ ├── inner-join (lookup lineitem@l_pk) + │ │ │ │ │ ├── columns: l_orderkey:119!null l_partkey:120!null l_linenumber:122!null p_partkey:137!null p_brand:140!null p_size:142!null p_container:143!null + │ │ │ │ │ ├── key columns: [137] = [120] + │ │ │ │ │ ├── key: (119,122) + │ │ │ │ │ ├── fd: ()-->(140), (137)-->(142,143), (119,122)-->(120), (120)==(137), (137)==(120) + │ │ │ │ │ ├── select + │ │ │ │ │ │ ├── columns: p_partkey:137!null p_brand:140!null p_size:142!null p_container:143!null + │ │ │ │ │ │ ├── key: (137) + │ │ │ │ │ │ ├── fd: ()-->(140), (137)-->(142,143) + │ │ │ │ │ │ ├── scan part + │ │ │ │ │ │ │ ├── columns: p_partkey:137!null p_brand:140!null p_size:142!null p_container:143!null + │ │ │ │ │ │ │ ├── key: (137) + │ │ │ │ │ │ │ └── fd: (137)-->(140,142,143) + │ │ │ │ │ │ └── filters + │ │ │ │ │ │ ├── (p_size:142 >= 1) AND (p_size:142 <= 10) [outer=(142), constraints=(/142: [/1 - /10]; tight)] + │ │ │ │ │ │ ├── p_brand:140 = 'Brand#23' [outer=(140), constraints=(/140: [/'Brand#23' - /'Brand#23']; tight), fd=()-->(140)] + │ │ │ │ │ │ └── p_container:143 IN ('MED BAG', 'MED BOX', 'MED PACK', 'MED PKG') [outer=(143), constraints=(/143: [/'MED BAG' - /'MED BAG'] [/'MED BOX' - /'MED BOX'] [/'MED PACK' - /'MED PACK'] [/'MED PKG' - /'MED PKG']; tight)] + │ │ │ │ │ └── filters (true) + │ │ │ │ └── filters + │ │ │ │ ├── (l_quantity:123 >= 10.0) AND (l_quantity:123 <= 20.0) [outer=(123), constraints=(/123: [/10.0 - /20.0]; tight)] + │ │ │ │ ├── l_shipmode:133 IN ('AIR', 'AIR REG') [outer=(133), constraints=(/133: [/'AIR' - /'AIR'] [/'AIR REG' - /'AIR REG']; tight)] + │ │ │ │ └── l_shipinstruct:132 = 'DELIVER IN PERSON' [outer=(132), constraints=(/132: [/'DELIVER IN PERSON' - /'DELIVER IN PERSON']; tight), fd=()-->(132)] + │ │ │ └── aggregations + │ │ │ ├── const-agg [as=l_partkey:62, outer=(62)] + │ │ │ │ └── l_partkey:62 + │ │ │ ├── const-agg [as=l_quantity:65, outer=(65)] + │ │ │ │ └── l_quantity:65 + │ │ │ ├── const-agg [as=l_extendedprice:66, outer=(66)] + │ │ │ │ └── l_extendedprice:66 + │ │ │ ├── const-agg [as=l_discount:67, outer=(67)] + │ │ │ │ └── l_discount:67 + │ │ │ ├── const-agg [as=l_shipinstruct:74, outer=(74)] + │ │ │ │ └── l_shipinstruct:74 + │ │ │ ├── const-agg [as=l_shipmode:75, outer=(75)] + │ │ │ │ └── l_shipmode:75 + │ │ │ ├── const-agg [as=p_brand:82, outer=(82)] + │ │ │ │ └── p_brand:82 + │ │ │ ├── const-agg [as=p_size:84, outer=(84)] + │ │ │ │ └── p_size:84 + │ │ │ └── const-agg [as=p_container:85, outer=(85)] + │ │ │ └── p_container:85 + │ │ └── aggregations + │ │ ├── const-agg [as=l_partkey:2, outer=(2)] + │ │ │ └── l_partkey:2 + │ │ ├── const-agg [as=l_quantity:5, outer=(5)] + │ │ │ └── l_quantity:5 + │ │ ├── const-agg [as=l_extendedprice:6, outer=(6)] + │ │ │ └── l_extendedprice:6 + │ │ ├── const-agg [as=l_discount:7, outer=(7)] + │ │ │ └── l_discount:7 + │ │ ├── const-agg [as=l_shipinstruct:14, outer=(14)] + │ │ │ └── l_shipinstruct:14 + │ │ ├── const-agg [as=l_shipmode:15, outer=(15)] + │ │ │ └── l_shipmode:15 + │ │ ├── const-agg [as=p_brand:22, outer=(22)] + │ │ │ └── p_brand:22 + │ │ ├── const-agg [as=p_size:24, outer=(24)] + │ │ │ └── p_size:24 + │ │ └── const-agg [as=p_container:25, outer=(25)] + │ │ └── p_container:25 │ └── projections │ └── l_extendedprice:6 * (1.0 - l_discount:7) [as=column30:30, outer=(6,7), immutable] └── aggregations diff --git a/pkg/sql/opt/xform/testdata/physprops/ordering b/pkg/sql/opt/xform/testdata/physprops/ordering index f111f5bcbae5..f57603b9aa02 100644 --- a/pkg/sql/opt/xform/testdata/physprops/ordering +++ b/pkg/sql/opt/xform/testdata/physprops/ordering @@ -2923,28 +2923,28 @@ project ├── fd: (2)==(6), (6)==(2), (2)-->(1,5) ├── ordering: +(2|6) [actual: +2] ├── inner-join (merge) - │ ├── columns: t0_85393.c0:9 t0_85393.rowid:10!null t1_85393.c0:13 t1_85393.rowid:14!null - │ ├── left ordering: +10 - │ ├── right ordering: +14 - │ ├── key: (14) - │ ├── fd: (10)-->(9), (14)-->(13), (10)==(14), (14)==(10) - │ ├── ordering: +(10|14) [actual: +10] + │ ├── columns: t0_85393.c0:17 t0_85393.rowid:18!null t1_85393.c0:21 t1_85393.rowid:22!null + │ ├── left ordering: +18 + │ ├── right ordering: +22 + │ ├── key: (22) + │ ├── fd: (18)-->(17), (22)-->(21), (18)==(22), (22)==(18) + │ ├── ordering: +(18|22) [actual: +18] │ ├── scan t0_85393 - │ │ ├── columns: t0_85393.c0:9 t0_85393.rowid:10!null - │ │ ├── key: (10) - │ │ ├── fd: (10)-->(9) - │ │ └── ordering: +10 + │ │ ├── columns: t0_85393.c0:17 t0_85393.rowid:18!null + │ │ ├── key: (18) + │ │ ├── fd: (18)-->(17) + │ │ └── ordering: +18 │ ├── scan t1_85393 - │ │ ├── columns: t1_85393.c0:13 t1_85393.rowid:14!null - │ │ ├── key: (14) - │ │ ├── fd: (14)-->(13) - │ │ └── ordering: +14 + │ │ ├── columns: t1_85393.c0:21 t1_85393.rowid:22!null + │ │ ├── key: (22) + │ │ ├── fd: (22)-->(21) + │ │ └── ordering: +22 │ └── filters (true) └── projections - ├── t0_85393.c0:9 [as=t0_85393.c0:1, outer=(9)] - ├── t0_85393.rowid:10 [as=t0_85393.rowid:2, outer=(10)] - ├── t1_85393.c0:13 [as=t1_85393.c0:5, outer=(13)] - └── t1_85393.rowid:14 [as=t1_85393.rowid:6, outer=(14)] + ├── t0_85393.c0:17 [as=t0_85393.c0:1, outer=(17)] + ├── t0_85393.rowid:18 [as=t0_85393.rowid:2, outer=(18)] + ├── t1_85393.c0:21 [as=t1_85393.c0:5, outer=(21)] + └── t1_85393.rowid:22 [as=t1_85393.rowid:6, outer=(22)] # Regression test for #83793 - include scan columns that are constrained to be # constant in the provided ordering when they are in the output of the scan. diff --git a/pkg/sql/opt/xform/testdata/rules/disjunction_in_join b/pkg/sql/opt/xform/testdata/rules/disjunction_in_join index 19a3db8a5805..f0b2b3eee3fb 100644 --- a/pkg/sql/opt/xform/testdata/rules/disjunction_in_join +++ b/pkg/sql/opt/xform/testdata/rules/disjunction_in_join @@ -25,6 +25,31 @@ CREATE TABLE d(d1 INT, d2 INT, d3 INT, d4 INT, INDEX d (d1) STORING (d2, d3, d4)) ---- +exec-ddl +CREATE TABLE e ( + e1 INT PRIMARY KEY, + e2 INT NOT NULL, + e3 INT NOT NULL, + e4 STRING NOT NULL, + e5 INT NULL, + INDEX (e2 ASC, e3 ASC, e4 ASC), + INDEX (e5 ASC), + INDEX (e3 ASC, e5 ASC, e4 ASC), + INDEX (e3 ASC) WHERE e4 IN ('a', 'b') +) +---- + +exec-ddl +CREATE TABLE f ( + f1 INT PRIMARY KEY, + f2 INT NULL, + f3 INT NULL, + f4 INT NOT NULL, + INDEX (f3 ASC), + INDEX (f2 ASC) STORING (f3) +) +---- + # -------------------------------------------------- # InnerJoin # -------------------------------------------------- @@ -366,40 +391,40 @@ project │ ├── columns: b1:1 b2:2 b3:3 b4:4 b.rowid:5!null d1:8 d2:9 d3:10 d4:11 d.rowid:12!null │ ├── left columns: b1:15 b2:16 b3:17 b4:18 b.rowid:19 d1:22 d2:23 d3:24 d4:25 d.rowid:26 │ ├── right columns: b1:29 b2:30 b3:31 b4:32 b.rowid:33 d1:36 d2:37 d3:38 d4:39 d.rowid:40 - │ ├── inner-join (hash) - │ │ ├── columns: b1:15 b2:16 b3:17!null b4:18 b.rowid:19!null d1:22 d2:23 d3:24!null d4:25 d.rowid:26!null + │ ├── inner-join (cross) + │ │ ├── columns: b1:15!null b2:16!null b3:17 b4:18 b.rowid:19!null d1:22 d2:23 d3:24 d4:25 d.rowid:26!null │ │ ├── key: (19,26) - │ │ ├── fd: (19)-->(15-18), (26)-->(22-25), (17)==(24), (24)==(17) - │ │ ├── scan b - │ │ │ ├── columns: b1:15 b2:16 b3:17 b4:18 b.rowid:19!null - │ │ │ ├── key: (19) - │ │ │ └── fd: (19)-->(15-18) + │ │ ├── fd: (19)-->(15-18), (15)==(16), (16)==(15), (26)-->(22-25) │ │ ├── scan d │ │ │ ├── columns: d1:22 d2:23 d3:24 d4:25 d.rowid:26!null │ │ │ ├── key: (26) │ │ │ └── fd: (26)-->(22-25) - │ │ └── filters - │ │ └── b3:17 = d3:24 [outer=(17,24), constraints=(/17: (/NULL - ]; /24: (/NULL - ]), fd=(17)==(24), (24)==(17)] - │ └── inner-join (cross) - │ ├── columns: b1:29!null b2:30!null b3:31 b4:32 b.rowid:33!null d1:36 d2:37 d3:38 d4:39 d.rowid:40!null + │ │ ├── select + │ │ │ ├── columns: b1:15!null b2:16!null b3:17 b4:18 b.rowid:19!null + │ │ │ ├── key: (19) + │ │ │ ├── fd: (19)-->(15-18), (15)==(16), (16)==(15) + │ │ │ ├── scan b@b_b1_b2_idx + │ │ │ │ ├── columns: b1:15!null b2:16 b3:17 b4:18 b.rowid:19!null + │ │ │ │ ├── constraint: /15/16/19: (/NULL - ] + │ │ │ │ ├── key: (19) + │ │ │ │ └── fd: (19)-->(15-18) + │ │ │ └── filters + │ │ │ └── b1:15 = b2:16 [outer=(15,16), constraints=(/15: (/NULL - ]; /16: (/NULL - ]), fd=(15)==(16), (16)==(15)] + │ │ └── filters (true) + │ └── inner-join (hash) + │ ├── columns: b1:29 b2:30 b3:31!null b4:32 b.rowid:33!null d1:36 d2:37 d3:38!null d4:39 d.rowid:40!null │ ├── key: (33,40) - │ ├── fd: (33)-->(29-32), (29)==(30), (30)==(29), (40)-->(36-39) + │ ├── fd: (33)-->(29-32), (40)-->(36-39), (31)==(38), (38)==(31) + │ ├── scan b + │ │ ├── columns: b1:29 b2:30 b3:31 b4:32 b.rowid:33!null + │ │ ├── key: (33) + │ │ └── fd: (33)-->(29-32) │ ├── scan d │ │ ├── columns: d1:36 d2:37 d3:38 d4:39 d.rowid:40!null │ │ ├── key: (40) │ │ └── fd: (40)-->(36-39) - │ ├── select - │ │ ├── columns: b1:29!null b2:30!null b3:31 b4:32 b.rowid:33!null - │ │ ├── key: (33) - │ │ ├── fd: (33)-->(29-32), (29)==(30), (30)==(29) - │ │ ├── scan b@b_b1_b2_idx - │ │ │ ├── columns: b1:29!null b2:30 b3:31 b4:32 b.rowid:33!null - │ │ │ ├── constraint: /29/30/33: (/NULL - ] - │ │ │ ├── key: (33) - │ │ │ └── fd: (33)-->(29-32) - │ │ └── filters - │ │ └── b1:29 = b2:30 [outer=(29,30), constraints=(/29: (/NULL - ]; /30: (/NULL - ]), fd=(29)==(30), (30)==(29)] - │ └── filters (true) + │ └── filters + │ └── b3:31 = d3:38 [outer=(31,38), constraints=(/31: (/NULL - ]; /38: (/NULL - ]), fd=(31)==(38), (38)==(31)] └── aggregations ├── const-agg [as=b1:1, outer=(1)] │ └── b1:1 @@ -461,103 +486,103 @@ project │ ├── columns: b1:1!null b2:2!null b3:3 b4:4 b.rowid:5!null d1:8!null d2:9 d3:10 d4:11 d.rowid:12!null │ ├── left columns: b1:29 b2:30 b3:31 b4:32 b.rowid:33 d1:36 d2:37 d3:38 d4:39 d.rowid:40 │ ├── right columns: b1:43 b2:44 b3:45 b4:46 b.rowid:47 d1:50 d2:51 d3:52 d4:53 d.rowid:54 - │ ├── inner-join (lookup d@d) + │ ├── project │ │ ├── columns: b1:29!null b2:30!null b3:31 b4:32 b.rowid:33!null d1:36!null d2:37 d3:38 d4:39 d.rowid:40!null - │ │ ├── key columns: [29] = [36] │ │ ├── key: (33,40) - │ │ ├── fd: (33)-->(29-32), (40)-->(36-39), (29)==(36), (36)==(29) - │ │ ├── distinct-on - │ │ │ ├── columns: b1:29!null b2:30!null b3:31 b4:32 b.rowid:33!null - │ │ │ ├── grouping columns: b.rowid:33!null - │ │ │ ├── key: (33) - │ │ │ ├── fd: (33)-->(29-32) - │ │ │ ├── union-all - │ │ │ │ ├── columns: b1:29!null b2:30!null b3:31 b4:32 b.rowid:33!null - │ │ │ │ ├── left columns: b1:57 b2:58 b3:59 b4:60 b.rowid:61 - │ │ │ │ ├── right columns: b1:64 b2:65 b3:66 b4:67 b.rowid:68 - │ │ │ │ ├── scan b@b_b1_b2_idx - │ │ │ │ │ ├── columns: b1:57!null b2:58!null b3:59 b4:60 b.rowid:61!null - │ │ │ │ │ ├── constraint: /57/58/61 - │ │ │ │ │ │ ├── [/0/0 - /0/0] - │ │ │ │ │ │ └── [/0/5 - /0/5] - │ │ │ │ │ ├── key: (61) - │ │ │ │ │ └── fd: ()-->(57), (61)-->(58-60) - │ │ │ │ └── select - │ │ │ │ ├── columns: b1:64!null b2:65!null b3:66 b4:67 b.rowid:68!null - │ │ │ │ ├── key: (68) - │ │ │ │ ├── fd: ()-->(65), (68)-->(64,66,67) - │ │ │ │ ├── scan b@b_b2_idx - │ │ │ │ │ ├── columns: b1:64 b2:65!null b3:66 b4:67 b.rowid:68!null - │ │ │ │ │ ├── constraint: /65/68: [/5 - /5] - │ │ │ │ │ ├── key: (68) - │ │ │ │ │ └── fd: ()-->(65), (68)-->(64,66,67) - │ │ │ │ └── filters - │ │ │ │ └── (b1:64 = 5) OR ((b1:64 IS DISTINCT FROM CAST(NULL AS INT8)) OR CAST(NULL AS BOOL)) [outer=(64), constraints=(/64: (/NULL - ]; tight)] - │ │ │ └── aggregations - │ │ │ ├── const-agg [as=b1:29, outer=(29)] - │ │ │ │ └── b1:29 - │ │ │ ├── const-agg [as=b2:30, outer=(30)] - │ │ │ │ └── b2:30 - │ │ │ ├── const-agg [as=b3:31, outer=(31)] - │ │ │ │ └── b3:31 - │ │ │ └── const-agg [as=b4:32, outer=(32)] - │ │ │ └── b4:32 - │ │ └── filters (true) - │ └── project + │ │ ├── fd: ()-->(29), (33)-->(30-32), (40)-->(36-39) + │ │ └── distinct-on + │ │ ├── columns: b1:29!null b2:30!null b3:31 b4:32 b.rowid:33!null d1:36!null d2:37 d3:38 d4:39 d.rowid:40!null + │ │ ├── grouping columns: b.rowid:33!null d.rowid:40!null + │ │ ├── key: (33,40) + │ │ ├── fd: (33,40)-->(29-32,36-39) + │ │ ├── union-all + │ │ │ ├── columns: b1:29!null b2:30!null b3:31 b4:32 b.rowid:33!null d1:36!null d2:37 d3:38 d4:39 d.rowid:40!null + │ │ │ ├── left columns: b1:57 b2:58 b3:59 b4:60 b.rowid:61 d1:64 d2:65 d3:66 d4:67 d.rowid:68 + │ │ │ ├── right columns: b1:71 b2:72 b3:73 b4:74 b.rowid:75 d1:78 d2:79 d3:80 d4:81 d.rowid:82 + │ │ │ ├── inner-join (lookup d@d) + │ │ │ │ ├── columns: b1:57!null b2:58!null b3:59 b4:60 b.rowid:61!null d1:64!null d2:65 d3:66 d4:67 d.rowid:68!null + │ │ │ │ ├── key columns: [58] = [64] + │ │ │ │ ├── key: (61,68) + │ │ │ │ ├── fd: ()-->(57), (61)-->(58-60), (68)-->(64-67), (58)==(64), (64)==(58) + │ │ │ │ ├── scan b@b_b1_b2_idx + │ │ │ │ │ ├── columns: b1:57!null b2:58!null b3:59 b4:60 b.rowid:61!null + │ │ │ │ │ ├── constraint: /57/58/61: (/0/NULL - /0] + │ │ │ │ │ ├── key: (61) + │ │ │ │ │ └── fd: ()-->(57), (61)-->(58-60) + │ │ │ │ └── filters + │ │ │ │ └── ((d1:64 IS DISTINCT FROM CAST(NULL AS INT8)) OR CAST(NULL AS BOOL)) OR (d1:64 = 5) [outer=(64), constraints=(/64: (/NULL - ]; tight)] + │ │ │ └── inner-join (lookup d@d) + │ │ │ ├── columns: b1:71!null b2:72!null b3:73 b4:74 b.rowid:75!null d1:78!null d2:79 d3:80 d4:81 d.rowid:82!null + │ │ │ ├── key columns: [71] = [78] + │ │ │ ├── key: (75,82) + │ │ │ ├── fd: ()-->(71,78), (75)-->(72-74), (82)-->(79-81), (71)==(78), (78)==(71) + │ │ │ ├── scan b@b_b1_b2_idx + │ │ │ │ ├── columns: b1:71!null b2:72!null b3:73 b4:74 b.rowid:75!null + │ │ │ │ ├── constraint: /71/72/75 + │ │ │ │ │ ├── [/0/0 - /0/0] + │ │ │ │ │ └── [/0/5 - /0/5] + │ │ │ │ ├── key: (75) + │ │ │ │ └── fd: ()-->(71), (75)-->(72-74) + │ │ │ └── filters (true) + │ │ └── aggregations + │ │ ├── const-agg [as=b1:29, outer=(29)] + │ │ │ └── b1:29 + │ │ ├── const-agg [as=b2:30, outer=(30)] + │ │ │ └── b2:30 + │ │ ├── const-agg [as=b3:31, outer=(31)] + │ │ │ └── b3:31 + │ │ ├── const-agg [as=b4:32, outer=(32)] + │ │ │ └── b4:32 + │ │ ├── const-agg [as=d1:36, outer=(36)] + │ │ │ └── d1:36 + │ │ ├── const-agg [as=d2:37, outer=(37)] + │ │ │ └── d2:37 + │ │ ├── const-agg [as=d3:38, outer=(38)] + │ │ │ └── d3:38 + │ │ └── const-agg [as=d4:39, outer=(39)] + │ │ └── d4:39 + │ └── inner-join (lookup d@d) │ ├── columns: b1:43!null b2:44!null b3:45 b4:46 b.rowid:47!null d1:50!null d2:51 d3:52 d4:53 d.rowid:54!null + │ ├── key columns: [43] = [50] │ ├── key: (47,54) - │ ├── fd: ()-->(43), (47)-->(44-46), (54)-->(50-53) - │ └── distinct-on - │ ├── columns: b1:43!null b2:44!null b3:45 b4:46 b.rowid:47!null d1:50!null d2:51 d3:52 d4:53 d.rowid:54!null - │ ├── grouping columns: b.rowid:47!null d.rowid:54!null - │ ├── key: (47,54) - │ ├── fd: (47,54)-->(43-46,50-53) - │ ├── union-all - │ │ ├── columns: b1:43!null b2:44!null b3:45 b4:46 b.rowid:47!null d1:50!null d2:51 d3:52 d4:53 d.rowid:54!null - │ │ ├── left columns: b1:71 b2:72 b3:73 b4:74 b.rowid:75 d1:78 d2:79 d3:80 d4:81 d.rowid:82 - │ │ ├── right columns: b1:85 b2:86 b3:87 b4:88 b.rowid:89 d1:92 d2:93 d3:94 d4:95 d.rowid:96 - │ │ ├── inner-join (lookup d@d) - │ │ │ ├── columns: b1:71!null b2:72!null b3:73 b4:74 b.rowid:75!null d1:78!null d2:79 d3:80 d4:81 d.rowid:82!null - │ │ │ ├── key columns: [72] = [78] - │ │ │ ├── key: (75,82) - │ │ │ ├── fd: ()-->(71), (75)-->(72-74), (82)-->(78-81), (72)==(78), (78)==(72) - │ │ │ ├── scan b@b_b1_b2_idx - │ │ │ │ ├── columns: b1:71!null b2:72!null b3:73 b4:74 b.rowid:75!null - │ │ │ │ ├── constraint: /71/72/75: (/0/NULL - /0] - │ │ │ │ ├── key: (75) - │ │ │ │ └── fd: ()-->(71), (75)-->(72-74) - │ │ │ └── filters - │ │ │ └── ((d1:78 IS DISTINCT FROM CAST(NULL AS INT8)) OR CAST(NULL AS BOOL)) OR (d1:78 = 5) [outer=(78), constraints=(/78: (/NULL - ]; tight)] - │ │ └── inner-join (lookup d@d) - │ │ ├── columns: b1:85!null b2:86!null b3:87 b4:88 b.rowid:89!null d1:92!null d2:93 d3:94 d4:95 d.rowid:96!null - │ │ ├── key columns: [85] = [92] - │ │ ├── key: (89,96) - │ │ ├── fd: ()-->(85,92), (89)-->(86-88), (96)-->(93-95), (85)==(92), (92)==(85) - │ │ ├── scan b@b_b1_b2_idx - │ │ │ ├── columns: b1:85!null b2:86!null b3:87 b4:88 b.rowid:89!null - │ │ │ ├── constraint: /85/86/89 - │ │ │ │ ├── [/0/0 - /0/0] - │ │ │ │ └── [/0/5 - /0/5] - │ │ │ ├── key: (89) - │ │ │ └── fd: ()-->(85), (89)-->(86-88) - │ │ └── filters (true) - │ └── aggregations - │ ├── const-agg [as=b1:43, outer=(43)] - │ │ └── b1:43 - │ ├── const-agg [as=b2:44, outer=(44)] - │ │ └── b2:44 - │ ├── const-agg [as=b3:45, outer=(45)] - │ │ └── b3:45 - │ ├── const-agg [as=b4:46, outer=(46)] - │ │ └── b4:46 - │ ├── const-agg [as=d1:50, outer=(50)] - │ │ └── d1:50 - │ ├── const-agg [as=d2:51, outer=(51)] - │ │ └── d2:51 - │ ├── const-agg [as=d3:52, outer=(52)] - │ │ └── d3:52 - │ └── const-agg [as=d4:53, outer=(53)] - │ └── d4:53 + │ ├── fd: (47)-->(43-46), (54)-->(50-53), (43)==(50), (50)==(43) + │ ├── distinct-on + │ │ ├── columns: b1:43!null b2:44!null b3:45 b4:46 b.rowid:47!null + │ │ ├── grouping columns: b.rowid:47!null + │ │ ├── key: (47) + │ │ ├── fd: (47)-->(43-46) + │ │ ├── union-all + │ │ │ ├── columns: b1:43!null b2:44!null b3:45 b4:46 b.rowid:47!null + │ │ │ ├── left columns: b1:115 b2:116 b3:117 b4:118 b.rowid:119 + │ │ │ ├── right columns: b1:122 b2:123 b3:124 b4:125 b.rowid:126 + │ │ │ ├── scan b@b_b1_b2_idx + │ │ │ │ ├── columns: b1:115!null b2:116!null b3:117 b4:118 b.rowid:119!null + │ │ │ │ ├── constraint: /115/116/119 + │ │ │ │ │ ├── [/0/0 - /0/0] + │ │ │ │ │ └── [/0/5 - /0/5] + │ │ │ │ ├── key: (119) + │ │ │ │ └── fd: ()-->(115), (119)-->(116-118) + │ │ │ └── select + │ │ │ ├── columns: b1:122!null b2:123!null b3:124 b4:125 b.rowid:126!null + │ │ │ ├── key: (126) + │ │ │ ├── fd: ()-->(123), (126)-->(122,124,125) + │ │ │ ├── scan b@b_b2_idx + │ │ │ │ ├── columns: b1:122 b2:123!null b3:124 b4:125 b.rowid:126!null + │ │ │ │ ├── constraint: /123/126: [/5 - /5] + │ │ │ │ ├── key: (126) + │ │ │ │ └── fd: ()-->(123), (126)-->(122,124,125) + │ │ │ └── filters + │ │ │ └── (b1:122 = 5) OR ((b1:122 IS DISTINCT FROM CAST(NULL AS INT8)) OR CAST(NULL AS BOOL)) [outer=(122), constraints=(/122: (/NULL - ]; tight)] + │ │ └── aggregations + │ │ ├── const-agg [as=b1:43, outer=(43)] + │ │ │ └── b1:43 + │ │ ├── const-agg [as=b2:44, outer=(44)] + │ │ │ └── b2:44 + │ │ ├── const-agg [as=b3:45, outer=(45)] + │ │ │ └── b3:45 + │ │ └── const-agg [as=b4:46, outer=(46)] + │ │ └── b4:46 + │ └── filters (true) └── aggregations ├── const-agg [as=b1:1, outer=(1)] │ └── b1:1 @@ -690,6 +715,222 @@ project └── const-agg [as=d4:10, outer=(10)] └── d4:10 +# Same test as above, but with the order of variables in equality conditions +# swapped. +opt expect=SplitDisjunctionOfJoinTerms +SELECT * FROM a, d WHERE (d2 = a1 AND d1 = a2) OR (d4 = a3 AND d3 = a4) +---- +project + ├── columns: a1:1!null a2:2!null a3:3!null a4:4!null d1:7 d2:8 d3:9 d4:10 + └── distinct-on + ├── columns: a1:1!null a2:2!null a3:3!null a4:4!null d1:7 d2:8 d3:9 d4:10 rowid:11!null + ├── grouping columns: a1:1!null a2:2!null a3:3!null a4:4!null rowid:11!null + ├── key: (1-4,11) + ├── fd: (1-4,11)-->(7-10) + ├── union-all + │ ├── columns: a1:1!null a2:2!null a3:3!null a4:4!null d1:7 d2:8 d3:9 d4:10 rowid:11!null + │ ├── left columns: a1:14 a2:15 a3:16 a4:17 d1:20 d2:21 d3:22 d4:23 rowid:24 + │ ├── right columns: a1:27 a2:28 a3:29 a4:30 d1:33 d2:34 d3:35 d4:36 rowid:37 + │ ├── inner-join (hash) + │ │ ├── columns: a1:14!null a2:15!null a3:16!null a4:17!null d1:20!null d2:21!null d3:22 d4:23 rowid:24!null + │ │ ├── key: (16,17,24) + │ │ ├── fd: (24)-->(20-23), (14)==(21), (21)==(14), (15)==(20), (20)==(15) + │ │ ├── scan a + │ │ │ ├── columns: a1:14!null a2:15!null a3:16!null a4:17!null + │ │ │ └── key: (14-17) + │ │ ├── scan d + │ │ │ ├── columns: d1:20 d2:21 d3:22 d4:23 rowid:24!null + │ │ │ ├── key: (24) + │ │ │ └── fd: (24)-->(20-23) + │ │ └── filters + │ │ ├── d2:21 = a1:14 [outer=(14,21), constraints=(/14: (/NULL - ]; /21: (/NULL - ]), fd=(14)==(21), (21)==(14)] + │ │ └── d1:20 = a2:15 [outer=(15,20), constraints=(/15: (/NULL - ]; /20: (/NULL - ]), fd=(15)==(20), (20)==(15)] + │ └── inner-join (hash) + │ ├── columns: a1:27!null a2:28!null a3:29!null a4:30!null d1:33 d2:34 d3:35!null d4:36!null rowid:37!null + │ ├── key: (27,28,37) + │ ├── fd: (37)-->(33-36), (29)==(36), (36)==(29), (30)==(35), (35)==(30) + │ ├── scan a + │ │ ├── columns: a1:27!null a2:28!null a3:29!null a4:30!null + │ │ └── key: (27-30) + │ ├── scan d + │ │ ├── columns: d1:33 d2:34 d3:35 d4:36 rowid:37!null + │ │ ├── key: (37) + │ │ └── fd: (37)-->(33-36) + │ └── filters + │ ├── d4:36 = a3:29 [outer=(29,36), constraints=(/29: (/NULL - ]; /36: (/NULL - ]), fd=(29)==(36), (36)==(29)] + │ └── d3:35 = a4:30 [outer=(30,35), constraints=(/30: (/NULL - ]; /35: (/NULL - ]), fd=(30)==(35), (35)==(30)] + └── aggregations + ├── const-agg [as=d1:7, outer=(7)] + │ └── d1:7 + ├── const-agg [as=d2:8, outer=(8)] + │ └── d2:8 + ├── const-agg [as=d3:9, outer=(9)] + │ └── d3:9 + └── const-agg [as=d4:10, outer=(10)] + └── d4:10 + +# We should be able to split the disjunction even though the predicates are +# equalities but not equijoin expressions. +opt expect=SplitDisjunctionOfJoinTerms +SELECT e.* +FROM + e + INNER JOIN f ON f.f3 = e.e2 +WHERE + e.e5 = 30 + OR (e.e3 = 10 AND f.f2 = 20) +---- +project + ├── columns: e1:1!null e2:2!null e3:3!null e4:4!null e5:5 + ├── fd: (1)-->(2-5) + └── project + ├── columns: e1:1!null e2:2!null e3:3!null e4:4!null e5:5 f2:9 f3:10!null + ├── fd: (1)-->(2-5), (2)==(10), (10)==(2) + └── distinct-on + ├── columns: e1:1!null e2:2!null e3:3!null e4:4!null e5:5 f1:8!null f2:9 f3:10!null + ├── grouping columns: e1:1!null f1:8!null + ├── key: (1,8) + ├── fd: (2)==(10), (10)==(2), (1,8)-->(2-5,9,10) + ├── union-all + │ ├── columns: e1:1!null e2:2!null e3:3!null e4:4!null e5:5 f1:8!null f2:9 f3:10!null + │ ├── left columns: e1:14 e2:15 e3:16 e4:17 e5:18 f1:21 f2:22 f3:23 + │ ├── right columns: e1:27 e2:28 e3:29 e4:30 e5:31 f1:34 f2:35 f3:36 + │ ├── fd: (2)==(10), (10)==(2) + │ ├── inner-join (lookup f) + │ │ ├── columns: e1:14!null e2:15!null e3:16!null e4:17!null e5:18!null f1:21!null f2:22 f3:23!null + │ │ ├── key columns: [21] = [21] + │ │ ├── lookup columns are key + │ │ ├── key: (14,21) + │ │ ├── fd: ()-->(18), (14)-->(15-17), (21)-->(22,23), (15)==(23), (23)==(15) + │ │ ├── inner-join (lookup f@f_f3_idx) + │ │ │ ├── columns: e1:14!null e2:15!null e3:16!null e4:17!null e5:18!null f1:21!null f3:23!null + │ │ │ ├── key columns: [15] = [23] + │ │ │ ├── key: (14,21) + │ │ │ ├── fd: ()-->(18), (14)-->(15-17), (21)-->(23), (15)==(23), (23)==(15) + │ │ │ ├── index-join e + │ │ │ │ ├── columns: e1:14!null e2:15!null e3:16!null e4:17!null e5:18!null + │ │ │ │ ├── key: (14) + │ │ │ │ ├── fd: ()-->(18), (14)-->(15-17) + │ │ │ │ └── scan e@e_e5_idx + │ │ │ │ ├── columns: e1:14!null e5:18!null + │ │ │ │ ├── constraint: /18/14: [/30 - /30] + │ │ │ │ ├── key: (14) + │ │ │ │ └── fd: ()-->(18) + │ │ │ └── filters (true) + │ │ └── filters (true) + │ └── inner-join (hash) + │ ├── columns: e1:27!null e2:28!null e3:29!null e4:30!null e5:31 f1:34!null f2:35!null f3:36!null + │ ├── key: (27,34) + │ ├── fd: ()-->(29,35), (27)-->(28,30,31), (34)-->(36), (28)==(36), (36)==(28) + │ ├── index-join e + │ │ ├── columns: e1:27!null e2:28!null e3:29!null e4:30!null e5:31 + │ │ ├── key: (27) + │ │ ├── fd: ()-->(29), (27)-->(28,30,31) + │ │ └── scan e@e_e3_e5_e4_idx + │ │ ├── columns: e1:27!null e3:29!null e4:30!null e5:31 + │ │ ├── constraint: /29/31/30/27: [/10 - /10] + │ │ ├── key: (27) + │ │ └── fd: ()-->(29), (27)-->(30,31) + │ ├── scan f@f_f2_idx + │ │ ├── columns: f1:34!null f2:35!null f3:36 + │ │ ├── constraint: /35/34: [/20 - /20] + │ │ ├── key: (34) + │ │ └── fd: ()-->(35), (34)-->(36) + │ └── filters + │ └── f3:36 = e2:28 [outer=(28,36), constraints=(/28: (/NULL - ]; /36: (/NULL - ]), fd=(28)==(36), (36)==(28)] + └── aggregations + ├── const-agg [as=e2:2, outer=(2)] + │ └── e2:2 + ├── const-agg [as=e3:3, outer=(3)] + │ └── e3:3 + ├── const-agg [as=e4:4, outer=(4)] + │ └── e4:4 + ├── const-agg [as=e5:5, outer=(5)] + │ └── e5:5 + ├── const-agg [as=f2:9, outer=(9)] + │ └── f2:9 + └── const-agg [as=f3:10, outer=(10)] + └── f3:10 + +# We should be able to split the disjunction even though the predicates are +# not equalities. +opt expect=SplitDisjunctionOfJoinTerms +SELECT e.* +FROM + e + INNER JOIN f ON f.f3 = e.e2 +WHERE + (e.e5 > 30 AND e.e5 < 40) + OR (e.e4 IN ('a', 'b') AND f.f2 < 20 AND f.f2 > 10) +---- +project + ├── columns: e1:1!null e2:2!null e3:3!null e4:4!null e5:5 + ├── fd: (1)-->(2-5) + └── project + ├── columns: e1:1!null e2:2!null e3:3!null e4:4!null e5:5 f2:9 f3:10!null + ├── fd: (1)-->(2-5), (2)==(10), (10)==(2) + └── distinct-on + ├── columns: e1:1!null e2:2!null e3:3!null e4:4!null e5:5 f1:8!null f2:9 f3:10!null + ├── grouping columns: e1:1!null f1:8!null + ├── key: (1,8) + ├── fd: (2)==(10), (10)==(2), (1,8)-->(2-5,9,10) + ├── union-all + │ ├── columns: e1:1!null e2:2!null e3:3!null e4:4!null e5:5 f1:8!null f2:9 f3:10!null + │ ├── left columns: e1:14 e2:15 e3:16 e4:17 e5:18 f1:21 f2:22 f3:23 + │ ├── right columns: e1:27 e2:28 e3:29 e4:30 e5:31 f1:34 f2:35 f3:36 + │ ├── fd: (2)==(10), (10)==(2) + │ ├── inner-join (hash) + │ │ ├── columns: e1:14!null e2:15!null e3:16!null e4:17!null e5:18!null f1:21!null f2:22 f3:23!null + │ │ ├── key: (14,21) + │ │ ├── fd: (14)-->(15-18), (21)-->(22,23), (15)==(23), (23)==(15) + │ │ ├── scan f@f_f2_idx + │ │ │ ├── columns: f1:21!null f2:22 f3:23 + │ │ │ ├── key: (21) + │ │ │ └── fd: (21)-->(22,23) + │ │ ├── index-join e + │ │ │ ├── columns: e1:14!null e2:15!null e3:16!null e4:17!null e5:18!null + │ │ │ ├── key: (14) + │ │ │ ├── fd: (14)-->(15-18) + │ │ │ └── scan e@e_e5_idx + │ │ │ ├── columns: e1:14!null e5:18!null + │ │ │ ├── constraint: /18/14: [/31 - /39] + │ │ │ ├── key: (14) + │ │ │ └── fd: (14)-->(18) + │ │ └── filters + │ │ └── f3:23 = e2:15 [outer=(15,23), constraints=(/15: (/NULL - ]; /23: (/NULL - ]), fd=(15)==(23), (23)==(15)] + │ └── inner-join (hash) + │ ├── columns: e1:27!null e2:28!null e3:29!null e4:30!null e5:31 f1:34!null f2:35!null f3:36!null + │ ├── key: (27,34) + │ ├── fd: (27)-->(28-31), (34)-->(35,36), (28)==(36), (36)==(28) + │ ├── scan f@f_f2_idx + │ │ ├── columns: f1:34!null f2:35!null f3:36 + │ │ ├── constraint: /35/34: [/11 - /19] + │ │ ├── key: (34) + │ │ └── fd: (34)-->(35,36) + │ ├── index-join e + │ │ ├── columns: e1:27!null e2:28!null e3:29!null e4:30!null e5:31 + │ │ ├── key: (27) + │ │ ├── fd: (27)-->(28-31) + │ │ └── scan e@e_e3_idx,partial + │ │ ├── columns: e1:27!null e3:29!null + │ │ ├── key: (27) + │ │ └── fd: (27)-->(29) + │ └── filters + │ └── f3:36 = e2:28 [outer=(28,36), constraints=(/28: (/NULL - ]; /36: (/NULL - ]), fd=(28)==(36), (36)==(28)] + └── aggregations + ├── const-agg [as=e2:2, outer=(2)] + │ └── e2:2 + ├── const-agg [as=e3:3, outer=(3)] + │ └── e3:3 + ├── const-agg [as=e4:4, outer=(4)] + │ └── e4:4 + ├── const-agg [as=e5:5, outer=(5)] + │ └── e5:5 + ├── const-agg [as=f2:9, outer=(9)] + │ └── f2:9 + └── const-agg [as=f3:10, outer=(10)] + └── f3:10 + ######################### # Uncorrelated semijoin # ######################### @@ -730,7 +971,7 @@ select │ └── true [as=column15:15] └── false -opt expect-not=SplitDisjunctionOfJoinTerms +opt expect=SplitDisjunctionOfJoinTerms SELECT * FROM a WHERE EXISTS (SELECT 1 FROM c, d WHERE d1 = 4 OR c2 = 50 HAVING sum(d4) > 40) ---- select @@ -760,14 +1001,55 @@ select │ │ │ ├── cardinality: [1 - 1] │ │ │ ├── key: () │ │ │ ├── fd: ()-->(21) - │ │ │ ├── inner-join (cross) - │ │ │ │ ├── columns: c2:8 d1:14 d4:17 - │ │ │ │ ├── scan c - │ │ │ │ │ └── columns: c2:8 - │ │ │ │ ├── scan d - │ │ │ │ │ └── columns: d1:14 d4:17 - │ │ │ │ └── filters - │ │ │ │ └── (d1:14 = 4) OR (c2:8 = 50) [outer=(8,14)] + │ │ │ ├── distinct-on + │ │ │ │ ├── columns: c2:8 c.rowid:11!null d1:14 d4:17 d.rowid:18!null + │ │ │ │ ├── grouping columns: c.rowid:11!null d.rowid:18!null + │ │ │ │ ├── key: (11,18) + │ │ │ │ ├── fd: (11,18)-->(8,14,17) + │ │ │ │ ├── union-all + │ │ │ │ │ ├── columns: c2:8 c.rowid:11!null d1:14 d4:17 d.rowid:18!null + │ │ │ │ │ ├── left columns: c2:25 c.rowid:28 d1:31 d4:34 d.rowid:35 + │ │ │ │ │ ├── right columns: c2:39 c.rowid:42 d1:45 d4:48 d.rowid:49 + │ │ │ │ │ ├── inner-join (cross) + │ │ │ │ │ │ ├── columns: c2:25 c.rowid:28!null d1:31!null d4:34 d.rowid:35!null + │ │ │ │ │ │ ├── key: (28,35) + │ │ │ │ │ │ ├── fd: ()-->(31), (28)-->(25), (35)-->(34) + │ │ │ │ │ │ ├── scan c + │ │ │ │ │ │ │ ├── columns: c2:25 c.rowid:28!null + │ │ │ │ │ │ │ ├── key: (28) + │ │ │ │ │ │ │ └── fd: (28)-->(25) + │ │ │ │ │ │ ├── scan d@d + │ │ │ │ │ │ │ ├── columns: d1:31!null d4:34 d.rowid:35!null + │ │ │ │ │ │ │ ├── constraint: /31/35: [/4 - /4] + │ │ │ │ │ │ │ ├── key: (35) + │ │ │ │ │ │ │ └── fd: ()-->(31), (35)-->(34) + │ │ │ │ │ │ └── filters (true) + │ │ │ │ │ └── inner-join (cross) + │ │ │ │ │ ├── columns: c2:39!null c.rowid:42!null d1:45 d4:48 d.rowid:49!null + │ │ │ │ │ ├── key: (42,49) + │ │ │ │ │ ├── fd: ()-->(39), (49)-->(45,48) + │ │ │ │ │ ├── scan d + │ │ │ │ │ │ ├── columns: d1:45 d4:48 d.rowid:49!null + │ │ │ │ │ │ ├── key: (49) + │ │ │ │ │ │ └── fd: (49)-->(45,48) + │ │ │ │ │ ├── select + │ │ │ │ │ │ ├── columns: c2:39!null c.rowid:42!null + │ │ │ │ │ │ ├── key: (42) + │ │ │ │ │ │ ├── fd: ()-->(39) + │ │ │ │ │ │ ├── scan c + │ │ │ │ │ │ │ ├── columns: c2:39 c.rowid:42!null + │ │ │ │ │ │ │ ├── key: (42) + │ │ │ │ │ │ │ └── fd: (42)-->(39) + │ │ │ │ │ │ └── filters + │ │ │ │ │ │ └── c2:39 = 50 [outer=(39), constraints=(/39: [/50 - /50]; tight), fd=()-->(39)] + │ │ │ │ │ └── filters (true) + │ │ │ │ └── aggregations + │ │ │ │ ├── const-agg [as=c2:8, outer=(8)] + │ │ │ │ │ └── c2:8 + │ │ │ │ ├── const-agg [as=d1:14, outer=(14)] + │ │ │ │ │ └── d1:14 + │ │ │ │ └── const-agg [as=d4:17, outer=(17)] + │ │ │ │ └── d4:17 │ │ │ └── aggregations │ │ │ └── sum [as=sum:21, outer=(17)] │ │ │ └── d4:17 @@ -1070,39 +1352,39 @@ project │ │ ├── columns: c1:7 c.rowid:11!null d1:14 d.rowid:18!null │ │ ├── left columns: c1:34 c.rowid:38 d1:41 d.rowid:45 │ │ ├── right columns: c1:48 c.rowid:52 d1:55 d.rowid:59 - │ │ ├── inner-join (hash) - │ │ │ ├── columns: c1:34!null c.rowid:38!null d1:41!null d.rowid:45!null + │ │ ├── inner-join (cross) + │ │ │ ├── columns: c1:34 c.rowid:38!null d1:41 d.rowid:45!null │ │ │ ├── key: (38,45) - │ │ │ ├── fd: (38)-->(34), (45)-->(41), (34)==(41), (41)==(34) - │ │ │ ├── scan c - │ │ │ │ ├── columns: c1:34 c.rowid:38!null - │ │ │ │ ├── key: (38) - │ │ │ │ └── fd: (38)-->(34) + │ │ │ ├── fd: ()-->(34), (45)-->(41) │ │ │ ├── scan d │ │ │ │ ├── columns: d1:41 d.rowid:45!null │ │ │ │ ├── key: (45) │ │ │ │ └── fd: (45)-->(41) - │ │ │ └── filters - │ │ │ └── c1:34 = d1:41 [outer=(34,41), constraints=(/34: (/NULL - ]; /41: (/NULL - ]), fd=(34)==(41), (41)==(34)] - │ │ └── inner-join (cross) - │ │ ├── columns: c1:48 c.rowid:52!null d1:55 d.rowid:59!null + │ │ │ ├── select + │ │ │ │ ├── columns: c1:34 c.rowid:38!null + │ │ │ │ ├── key: (38) + │ │ │ │ ├── fd: ()-->(34) + │ │ │ │ ├── scan c + │ │ │ │ │ ├── columns: c1:34 c.rowid:38!null + │ │ │ │ │ ├── key: (38) + │ │ │ │ │ └── fd: (38)-->(34) + │ │ │ │ └── filters + │ │ │ │ └── c1:34 IS NULL [outer=(34), constraints=(/34: [/NULL - /NULL]; tight), fd=()-->(34)] + │ │ │ └── filters (true) + │ │ └── inner-join (hash) + │ │ ├── columns: c1:48!null c.rowid:52!null d1:55!null d.rowid:59!null │ │ ├── key: (52,59) - │ │ ├── fd: ()-->(48), (59)-->(55) + │ │ ├── fd: (52)-->(48), (59)-->(55), (48)==(55), (55)==(48) + │ │ ├── scan c + │ │ │ ├── columns: c1:48 c.rowid:52!null + │ │ │ ├── key: (52) + │ │ │ └── fd: (52)-->(48) │ │ ├── scan d │ │ │ ├── columns: d1:55 d.rowid:59!null │ │ │ ├── key: (59) │ │ │ └── fd: (59)-->(55) - │ │ ├── select - │ │ │ ├── columns: c1:48 c.rowid:52!null - │ │ │ ├── key: (52) - │ │ │ ├── fd: ()-->(48) - │ │ │ ├── scan c - │ │ │ │ ├── columns: c1:48 c.rowid:52!null - │ │ │ │ ├── key: (52) - │ │ │ │ └── fd: (52)-->(48) - │ │ │ └── filters - │ │ │ └── c1:48 IS NULL [outer=(48), constraints=(/48: [/NULL - /NULL]; tight), fd=()-->(48)] - │ │ └── filters (true) + │ │ └── filters + │ │ └── c1:48 = d1:55 [outer=(48,55), constraints=(/48: (/NULL - ]; /55: (/NULL - ]), fd=(48)==(55), (55)==(48)] │ └── aggregations │ ├── const-agg [as=c1:7, outer=(7)] │ │ └── c1:7 @@ -1138,39 +1420,39 @@ anti-join (cross) │ │ ├── columns: c1:8 c.rowid:12!null d1:15 d.rowid:19!null │ │ ├── left columns: c1:22 c.rowid:26 d1:29 d.rowid:33 │ │ ├── right columns: c1:36 c.rowid:40 d1:43 d.rowid:47 - │ │ ├── inner-join (hash) - │ │ │ ├── columns: c1:22!null c.rowid:26!null d1:29!null d.rowid:33!null + │ │ ├── inner-join (cross) + │ │ │ ├── columns: c1:22 c.rowid:26!null d1:29 d.rowid:33!null │ │ │ ├── key: (26,33) - │ │ │ ├── fd: (26)-->(22), (33)-->(29), (22)==(29), (29)==(22) - │ │ │ ├── scan c - │ │ │ │ ├── columns: c1:22 c.rowid:26!null - │ │ │ │ ├── key: (26) - │ │ │ │ └── fd: (26)-->(22) + │ │ │ ├── fd: ()-->(22), (33)-->(29) │ │ │ ├── scan d │ │ │ │ ├── columns: d1:29 d.rowid:33!null │ │ │ │ ├── key: (33) │ │ │ │ └── fd: (33)-->(29) - │ │ │ └── filters - │ │ │ └── c1:22 = d1:29 [outer=(22,29), constraints=(/22: (/NULL - ]; /29: (/NULL - ]), fd=(22)==(29), (29)==(22)] - │ │ └── inner-join (cross) - │ │ ├── columns: c1:36 c.rowid:40!null d1:43 d.rowid:47!null + │ │ │ ├── select + │ │ │ │ ├── columns: c1:22 c.rowid:26!null + │ │ │ │ ├── key: (26) + │ │ │ │ ├── fd: ()-->(22) + │ │ │ │ ├── scan c + │ │ │ │ │ ├── columns: c1:22 c.rowid:26!null + │ │ │ │ │ ├── key: (26) + │ │ │ │ │ └── fd: (26)-->(22) + │ │ │ │ └── filters + │ │ │ │ └── c1:22 IS NULL [outer=(22), constraints=(/22: [/NULL - /NULL]; tight), fd=()-->(22)] + │ │ │ └── filters (true) + │ │ └── inner-join (hash) + │ │ ├── columns: c1:36!null c.rowid:40!null d1:43!null d.rowid:47!null │ │ ├── key: (40,47) - │ │ ├── fd: ()-->(36), (47)-->(43) + │ │ ├── fd: (40)-->(36), (47)-->(43), (36)==(43), (43)==(36) + │ │ ├── scan c + │ │ │ ├── columns: c1:36 c.rowid:40!null + │ │ │ ├── key: (40) + │ │ │ └── fd: (40)-->(36) │ │ ├── scan d │ │ │ ├── columns: d1:43 d.rowid:47!null │ │ │ ├── key: (47) │ │ │ └── fd: (47)-->(43) - │ │ ├── select - │ │ │ ├── columns: c1:36 c.rowid:40!null - │ │ │ ├── key: (40) - │ │ │ ├── fd: ()-->(36) - │ │ │ ├── scan c - │ │ │ │ ├── columns: c1:36 c.rowid:40!null - │ │ │ │ ├── key: (40) - │ │ │ │ └── fd: (40)-->(36) - │ │ │ └── filters - │ │ │ └── c1:36 IS NULL [outer=(36), constraints=(/36: [/NULL - /NULL]; tight), fd=()-->(36)] - │ │ └── filters (true) + │ │ └── filters + │ │ └── c1:36 = d1:43 [outer=(36,43), constraints=(/36: (/NULL - ]; /43: (/NULL - ]), fd=(36)==(43), (43)==(36)] │ └── aggregations │ ├── const-agg [as=c1:8, outer=(8)] │ │ └── c1:8 @@ -1200,39 +1482,39 @@ anti-join (cross) │ │ │ ├── columns: c1:8 c2:9 c.rowid:12!null d1:15 d.rowid:19!null │ │ │ ├── left columns: c1:23 c2:24 c.rowid:27 d1:30 d.rowid:34 │ │ │ ├── right columns: c1:37 c2:38 c.rowid:41 d1:44 d.rowid:48 - │ │ │ ├── inner-join (hash) - │ │ │ │ ├── columns: c1:23!null c2:24 c.rowid:27!null d1:30!null d.rowid:34!null + │ │ │ ├── inner-join (cross) + │ │ │ │ ├── columns: c1:23 c2:24 c.rowid:27!null d1:30 d.rowid:34!null │ │ │ │ ├── key: (27,34) - │ │ │ │ ├── fd: (27)-->(23,24), (34)-->(30), (23)==(30), (30)==(23) - │ │ │ │ ├── scan c - │ │ │ │ │ ├── columns: c1:23 c2:24 c.rowid:27!null - │ │ │ │ │ ├── key: (27) - │ │ │ │ │ └── fd: (27)-->(23,24) + │ │ │ │ ├── fd: ()-->(23), (27)-->(24), (34)-->(30) │ │ │ │ ├── scan d │ │ │ │ │ ├── columns: d1:30 d.rowid:34!null │ │ │ │ │ ├── key: (34) │ │ │ │ │ └── fd: (34)-->(30) - │ │ │ │ └── filters - │ │ │ │ └── c1:23 = d1:30 [outer=(23,30), constraints=(/23: (/NULL - ]; /30: (/NULL - ]), fd=(23)==(30), (30)==(23)] - │ │ │ └── inner-join (cross) - │ │ │ ├── columns: c1:37 c2:38 c.rowid:41!null d1:44 d.rowid:48!null + │ │ │ │ ├── select + │ │ │ │ │ ├── columns: c1:23 c2:24 c.rowid:27!null + │ │ │ │ │ ├── key: (27) + │ │ │ │ │ ├── fd: ()-->(23), (27)-->(24) + │ │ │ │ │ ├── scan c + │ │ │ │ │ │ ├── columns: c1:23 c2:24 c.rowid:27!null + │ │ │ │ │ │ ├── key: (27) + │ │ │ │ │ │ └── fd: (27)-->(23,24) + │ │ │ │ │ └── filters + │ │ │ │ │ └── c1:23 IS NULL [outer=(23), constraints=(/23: [/NULL - /NULL]; tight), fd=()-->(23)] + │ │ │ │ └── filters (true) + │ │ │ └── inner-join (hash) + │ │ │ ├── columns: c1:37!null c2:38 c.rowid:41!null d1:44!null d.rowid:48!null │ │ │ ├── key: (41,48) - │ │ │ ├── fd: ()-->(37), (41)-->(38), (48)-->(44) + │ │ │ ├── fd: (41)-->(37,38), (48)-->(44), (37)==(44), (44)==(37) + │ │ │ ├── scan c + │ │ │ │ ├── columns: c1:37 c2:38 c.rowid:41!null + │ │ │ │ ├── key: (41) + │ │ │ │ └── fd: (41)-->(37,38) │ │ │ ├── scan d │ │ │ │ ├── columns: d1:44 d.rowid:48!null │ │ │ │ ├── key: (48) │ │ │ │ └── fd: (48)-->(44) - │ │ │ ├── select - │ │ │ │ ├── columns: c1:37 c2:38 c.rowid:41!null - │ │ │ │ ├── key: (41) - │ │ │ │ ├── fd: ()-->(37), (41)-->(38) - │ │ │ │ ├── scan c - │ │ │ │ │ ├── columns: c1:37 c2:38 c.rowid:41!null - │ │ │ │ │ ├── key: (41) - │ │ │ │ │ └── fd: (41)-->(37,38) - │ │ │ │ └── filters - │ │ │ │ └── c1:37 IS NULL [outer=(37), constraints=(/37: [/NULL - /NULL]; tight), fd=()-->(37)] - │ │ │ └── filters (true) + │ │ │ └── filters + │ │ │ └── c1:37 = d1:44 [outer=(37,44), constraints=(/37: (/NULL - ]; /44: (/NULL - ]), fd=(37)==(44), (44)==(37)] │ │ └── aggregations │ │ ├── const-agg [as=c1:8, outer=(8)] │ │ │ └── c1:8 @@ -1308,7 +1590,7 @@ select │ └── true [as=column15:15] └── false -opt expect-not=SplitDisjunctionOfJoinTerms +opt expect=SplitDisjunctionOfJoinTerms SELECT * FROM a WHERE NOT EXISTS (SELECT 1 FROM c, d WHERE d1 = 4 OR c2 = 50 or d2+c3 > 5) ---- select @@ -1650,39 +1932,39 @@ anti-join (cross) │ │ │ ├── columns: c1:7 c.rowid:11!null d1:14 d.rowid:18!null │ │ │ ├── left columns: c1:22 c.rowid:26 d1:29 d.rowid:33 │ │ │ ├── right columns: c1:36 c.rowid:40 d1:43 d.rowid:47 - │ │ │ ├── inner-join (hash) - │ │ │ │ ├── columns: c1:22!null c.rowid:26!null d1:29!null d.rowid:33!null + │ │ │ ├── inner-join (cross) + │ │ │ │ ├── columns: c1:22 c.rowid:26!null d1:29 d.rowid:33!null │ │ │ │ ├── key: (26,33) - │ │ │ │ ├── fd: (26)-->(22), (33)-->(29), (22)==(29), (29)==(22) - │ │ │ │ ├── scan c - │ │ │ │ │ ├── columns: c1:22 c.rowid:26!null - │ │ │ │ │ ├── key: (26) - │ │ │ │ │ └── fd: (26)-->(22) + │ │ │ │ ├── fd: ()-->(22), (33)-->(29) │ │ │ │ ├── scan d │ │ │ │ │ ├── columns: d1:29 d.rowid:33!null │ │ │ │ │ ├── key: (33) │ │ │ │ │ └── fd: (33)-->(29) - │ │ │ │ └── filters - │ │ │ │ └── c1:22 = d1:29 [outer=(22,29), constraints=(/22: (/NULL - ]; /29: (/NULL - ]), fd=(22)==(29), (29)==(22)] - │ │ │ └── inner-join (cross) - │ │ │ ├── columns: c1:36 c.rowid:40!null d1:43 d.rowid:47!null + │ │ │ │ ├── select + │ │ │ │ │ ├── columns: c1:22 c.rowid:26!null + │ │ │ │ │ ├── key: (26) + │ │ │ │ │ ├── fd: ()-->(22) + │ │ │ │ │ ├── scan c + │ │ │ │ │ │ ├── columns: c1:22 c.rowid:26!null + │ │ │ │ │ │ ├── key: (26) + │ │ │ │ │ │ └── fd: (26)-->(22) + │ │ │ │ │ └── filters + │ │ │ │ │ └── c1:22 IS NULL [outer=(22), constraints=(/22: [/NULL - /NULL]; tight), fd=()-->(22)] + │ │ │ │ └── filters (true) + │ │ │ └── inner-join (hash) + │ │ │ ├── columns: c1:36!null c.rowid:40!null d1:43!null d.rowid:47!null │ │ │ ├── key: (40,47) - │ │ │ ├── fd: ()-->(36), (47)-->(43) + │ │ │ ├── fd: (40)-->(36), (47)-->(43), (36)==(43), (43)==(36) + │ │ │ ├── scan c + │ │ │ │ ├── columns: c1:36 c.rowid:40!null + │ │ │ │ ├── key: (40) + │ │ │ │ └── fd: (40)-->(36) │ │ │ ├── scan d │ │ │ │ ├── columns: d1:43 d.rowid:47!null │ │ │ │ ├── key: (47) │ │ │ │ └── fd: (47)-->(43) - │ │ │ ├── select - │ │ │ │ ├── columns: c1:36 c.rowid:40!null - │ │ │ │ ├── key: (40) - │ │ │ │ ├── fd: ()-->(36) - │ │ │ │ ├── scan c - │ │ │ │ │ ├── columns: c1:36 c.rowid:40!null - │ │ │ │ │ ├── key: (40) - │ │ │ │ │ └── fd: (40)-->(36) - │ │ │ │ └── filters - │ │ │ │ └── c1:36 IS NULL [outer=(36), constraints=(/36: [/NULL - /NULL]; tight), fd=()-->(36)] - │ │ │ └── filters (true) + │ │ │ └── filters + │ │ │ └── c1:36 = d1:43 [outer=(36,43), constraints=(/36: (/NULL - ]; /43: (/NULL - ]), fd=(36)==(43), (43)==(36)] │ │ └── aggregations │ │ ├── const-agg [as=c1:7, outer=(7)] │ │ │ └── c1:7 @@ -2194,23 +2476,35 @@ project │ │ │ │ ├── columns: b1:23 b2:24 b3:25 b.rowid:27!null │ │ │ │ ├── key: (27) │ │ │ │ ├── fd: (27)-->(23-25) - │ │ │ │ └── inner-join (hash) - │ │ │ │ ├── columns: b1:23 b2:24!null b3:25 b.rowid:27!null c2:31!null - │ │ │ │ ├── multiplicity: left-rows(zero-or-one), right-rows(zero-or-more) + │ │ │ │ └── project + │ │ │ │ ├── columns: b1:23 b2:24 b3:25 b.rowid:27!null │ │ │ │ ├── key: (27) - │ │ │ │ ├── fd: (27)-->(23-25), (24)==(31), (31)==(24) - │ │ │ │ ├── scan b - │ │ │ │ │ ├── columns: b1:23 b2:24 b3:25 b.rowid:27!null - │ │ │ │ │ ├── key: (27) - │ │ │ │ │ └── fd: (27)-->(23-25) - │ │ │ │ ├── distinct-on - │ │ │ │ │ ├── columns: c2:31 - │ │ │ │ │ ├── grouping columns: c2:31 - │ │ │ │ │ ├── key: (31) - │ │ │ │ │ └── scan c - │ │ │ │ │ └── columns: c2:31 - │ │ │ │ └── filters - │ │ │ │ └── c2:31 = b2:24 [outer=(24,31), constraints=(/24: (/NULL - ]; /31: (/NULL - ]), fd=(24)==(31), (31)==(24)] + │ │ │ │ ├── fd: (27)-->(23-25) + │ │ │ │ └── inner-join (cross) + │ │ │ │ ├── columns: b1:23 b2:24 b3:25 b.rowid:27!null c2:31 + │ │ │ │ ├── multiplicity: left-rows(zero-or-one), right-rows(zero-or-more) + │ │ │ │ ├── key: (27) + │ │ │ │ ├── fd: ()-->(31), (27)-->(23-25) + │ │ │ │ ├── scan b + │ │ │ │ │ ├── columns: b1:23 b2:24 b3:25 b.rowid:27!null + │ │ │ │ │ ├── key: (27) + │ │ │ │ │ └── fd: (27)-->(23-25) + │ │ │ │ ├── limit + │ │ │ │ │ ├── columns: c2:31 + │ │ │ │ │ ├── cardinality: [0 - 1] + │ │ │ │ │ ├── key: () + │ │ │ │ │ ├── fd: ()-->(31) + │ │ │ │ │ ├── select + │ │ │ │ │ │ ├── columns: c2:31 + │ │ │ │ │ │ ├── fd: ()-->(31) + │ │ │ │ │ │ ├── limit hint: 1.00 + │ │ │ │ │ │ ├── scan c + │ │ │ │ │ │ │ ├── columns: c2:31 + │ │ │ │ │ │ │ └── limit hint: 100.00 + │ │ │ │ │ │ └── filters + │ │ │ │ │ │ └── c2:31 IS NULL [outer=(31), constraints=(/31: [/NULL - /NULL]; tight), fd=()-->(31)] + │ │ │ │ │ └── 1 + │ │ │ │ └── filters (true) │ │ │ └── project │ │ │ ├── columns: b1:37 b2:38 b3:39 b.rowid:41!null │ │ │ ├── key: (41) @@ -2249,35 +2543,23 @@ project │ │ │ │ ├── columns: b1:205 b2:206 b3:207 b.rowid:209!null │ │ │ │ ├── key: (209) │ │ │ │ ├── fd: (209)-->(205-207) - │ │ │ │ └── project - │ │ │ │ ├── columns: b1:205 b2:206 b3:207 b.rowid:209!null + │ │ │ │ └── inner-join (hash) + │ │ │ │ ├── columns: b1:205 b2:206!null b3:207 b.rowid:209!null c2:213!null + │ │ │ │ ├── multiplicity: left-rows(zero-or-one), right-rows(zero-or-more) │ │ │ │ ├── key: (209) - │ │ │ │ ├── fd: (209)-->(205-207) - │ │ │ │ └── inner-join (cross) - │ │ │ │ ├── columns: b1:205 b2:206 b3:207 b.rowid:209!null c2:213 - │ │ │ │ ├── multiplicity: left-rows(zero-or-one), right-rows(zero-or-more) - │ │ │ │ ├── key: (209) - │ │ │ │ ├── fd: ()-->(213), (209)-->(205-207) - │ │ │ │ ├── scan b - │ │ │ │ │ ├── columns: b1:205 b2:206 b3:207 b.rowid:209!null - │ │ │ │ │ ├── key: (209) - │ │ │ │ │ └── fd: (209)-->(205-207) - │ │ │ │ ├── limit - │ │ │ │ │ ├── columns: c2:213 - │ │ │ │ │ ├── cardinality: [0 - 1] - │ │ │ │ │ ├── key: () - │ │ │ │ │ ├── fd: ()-->(213) - │ │ │ │ │ ├── select - │ │ │ │ │ │ ├── columns: c2:213 - │ │ │ │ │ │ ├── fd: ()-->(213) - │ │ │ │ │ │ ├── limit hint: 1.00 - │ │ │ │ │ │ ├── scan c - │ │ │ │ │ │ │ ├── columns: c2:213 - │ │ │ │ │ │ │ └── limit hint: 100.00 - │ │ │ │ │ │ └── filters - │ │ │ │ │ │ └── c2:213 IS NULL [outer=(213), constraints=(/213: [/NULL - /NULL]; tight), fd=()-->(213)] - │ │ │ │ │ └── 1 - │ │ │ │ └── filters (true) + │ │ │ │ ├── fd: (209)-->(205-207), (206)==(213), (213)==(206) + │ │ │ │ ├── scan b + │ │ │ │ │ ├── columns: b1:205 b2:206 b3:207 b.rowid:209!null + │ │ │ │ │ ├── key: (209) + │ │ │ │ │ └── fd: (209)-->(205-207) + │ │ │ │ ├── distinct-on + │ │ │ │ │ ├── columns: c2:213 + │ │ │ │ │ ├── grouping columns: c2:213 + │ │ │ │ │ ├── key: (213) + │ │ │ │ │ └── scan c + │ │ │ │ │ └── columns: c2:213 + │ │ │ │ └── filters + │ │ │ │ └── c2:213 = b2:206 [outer=(206,213), constraints=(/206: (/NULL - ]; /213: (/NULL - ]), fd=(206)==(213), (213)==(206)] │ │ │ └── aggregations │ │ │ ├── const-agg [as=b1:37, outer=(37)] │ │ │ │ └── b1:37 @@ -2324,23 +2606,35 @@ project │ │ │ │ ├── columns: b1:24 b2:25 b3:26 b.rowid:28!null │ │ │ │ ├── key: (28) │ │ │ │ ├── fd: (28)-->(24-26) - │ │ │ │ └── inner-join (hash) - │ │ │ │ ├── columns: b1:24 b2:25!null b3:26 b.rowid:28!null c2:32!null - │ │ │ │ ├── multiplicity: left-rows(zero-or-one), right-rows(zero-or-more) + │ │ │ │ └── project + │ │ │ │ ├── columns: b1:24 b2:25 b3:26 b.rowid:28!null │ │ │ │ ├── key: (28) - │ │ │ │ ├── fd: (28)-->(24-26), (25)==(32), (32)==(25) - │ │ │ │ ├── scan b - │ │ │ │ │ ├── columns: b1:24 b2:25 b3:26 b.rowid:28!null - │ │ │ │ │ ├── key: (28) - │ │ │ │ │ └── fd: (28)-->(24-26) - │ │ │ │ ├── distinct-on - │ │ │ │ │ ├── columns: c2:32 - │ │ │ │ │ ├── grouping columns: c2:32 - │ │ │ │ │ ├── key: (32) - │ │ │ │ │ └── scan c - │ │ │ │ │ └── columns: c2:32 - │ │ │ │ └── filters - │ │ │ │ └── c2:32 = b2:25 [outer=(25,32), constraints=(/25: (/NULL - ]; /32: (/NULL - ]), fd=(25)==(32), (32)==(25)] + │ │ │ │ ├── fd: (28)-->(24-26) + │ │ │ │ └── inner-join (cross) + │ │ │ │ ├── columns: b1:24 b2:25 b3:26 b.rowid:28!null c2:32 + │ │ │ │ ├── multiplicity: left-rows(zero-or-one), right-rows(zero-or-more) + │ │ │ │ ├── key: (28) + │ │ │ │ ├── fd: ()-->(32), (28)-->(24-26) + │ │ │ │ ├── scan b + │ │ │ │ │ ├── columns: b1:24 b2:25 b3:26 b.rowid:28!null + │ │ │ │ │ ├── key: (28) + │ │ │ │ │ └── fd: (28)-->(24-26) + │ │ │ │ ├── limit + │ │ │ │ │ ├── columns: c2:32 + │ │ │ │ │ ├── cardinality: [0 - 1] + │ │ │ │ │ ├── key: () + │ │ │ │ │ ├── fd: ()-->(32) + │ │ │ │ │ ├── select + │ │ │ │ │ │ ├── columns: c2:32 + │ │ │ │ │ │ ├── fd: ()-->(32) + │ │ │ │ │ │ ├── limit hint: 1.00 + │ │ │ │ │ │ ├── scan c + │ │ │ │ │ │ │ ├── columns: c2:32 + │ │ │ │ │ │ │ └── limit hint: 100.00 + │ │ │ │ │ │ └── filters + │ │ │ │ │ │ └── c2:32 IS NULL [outer=(32), constraints=(/32: [/NULL - /NULL]; tight), fd=()-->(32)] + │ │ │ │ │ └── 1 + │ │ │ │ └── filters (true) │ │ │ └── project │ │ │ ├── columns: b1:38 b2:39 b3:40 b.rowid:42!null │ │ │ ├── key: (42) @@ -2379,35 +2673,23 @@ project │ │ │ │ ├── columns: b1:206 b2:207 b3:208 b.rowid:210!null │ │ │ │ ├── key: (210) │ │ │ │ ├── fd: (210)-->(206-208) - │ │ │ │ └── project - │ │ │ │ ├── columns: b1:206 b2:207 b3:208 b.rowid:210!null + │ │ │ │ └── inner-join (hash) + │ │ │ │ ├── columns: b1:206 b2:207!null b3:208 b.rowid:210!null c2:214!null + │ │ │ │ ├── multiplicity: left-rows(zero-or-one), right-rows(zero-or-more) │ │ │ │ ├── key: (210) - │ │ │ │ ├── fd: (210)-->(206-208) - │ │ │ │ └── inner-join (cross) - │ │ │ │ ├── columns: b1:206 b2:207 b3:208 b.rowid:210!null c2:214 - │ │ │ │ ├── multiplicity: left-rows(zero-or-one), right-rows(zero-or-more) - │ │ │ │ ├── key: (210) - │ │ │ │ ├── fd: ()-->(214), (210)-->(206-208) - │ │ │ │ ├── scan b - │ │ │ │ │ ├── columns: b1:206 b2:207 b3:208 b.rowid:210!null - │ │ │ │ │ ├── key: (210) - │ │ │ │ │ └── fd: (210)-->(206-208) - │ │ │ │ ├── limit - │ │ │ │ │ ├── columns: c2:214 - │ │ │ │ │ ├── cardinality: [0 - 1] - │ │ │ │ │ ├── key: () - │ │ │ │ │ ├── fd: ()-->(214) - │ │ │ │ │ ├── select - │ │ │ │ │ │ ├── columns: c2:214 - │ │ │ │ │ │ ├── fd: ()-->(214) - │ │ │ │ │ │ ├── limit hint: 1.00 - │ │ │ │ │ │ ├── scan c - │ │ │ │ │ │ │ ├── columns: c2:214 - │ │ │ │ │ │ │ └── limit hint: 100.00 - │ │ │ │ │ │ └── filters - │ │ │ │ │ │ └── c2:214 IS NULL [outer=(214), constraints=(/214: [/NULL - /NULL]; tight), fd=()-->(214)] - │ │ │ │ │ └── 1 - │ │ │ │ └── filters (true) + │ │ │ │ ├── fd: (210)-->(206-208), (207)==(214), (214)==(207) + │ │ │ │ ├── scan b + │ │ │ │ │ ├── columns: b1:206 b2:207 b3:208 b.rowid:210!null + │ │ │ │ │ ├── key: (210) + │ │ │ │ │ └── fd: (210)-->(206-208) + │ │ │ │ ├── distinct-on + │ │ │ │ │ ├── columns: c2:214 + │ │ │ │ │ ├── grouping columns: c2:214 + │ │ │ │ │ ├── key: (214) + │ │ │ │ │ └── scan c + │ │ │ │ │ └── columns: c2:214 + │ │ │ │ └── filters + │ │ │ │ └── c2:214 = b2:207 [outer=(207,214), constraints=(/207: (/NULL - ]; /214: (/NULL - ]), fd=(207)==(214), (214)==(207)] │ │ │ └── aggregations │ │ │ ├── const-agg [as=b1:38, outer=(38)] │ │ │ │ └── b1:38 @@ -3025,6 +3307,161 @@ inner-join (hash) └── filters └── a1:1 = b1:7 [outer=(1,7), constraints=(/1: (/NULL - ]; /7: (/NULL - ]), fd=(1)==(7), (7)==(1)] +# We should be able to split the disjunction even though the predicates are +# equalities but not equijoin expressions. +opt expect=SplitDisjunctionOfJoinTerms +SELECT + e.* +FROM + e +WHERE EXISTS ( + SELECT * + FROM f + WHERE (e5 = 30 OR (e3 = 10 AND f2 = 20)) AND f3 = e2 +); +---- +project + ├── columns: e1:1!null e2:2!null e3:3!null e4:4!null e5:5 + ├── key: (1) + ├── fd: (1)-->(2-5) + └── distinct-on + ├── columns: e1:1!null e2:2!null e3:3!null e4:4!null e5:5 + ├── grouping columns: e1:1!null + ├── key: (1) + ├── fd: (1)-->(2-5) + ├── union-all + │ ├── columns: e1:1!null e2:2!null e3:3!null e4:4!null e5:5 + │ ├── left columns: e1:14 e2:15 e3:16 e4:17 e5:18 + │ ├── right columns: e1:27 e2:28 e3:29 e4:30 e5:31 + │ ├── semi-join (lookup f@f_f3_idx) + │ │ ├── columns: e1:14!null e2:15!null e3:16!null e4:17!null e5:18!null + │ │ ├── key columns: [15] = [23] + │ │ ├── key: (14) + │ │ ├── fd: ()-->(18), (14)-->(15-17) + │ │ ├── index-join e + │ │ │ ├── columns: e1:14!null e2:15!null e3:16!null e4:17!null e5:18!null + │ │ │ ├── key: (14) + │ │ │ ├── fd: ()-->(18), (14)-->(15-17) + │ │ │ └── scan e@e_e5_idx + │ │ │ ├── columns: e1:14!null e5:18!null + │ │ │ ├── constraint: /18/14: [/30 - /30] + │ │ │ ├── key: (14) + │ │ │ └── fd: ()-->(18) + │ │ └── filters (true) + │ └── semi-join (hash) + │ ├── columns: e1:27!null e2:28!null e3:29!null e4:30!null e5:31 + │ ├── key: (27) + │ ├── fd: ()-->(29), (27)-->(28,30,31) + │ ├── index-join e + │ │ ├── columns: e1:27!null e2:28!null e3:29!null e4:30!null e5:31 + │ │ ├── key: (27) + │ │ ├── fd: ()-->(29), (27)-->(28,30,31) + │ │ └── scan e@e_e3_e5_e4_idx + │ │ ├── columns: e1:27!null e3:29!null e4:30!null e5:31 + │ │ ├── constraint: /29/31/30/27: [/10 - /10] + │ │ ├── key: (27) + │ │ └── fd: ()-->(29), (27)-->(30,31) + │ ├── scan f@f_f2_idx + │ │ ├── columns: f2:35!null f3:36 + │ │ ├── constraint: /35/34: [/20 - /20] + │ │ └── fd: ()-->(35) + │ └── filters + │ └── f3:36 = e2:28 [outer=(28,36), constraints=(/28: (/NULL - ]; /36: (/NULL - ]), fd=(28)==(36), (36)==(28)] + └── aggregations + ├── const-agg [as=e2:2, outer=(2)] + │ └── e2:2 + ├── const-agg [as=e3:3, outer=(3)] + │ └── e3:3 + ├── const-agg [as=e4:4, outer=(4)] + │ └── e4:4 + └── const-agg [as=e5:5, outer=(5)] + └── e5:5 + +# We should be able to split the disjunction even though the predicates are +# not equalities. +opt expect=SplitDisjunctionOfJoinTerms +SELECT + e.* +FROM + e +WHERE EXISTS ( + SELECT * + FROM f + WHERE ( + (e.e5 > 30 AND e.e5 < 40) + OR (e.e4 IN ('a', 'b') AND f.f2 < 20 AND f.f2 > 10) + ) AND f3 = e2 +) +---- +project + ├── columns: e1:1!null e2:2!null e3:3!null e4:4!null e5:5 + ├── key: (1) + ├── fd: (1)-->(2-5) + └── distinct-on + ├── columns: e1:1!null e2:2!null e3:3!null e4:4!null e5:5 + ├── grouping columns: e1:1!null + ├── key: (1) + ├── fd: (1)-->(2-5) + ├── union-all + │ ├── columns: e1:1!null e2:2!null e3:3!null e4:4!null e5:5 + │ ├── left columns: e1:14 e2:15 e3:16 e4:17 e5:18 + │ ├── right columns: e1:27 e2:28 e3:29 e4:30 e5:31 + │ ├── project + │ │ ├── columns: e1:14!null e2:15!null e3:16!null e4:17!null e5:18!null + │ │ ├── key: (14) + │ │ ├── fd: (14)-->(15-18) + │ │ └── inner-join (hash) + │ │ ├── columns: e1:14!null e2:15!null e3:16!null e4:17!null e5:18!null f3:23!null + │ │ ├── multiplicity: left-rows(zero-or-more), right-rows(zero-or-one) + │ │ ├── key: (14) + │ │ ├── fd: (14)-->(15-18), (15)==(23), (23)==(15) + │ │ ├── distinct-on + │ │ │ ├── columns: f3:23 + │ │ │ ├── grouping columns: f3:23 + │ │ │ ├── internal-ordering: +23 + │ │ │ ├── key: (23) + │ │ │ └── scan f@f_f3_idx + │ │ │ ├── columns: f3:23 + │ │ │ └── ordering: +23 + │ │ ├── index-join e + │ │ │ ├── columns: e1:14!null e2:15!null e3:16!null e4:17!null e5:18!null + │ │ │ ├── key: (14) + │ │ │ ├── fd: (14)-->(15-18) + │ │ │ └── scan e@e_e5_idx + │ │ │ ├── columns: e1:14!null e5:18!null + │ │ │ ├── constraint: /18/14: [/31 - /39] + │ │ │ ├── key: (14) + │ │ │ └── fd: (14)-->(18) + │ │ └── filters + │ │ └── f3:23 = e2:15 [outer=(15,23), constraints=(/15: (/NULL - ]; /23: (/NULL - ]), fd=(15)==(23), (23)==(15)] + │ └── semi-join (hash) + │ ├── columns: e1:27!null e2:28!null e3:29!null e4:30!null e5:31 + │ ├── key: (27) + │ ├── fd: (27)-->(28-31) + │ ├── index-join e + │ │ ├── columns: e1:27!null e2:28!null e3:29!null e4:30!null e5:31 + │ │ ├── key: (27) + │ │ ├── fd: (27)-->(28-31) + │ │ └── scan e@e_e3_idx,partial + │ │ ├── columns: e1:27!null e3:29!null + │ │ ├── key: (27) + │ │ └── fd: (27)-->(29) + │ ├── scan f@f_f2_idx + │ │ ├── columns: f2:35!null f3:36 + │ │ └── constraint: /35/34: [/11 - /19] + │ └── filters + │ └── f3:36 = e2:28 [outer=(28,36), constraints=(/28: (/NULL - ]; /36: (/NULL - ]), fd=(28)==(36), (36)==(28)] + └── aggregations + ├── const-agg [as=e2:2, outer=(2)] + │ └── e2:2 + ├── const-agg [as=e3:3, outer=(3)] + │ └── e3:3 + ├── const-agg [as=e4:4, outer=(4)] + │ └── e4:4 + └── const-agg [as=e5:5, outer=(5)] + └── e5:5 + + ####################### # Correlated antijoin # ####################### @@ -3469,6 +3906,73 @@ inner-join (lookup a) │ └── c2:44 = b2:37 [outer=(37,44), constraints=(/37: (/NULL - ]; /44: (/NULL - ]), fd=(37)==(44), (44)==(37)] └── filters (true) +# We should be able to split the disjunction even though the predicates are +# equalities but not equijoin expressions. +# TODO(rytaft): investigate whether bad stats are causing us to select the +# wrong plan. +opt expect=SplitDisjunctionOfAntiJoinTerms +SELECT + e.* +FROM + e +WHERE NOT EXISTS ( + SELECT * + FROM f + WHERE ((e5 = 30 AND f2 = 40) OR (e3 = 10 AND f2 = 20)) AND f3 = e2 +); +---- +anti-join (hash) + ├── columns: e1:1!null e2:2!null e3:3!null e4:4!null e5:5 + ├── key: (1) + ├── fd: (1)-->(2-5) + ├── scan e + │ ├── columns: e1:1!null e2:2!null e3:3!null e4:4!null e5:5 + │ ├── partial index predicates + │ │ └── e_e3_idx: filters + │ │ └── e4:4 IN ('a', 'b') [outer=(4), constraints=(/4: [/'a' - /'a'] [/'b' - /'b']; tight)] + │ ├── key: (1) + │ └── fd: (1)-->(2-5) + ├── scan f@f_f2_idx + │ └── columns: f2:9 f3:10 + └── filters + ├── ((e5:5 = 30) AND (f2:9 = 40)) OR ((e3:3 = 10) AND (f2:9 = 20)) [outer=(3,5,9), constraints=(/9: [/20 - /20] [/40 - /40])] + └── f3:10 = e2:2 [outer=(2,10), constraints=(/2: (/NULL - ]; /10: (/NULL - ]), fd=(2)==(10), (10)==(2)] + +# We should be able to split the disjunction even though the predicates are +# not equalities. +# TODO(rytaft): investigate whether bad stats are causing us to select the +# wrong plan. +opt expect=SplitDisjunctionOfAntiJoinTerms +SELECT + e.* +FROM + e +WHERE NOT EXISTS ( + SELECT * + FROM f + WHERE ( + (e.e5 > 30 AND e.e5 < 40) + OR (e.e4 IN ('a', 'b') AND f.f2 < 20 AND f.f2 > 10) + ) AND f3 = e2 +) +---- +anti-join (hash) + ├── columns: e1:1!null e2:2!null e3:3!null e4:4!null e5:5 + ├── key: (1) + ├── fd: (1)-->(2-5) + ├── scan e + │ ├── columns: e1:1!null e2:2!null e3:3!null e4:4!null e5:5 + │ ├── partial index predicates + │ │ └── e_e3_idx: filters + │ │ └── e4:4 IN ('a', 'b') [outer=(4), constraints=(/4: [/'a' - /'a'] [/'b' - /'b']; tight)] + │ ├── key: (1) + │ └── fd: (1)-->(2-5) + ├── scan f@f_f2_idx + │ └── columns: f2:9 f3:10 + └── filters + ├── ((e5:5 > 30) AND (e5:5 < 40)) OR (((e4:4 IN ('a', 'b')) AND (f2:9 < 20)) AND (f2:9 > 10)) [outer=(4,5,9)] + └── f3:10 = e2:2 [outer=(2,10), constraints=(/2: (/NULL - ]; /10: (/NULL - ]), fd=(2)==(10), (10)==(2)] + # NOT IN subquery opt expect=SplitDisjunctionOfJoinTerms SELECT d3,d1,d2 FROM d WHERE d1 NOT IN (SELECT b1 FROM b WHERE EXISTS (SELECT 1 FROM c WHERE c2=b2 OR c2=b3)) @@ -3636,30 +4140,14 @@ inner-join (cross) └── (((t1.a1:1 = t2.a1:7) OR (t1.a1:1 = t2.a2:8)) AND (t1.a2:2 = t2.a2:8)) OR (((t2.a1:7 = (t1.a1:1 + 1)) OR (t2.a2:8 = (t1.a1:1 + 4))) AND ((t2.a2:8 = (t1.a2:2 + 8)) OR (t2.a2:8 = (t1.a2:2 + 9)))) [outer=(1,2,7,8), immutable, constraints=(/8: (/NULL - ])] # Negative Tests -# No equijoin terms. Must be at least one equality predicate referencing -# columns from both tables. -opt expect-not=SplitDisjunctionOfJoinTerms -SELECT * FROM a t1, a t2 WHERE (t1.a2 = 1 OR t2.a2 = 1) ----- -inner-join (cross) - ├── columns: a1:1!null a2:2!null a3:3!null a4:4!null a1:7!null a2:8!null a3:9!null a4:10!null - ├── key: (1-4,7-10) - ├── scan a [as=t1] - │ ├── columns: t1.a1:1!null t1.a2:2!null t1.a3:3!null t1.a4:4!null - │ └── key: (1-4) - ├── scan a [as=t2] - │ ├── columns: t2.a1:7!null t2.a2:8!null t2.a3:9!null t2.a4:10!null - │ └── key: (7-10) - └── filters - └── (t1.a2:2 = 1) OR (t2.a2:8 = 1) [outer=(2,8)] - -# No equijoin terms. Must be at least one equality predicate referencing -# columns from both tables. +# No interesting terms. Must be at least one equality predicate referencing +# columns from both tables or a predicate referencing a single table. opt expect-not=SplitDisjunctionOfJoinTerms -SELECT * FROM a t1, a t2 WHERE (t1.a2 > t2.a2 AND t1.a3 > t2.a3 OR t2.a2 = 1) +SELECT * FROM a t1, a t2 WHERE (t1.a2 > t2.a2 AND t1.a3 > t2.a3 OR t2.a2 % t1.a3 = 2) ---- inner-join (cross) ├── columns: a1:1!null a2:2!null a3:3!null a4:4!null a1:7!null a2:8!null a3:9!null a4:10!null + ├── immutable ├── key: (1-4,7-10) ├── scan a [as=t1] │ ├── columns: t1.a1:1!null t1.a2:2!null t1.a3:3!null t1.a4:4!null @@ -3668,7 +4156,7 @@ inner-join (cross) │ ├── columns: t2.a1:7!null t2.a2:8!null t2.a3:9!null t2.a4:10!null │ └── key: (7-10) └── filters - └── ((t1.a2:2 > t2.a2:8) AND (t1.a3:3 > t2.a3:9)) OR (t2.a2:8 = 1) [outer=(2,3,8,9), constraints=(/8: (/NULL - ])] + └── ((t1.a2:2 > t2.a2:8) AND (t1.a3:3 > t2.a3:9)) OR ((t2.a2:8 % t1.a3:3) = 2) [outer=(2,3,8,9), immutable] # Outer join not supported with this optimization opt expect-not=SplitDisjunctionOfJoinTerms @@ -3817,11 +4305,11 @@ project │ └── ((t3.a3:15 IS DISTINCT FROM CAST(NULL AS INT8)) OR CAST(NULL AS BOOL)) OR ((t3.a1:13 IS DISTINCT FROM CAST(NULL AS INT8)) OR CAST(NULL AS BOOL)) [outer=(13,15)] └── t1.a2:2 -# The conjuncts under the top-level disjunct contain no equijoin terms, and -# neither do the nested simple predicates. +# The conjuncts under the top-level disjunct contain no equijoin terms or +# single-table terms, and neither do the nested simple predicates. opt expect-not=SplitDisjunctionOfJoinTerms -SELECT * FROM a t1, a t2 WHERE (((t1.a1 > t1.a1 OR t1.a1 <= t1.a2) AND (t1.a2 > t2.a2+1 OR t1.a1 <= t1.a2-1)) OR - ((t1.a1 > t1.a1+5 OR t1.a1 <= t1.a2+5) AND (t1.a2 > t2.a2+7 OR t1.a1 <= t1.a2-9))) +SELECT * FROM a t1, a t2 WHERE (((t1.a1 > t2.a1 OR t1.a1 <= t2.a2) AND (t1.a2 > t2.a2+1 OR t1.a1 <= t2.a2-1)) OR + ((t1.a1 > t2.a1+5 OR t1.a1 <= t2.a2+5) AND (t1.a2 > t2.a2+7 OR t1.a1 <= t2.a2-9))) ---- inner-join (cross) ├── columns: a1:1!null a2:2!null a3:3!null a4:4!null a1:7!null a2:8!null a3:9!null a4:10!null @@ -3834,10 +4322,10 @@ inner-join (cross) │ ├── columns: t2.a1:7!null t2.a2:8!null t2.a3:9!null t2.a4:10!null │ └── key: (7-10) └── filters - └── ((((t1.a1:1 IS NOT DISTINCT FROM CAST(NULL AS INT8)) AND CAST(NULL AS BOOL)) OR (t1.a1:1 <= t1.a2:2)) AND ((t1.a2:2 > (t2.a2:8 + 1)) OR (t1.a1:1 <= (t1.a2:2 - 1)))) OR (((t1.a1:1 > (t1.a1:1 + 5)) OR (t1.a1:1 <= (t1.a2:2 + 5))) AND ((t1.a2:2 > (t2.a2:8 + 7)) OR (t1.a1:1 <= (t1.a2:2 - 9)))) [outer=(1,2,8), immutable, constraints=(/1: (/NULL - ])] + └── (((t1.a1:1 > t2.a1:7) OR (t1.a1:1 <= t2.a2:8)) AND ((t1.a2:2 > (t2.a2:8 + 1)) OR (t1.a1:1 <= (t2.a2:8 - 1)))) OR (((t1.a1:1 > (t2.a1:7 + 5)) OR (t1.a1:1 <= (t2.a2:8 + 5))) AND ((t1.a2:2 > (t2.a2:8 + 7)) OR (t1.a1:1 <= (t2.a2:8 - 9)))) [outer=(1,2,7,8), immutable, constraints=(/1: (/NULL - ])] # Can't consume both OR terms with a join to a single Scan relation. Both sides -# of each equijoin predicate must be applied on a simple Scan or Select. +# of each interesting predicate must be applied on a simple Scan or Select. opt expect-not=SplitDisjunctionOfJoinTerms SELECT * FROM a t2 INNER JOIN a t1 ON TRUE LEFT OUTER JOIN a t3 ON (t1.a1 = t3.a1 OR t2.a2 = t3.a2) ---- diff --git a/pkg/sql/opt/xform/testdata/rules/join b/pkg/sql/opt/xform/testdata/rules/join index c6e0c2d3b77c..c8f2205cb065 100644 --- a/pkg/sql/opt/xform/testdata/rules/join +++ b/pkg/sql/opt/xform/testdata/rules/join @@ -7362,13 +7362,13 @@ project ├── immutable └── inner-join (lookup nyc_neighborhoods [as=n]) ├── columns: c.boroname:9 c.geom:10!null name:16 n.geom:17!null - ├── key columns: [21] = [14] + ├── key columns: [61] = [14] ├── lookup columns are key ├── immutable ├── inner-join (inverted nyc_neighborhoods@nyc_neighborhoods_geo_idx [as=n]) - │ ├── columns: c.boroname:9 c.geom:10 n.gid:21!null + │ ├── columns: c.boroname:9 c.geom:10 n.gid:61!null │ ├── inverted-expr - │ │ └── st_coveredby(c.geom:10, n.geom:24) AND (st_dwithin(c.geom:10, n.geom:24, 50.0) OR st_intersects('0102000000020000000000000000000000000000000000000000000000000000000000000000000040', n.geom:24)) + │ │ └── st_coveredby(c.geom:10, n.geom:64) AND (st_dwithin(c.geom:10, n.geom:64, 50.0) OR st_intersects('0102000000020000000000000000000000000000000000000000000000000000000000000000000040', n.geom:64)) │ ├── scan nyc_census_blocks [as=c] │ │ └── columns: c.boroname:9 c.geom:10 │ └── filters (true) @@ -7516,7 +7516,7 @@ SELECT n.name, c.boroname FROM nyc_census_blocks AS c JOIN nyc_neighborhoods@nyc_neighborhoods_geo_idx AS n -ON ST_Covers(c.geom, n.geom) OR n.name LIKE 'Upper%' +ON ST_Covers(c.geom, n.geom) OR n.name LIKE c.boroname || 'Upper%' ---- project ├── columns: name:16 boroname:9 @@ -7530,7 +7530,7 @@ project │ ├── columns: name:16 n.geom:17 │ └── flags: force-index=nyc_neighborhoods_geo_idx └── filters - └── st_covers(c.geom:10, n.geom:17) OR (name:16 LIKE 'Upper%') [outer=(10,16,17), immutable] + └── st_covers(c.geom:10, n.geom:17) OR (name:16 LIKE (c.boroname:9 || 'Upper%')) [outer=(9,10,16,17), immutable] # Semi-joins are supported by converting them to a paired-join consisting of # an inner inverted join followed by a left semi lookup join. @@ -9792,66 +9792,66 @@ project │ ├── right columns: a:25 b:26 c:27 │ ├── cardinality: [0 - 2] │ ├── ordering: +1 - │ ├── project - │ │ ├── columns: a:13!null b:14 c:15 + │ ├── semi-join (lookup pqr@q) + │ │ ├── columns: a:13!null b:14 c:15!null + │ │ ├── key columns: [14 105] = [19 18] + │ │ ├── lookup columns are key │ │ ├── cardinality: [0 - 1] - │ │ ├── key: (13) - │ │ ├── fd: (13)-->(14,15), (15)~~>(13,14) - │ │ ├── ordering: +13 [actual: ] - │ │ └── project - │ │ ├── columns: a:13!null b:14!null c:15!null q:19!null r:20!null - │ │ ├── cardinality: [0 - 1] - │ │ ├── key: () - │ │ ├── fd: ()-->(13-15,19,20), (15)==(20), (20)==(15), (14)==(19), (19)==(14) - │ │ └── inner-join (lookup zz) - │ │ ├── columns: a:13!null b:14!null c:15!null p:18!null q:19!null r:20!null - │ │ ├── key columns: [13] = [13] - │ │ ├── lookup columns are key - │ │ ├── cardinality: [0 - 1] - │ │ ├── key: () - │ │ ├── fd: ()-->(13-15,18-20), (19)==(14), (15)==(20), (20)==(15), (14)==(19) - │ │ ├── inner-join (lookup zz@idx_c) - │ │ │ ├── columns: a:13!null c:15!null p:18!null q:19 r:20!null - │ │ │ ├── key columns: [20] = [15] - │ │ │ ├── lookup columns are key - │ │ │ ├── cardinality: [0 - 1] - │ │ │ ├── key: () - │ │ │ ├── fd: ()-->(13,15,18-20), (20)==(15), (15)==(20) - │ │ │ ├── scan pqr - │ │ │ │ ├── columns: p:18!null q:19 r:20 - │ │ │ │ ├── constraint: /18: [/0 - /0] - │ │ │ │ ├── cardinality: [0 - 1] - │ │ │ │ ├── key: () - │ │ │ │ └── fd: ()-->(18-20) - │ │ │ └── filters (true) - │ │ └── filters - │ │ └── q:19 = b:14 [outer=(14,19), constraints=(/14: (/NULL - ]; /19: (/NULL - ]), fd=(14)==(19), (19)==(14)] - │ └── semi-join (lookup pqr@q) - │ ├── columns: a:25!null b:26 c:27!null - │ ├── key columns: [26 121] = [31 30] - │ ├── lookup columns are key + │ │ ├── key: () + │ │ ├── fd: ()-->(13-15) + │ │ ├── project + │ │ │ ├── columns: "lookup_join_const_col_@18":105!null a:13!null b:14 c:15!null + │ │ │ ├── cardinality: [0 - 1] + │ │ │ ├── key: () + │ │ │ ├── fd: ()-->(13-15,105) + │ │ │ ├── index-join zz + │ │ │ │ ├── columns: a:13!null b:14 c:15!null + │ │ │ │ ├── cardinality: [0 - 1] + │ │ │ │ ├── key: () + │ │ │ │ ├── fd: ()-->(13-15) + │ │ │ │ └── scan zz@idx_c + │ │ │ │ ├── columns: a:13!null c:15!null + │ │ │ │ ├── constraint: /15: [/0 - /0] + │ │ │ │ ├── cardinality: [0 - 1] + │ │ │ │ ├── key: () + │ │ │ │ └── fd: ()-->(13,15) + │ │ │ └── projections + │ │ │ └── 0 [as="lookup_join_const_col_@18":105] + │ │ └── filters (true) + │ └── project + │ ├── columns: a:25!null b:26 c:27 │ ├── cardinality: [0 - 1] - │ ├── key: () - │ ├── fd: ()-->(25-27) - │ ├── project - │ │ ├── columns: "lookup_join_const_col_@30":121!null a:25!null b:26 c:27!null - │ │ ├── cardinality: [0 - 1] - │ │ ├── key: () - │ │ ├── fd: ()-->(25-27,121) - │ │ ├── index-join zz - │ │ │ ├── columns: a:25!null b:26 c:27!null - │ │ │ ├── cardinality: [0 - 1] - │ │ │ ├── key: () - │ │ │ ├── fd: ()-->(25-27) - │ │ │ └── scan zz@idx_c - │ │ │ ├── columns: a:25!null c:27!null - │ │ │ ├── constraint: /27: [/0 - /0] - │ │ │ ├── cardinality: [0 - 1] - │ │ │ ├── key: () - │ │ │ └── fd: ()-->(25,27) - │ │ └── projections - │ │ └── 0 [as="lookup_join_const_col_@30":121] - │ └── filters (true) + │ ├── key: (25) + │ ├── fd: (25)-->(26,27), (27)~~>(25,26) + │ ├── ordering: +25 [actual: ] + │ └── project + │ ├── columns: a:25!null b:26!null c:27!null q:31!null r:32!null + │ ├── cardinality: [0 - 1] + │ ├── key: () + │ ├── fd: ()-->(25-27,31,32), (27)==(32), (32)==(27), (26)==(31), (31)==(26) + │ └── inner-join (lookup zz) + │ ├── columns: a:25!null b:26!null c:27!null p:30!null q:31!null r:32!null + │ ├── key columns: [25] = [25] + │ ├── lookup columns are key + │ ├── cardinality: [0 - 1] + │ ├── key: () + │ ├── fd: ()-->(25-27,30-32), (31)==(26), (27)==(32), (32)==(27), (26)==(31) + │ ├── inner-join (lookup zz@idx_c) + │ │ ├── columns: a:25!null c:27!null p:30!null q:31 r:32!null + │ │ ├── key columns: [32] = [27] + │ │ ├── lookup columns are key + │ │ ├── cardinality: [0 - 1] + │ │ ├── key: () + │ │ ├── fd: ()-->(25,27,30-32), (32)==(27), (27)==(32) + │ │ ├── scan pqr + │ │ │ ├── columns: p:30!null q:31 r:32 + │ │ │ ├── constraint: /30: [/0 - /0] + │ │ │ ├── cardinality: [0 - 1] + │ │ │ ├── key: () + │ │ │ └── fd: ()-->(30-32) + │ │ └── filters (true) + │ └── filters + │ └── q:31 = b:26 [outer=(26,31), constraints=(/26: (/NULL - ]; /31: (/NULL - ]), fd=(26)==(31), (31)==(26)] └── aggregations ├── const-agg [as=b:2, outer=(2)] │ └── b:2