Skip to content

Commit

Permalink
opt: prune RHS of a semi/anti join
Browse files Browse the repository at this point in the history
Fixes #38704.

This change adds a PruneSemiAntiJoinRightCols to prune
columns in the RHS of a semi/anti join. Alternatively,
we could just tag the PruneJoinRightCols rule as higher
priority to achieve the same effect (previously that rule
was never triggered because the `EliminateProjects` rule
would fire and remove the projections after
`PruneJoinLeftCols` rule is applied). I prefer this rule
because it avoids requiring an ordering of transformations.

Release note: None
  • Loading branch information
Ridwan Sharif committed Aug 15, 2019
1 parent da31c04 commit 76411a6
Show file tree
Hide file tree
Showing 13 changed files with 385 additions and 405 deletions.
56 changes: 26 additions & 30 deletions pkg/sql/opt/exec/execbuilder/testdata/subquery
Original file line number Diff line number Diff line change
Expand Up @@ -156,27 +156,25 @@ merge-join · · (x, y) ·
├── scan · · (x, y) +x
│ table a@primary · ·
│ spans ALL · ·
└── scan · · (x, z) +x
└── scan · · (x) +x
· table b@primary · ·
· spans ALL · ·

query TTTTT
EXPLAIN (VERBOSE) SELECT * FROM a WHERE EXISTS(SELECT * FROM b WHERE b.x-1 = a.x)
----
hash-join · · (x, y) ·
│ type semi · ·
│ equality (x) = (column5) · ·
│ left cols are key · · ·
├── scan · · (x, y) ·
│ table a@primary · ·
│ spans ALL · ·
└── render · · (column5, x, z) ·
│ render 0 x - 1 · ·
│ render 1 x · ·
│ render 2 z · ·
└── scan · · (x, z) ·
· table b@primary · ·
· spans ALL · ·
hash-join · · (x, y) ·
│ type semi · ·
│ equality (x) = (column5) · ·
│ left cols are key · · ·
├── scan · · (x, y) ·
│ table a@primary · ·
│ spans ALL · ·
└── render · · (column5) ·
│ render 0 x - 1 · ·
└── scan · · (x) ·
· table b@primary · ·
· spans ALL · ·

query TTTTT
EXPLAIN (VERBOSE) SELECT * FROM a WHERE NOT EXISTS(SELECT * FROM b WHERE b.x = a.x)
Expand All @@ -188,27 +186,25 @@ merge-join · · (x, y) ·
├── scan · · (x, y) +x
│ table a@primary · ·
│ spans ALL · ·
└── scan · · (x, z) +x
└── scan · · (x) +x
· table b@primary · ·
· spans ALL · ·

query TTTTT
EXPLAIN (VERBOSE) SELECT * FROM b WHERE NOT EXISTS(SELECT * FROM a WHERE x-1 = b.x)
----
hash-join · · (x, z) ·
│ type anti · ·
│ equality (x) = (column5) · ·
│ left cols are key · · ·
├── scan · · (x, z) ·
│ table b@primary · ·
│ spans ALL · ·
└── render · · (column5, x, y) ·
│ render 0 x - 1 · ·
│ render 1 x · ·
│ render 2 y · ·
└── scan · · (x, y) ·
· table a@primary · ·
· spans ALL · ·
hash-join · · (x, z) ·
│ type anti · ·
│ equality (x) = (column5) · ·
│ left cols are key · · ·
├── scan · · (x, z) ·
│ table b@primary · ·
│ spans ALL · ·
└── render · · (column5) ·
│ render 0 x - 1 · ·
└── scan · · (x) ·
· table a@primary · ·
· spans ALL · ·

query TTTTT
EXPLAIN (VERBOSE) SELECT ARRAY(SELECT x FROM b)
Expand Down
68 changes: 28 additions & 40 deletions pkg/sql/opt/memo/testdata/logprops/join
Original file line number Diff line number Diff line change
Expand Up @@ -363,8 +363,8 @@ semi-join (hash)
│ ├── prune: (1-4)
│ └── interesting orderings: (+1) (-3,+4,+1)
├── scan uv
│ ├── columns: u:5(int) v:6(int!null)
│ └── prune: (5,6)
│ ├── columns: u:5(int)
│ └── prune: (5)
└── filters
└── eq [type=bool, outer=(1,5), constraints=(/1: (/NULL - ]; /5: (/NULL - ]), fd=(1)==(5), (5)==(1)]
├── variable: x [type=int]
Expand All @@ -387,18 +387,16 @@ semi-join-apply
│ ├── prune: (1-4)
│ └── interesting orderings: (+1) (-3,+4,+1)
├── offset
│ ├── columns: u:5(int) v:6(int!null)
│ ├── columns: v:6(int!null)
│ ├── outer: (1)
│ ├── fd: ()-->(6)
│ ├── prune: (5)
│ ├── select
│ │ ├── columns: u:5(int) v:6(int!null)
│ │ ├── columns: v:6(int!null)
│ │ ├── outer: (1)
│ │ ├── fd: ()-->(6)
│ │ ├── prune: (5)
│ │ ├── scan uv
│ │ │ ├── columns: u:5(int) v:6(int!null)
│ │ │ └── prune: (5,6)
│ │ │ ├── columns: v:6(int!null)
│ │ │ └── prune: (6)
│ │ └── filters
│ │ └── eq [type=bool, outer=(1,6), constraints=(/1: (/NULL - ]; /6: (/NULL - ]), fd=(1)==(6), (6)==(1)]
│ │ ├── variable: v [type=int]
Expand All @@ -423,19 +421,17 @@ semi-join-apply
│ ├── prune: (1-4)
│ └── interesting orderings: (+1) (-3,+4,+1)
├── semi-join (hash)
│ ├── columns: u:5(int) v:6(int!null)
│ ├── columns: v:6(int!null)
│ ├── outer: (1)
│ ├── fd: ()-->(6)
│ ├── prune: (5)
│ ├── scan uv
│ │ ├── columns: u:5(int) v:6(int!null)
│ │ └── prune: (5,6)
│ │ ├── columns: v:6(int!null)
│ │ └── prune: (6)
│ ├── scan mn
│ │ ├── columns: m:8(int!null) n:9(int)
│ │ ├── columns: m:8(int!null)
│ │ ├── key: (8)
│ │ ├── fd: (8)-->(9), (9)~~>(8)
│ │ ├── prune: (8,9)
│ │ └── interesting orderings: (+8) (+9,+8)
│ │ ├── prune: (8)
│ │ └── interesting orderings: (+8)
│ └── filters
│ ├── eq [type=bool, outer=(1,8), constraints=(/1: (/NULL - ]; /8: (/NULL - ]), fd=(1)==(8), (8)==(1)]
│ │ ├── variable: x [type=int]
Expand All @@ -462,8 +458,8 @@ anti-join (hash)
│ ├── prune: (1-4)
│ └── interesting orderings: (+1) (-3,+4,+1)
├── scan uv
│ ├── columns: u:5(int) v:6(int!null)
│ └── prune: (5,6)
│ ├── columns: u:5(int)
│ └── prune: (5)
└── filters
└── eq [type=bool, outer=(1,5), constraints=(/1: (/NULL - ]; /5: (/NULL - ]), fd=(1)==(5), (5)==(1)]
├── variable: x [type=int]
Expand All @@ -486,18 +482,16 @@ anti-join-apply
│ ├── prune: (1-4)
│ └── interesting orderings: (+1) (-3,+4,+1)
├── offset
│ ├── columns: u:5(int) v:6(int!null)
│ ├── columns: v:6(int!null)
│ ├── outer: (1)
│ ├── fd: ()-->(6)
│ ├── prune: (5)
│ ├── select
│ │ ├── columns: u:5(int) v:6(int!null)
│ │ ├── columns: v:6(int!null)
│ │ ├── outer: (1)
│ │ ├── fd: ()-->(6)
│ │ ├── prune: (5)
│ │ ├── scan uv
│ │ │ ├── columns: u:5(int) v:6(int!null)
│ │ │ └── prune: (5,6)
│ │ │ ├── columns: v:6(int!null)
│ │ │ └── prune: (6)
│ │ └── filters
│ │ └── eq [type=bool, outer=(1,6), constraints=(/1: (/NULL - ]; /6: (/NULL - ]), fd=(1)==(6), (6)==(1)]
│ │ ├── variable: v [type=int]
Expand Down Expand Up @@ -643,8 +637,6 @@ semi-join (hash)
│ ├── variable: count_rows [type=int]
│ └── const: 1 [type=int]
├── scan uv
│ ├── columns: u:6(int) v:7(int!null)
│ └── prune: (6,7)
└── filters (true)

# Calculate semi-join-apply cardinality.
Expand All @@ -666,19 +658,17 @@ semi-join-apply
│ ├── prune: (1-4)
│ └── interesting orderings: (+1) (-3,+4,+1)
├── limit
│ ├── columns: u:5(int!null) v:6(int!null)
│ ├── columns: u:5(int!null)
│ ├── outer: (1)
│ ├── cardinality: [0 - 5]
│ ├── fd: ()-->(5)
│ ├── prune: (6)
│ ├── select
│ │ ├── columns: u:5(int!null) v:6(int!null)
│ │ ├── columns: u:5(int!null)
│ │ ├── outer: (1)
│ │ ├── fd: ()-->(5)
│ │ ├── prune: (6)
│ │ ├── scan uv
│ │ │ ├── columns: u:5(int) v:6(int!null)
│ │ │ └── prune: (5,6)
│ │ │ ├── columns: u:5(int)
│ │ │ └── prune: (5)
│ │ └── filters
│ │ └── eq [type=bool, outer=(1,5), constraints=(/1: (/NULL - ]; /5: (/NULL - ]), fd=(1)==(5), (5)==(1)]
│ │ ├── variable: x [type=int]
Expand All @@ -702,8 +692,8 @@ anti-join (hash)
│ └── tuple [type=tuple{int}]
│ └── const: 2 [type=int]
├── scan uv
│ ├── columns: u:2(int) v:3(int!null)
│ └── prune: (2,3)
│ ├── columns: u:2(int)
│ └── prune: (2)
└── filters
└── eq [type=bool, outer=(1,2), constraints=(/1: (/NULL - ]; /2: (/NULL - ]), fd=(1)==(2), (2)==(1)]
├── variable: u [type=int]
Expand All @@ -728,19 +718,17 @@ anti-join-apply
│ ├── prune: (1-4)
│ └── interesting orderings: (+1) (-3,+4,+1)
├── limit
│ ├── columns: u:5(int!null) v:6(int!null)
│ ├── columns: u:5(int!null)
│ ├── outer: (1)
│ ├── cardinality: [0 - 5]
│ ├── fd: ()-->(5)
│ ├── prune: (6)
│ ├── select
│ │ ├── columns: u:5(int!null) v:6(int!null)
│ │ ├── columns: u:5(int!null)
│ │ ├── outer: (1)
│ │ ├── fd: ()-->(5)
│ │ ├── prune: (6)
│ │ ├── scan uv
│ │ │ ├── columns: u:5(int) v:6(int!null)
│ │ │ └── prune: (5,6)
│ │ │ ├── columns: u:5(int)
│ │ │ └── prune: (5)
│ │ └── filters
│ │ └── eq [type=bool, outer=(1,5), constraints=(/1: (/NULL - ]; /5: (/NULL - ]), fd=(1)==(5), (5)==(1)]
│ │ ├── variable: x [type=int]
Expand Down
8 changes: 4 additions & 4 deletions pkg/sql/opt/memo/testdata/stats/join
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,8 @@ semi-join (hash)
│ ├── key: (1)
│ └── fd: (1)-->(2-4), (3,4)~~>(1,2)
├── scan uv
│ ├── columns: u:5(int) v:6(int!null)
│ └── stats: [rows=10000, distinct(5)=500, null(5)=0, distinct(6)=100, null(6)=0]
│ ├── columns: u:5(int)
│ └── stats: [rows=10000]
└── filters
└── x = u [type=bool, outer=(1,5), constraints=(/1: (/NULL - ]; /5: (/NULL - ]), fd=(1)==(5), (5)==(1)]

Expand All @@ -345,8 +345,8 @@ anti-join (hash)
│ ├── key: (1)
│ └── fd: (1)-->(2-4), (3,4)~~>(1,2)
├── scan uv
│ ├── columns: u:5(int) v:6(int!null)
│ └── stats: [rows=10000, distinct(5)=500, null(5)=0, distinct(6)=100, null(6)=0]
│ ├── columns: u:5(int)
│ └── stats: [rows=10000]
└── filters
└── x = u [type=bool, outer=(1,5), constraints=(/1: (/NULL - ]; /5: (/NULL - ]), fd=(1)==(5), (5)==(1)]

Expand Down
Loading

0 comments on commit 76411a6

Please sign in to comment.