Skip to content

Commit c7ecbe2

Browse files
author
Mark Sirek
committed
xform: improve detection of local lookup joins with RBR tables
This commit improves the optimizer's ability to detect the proper distribution of a string of lookup joins involving REGIONAL BY ROW tables by updating the interfaces which match on the `crdb_region` key column of the join to use a `ColSet` which holds all of the `crdb_region` column ids which have been equated with eachother. Informs: cockroachdb#105942 Release note (bug fix): This patch fixes an optimizer costing bug introduced in v23.1 which may cause a query whose best-cost query plan is a string of lookup joins with REGIONAL BY ROW tables, one after the other in sequence, to not pick the most optimal join plan.
1 parent 5c276ae commit c7ecbe2

File tree

6 files changed

+249
-116
lines changed

6 files changed

+249
-116
lines changed

pkg/ccl/logictestccl/testdata/logic_test/regional_by_row_query_behavior

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3642,3 +3642,113 @@ vectorized: true
36423642
table: xyz@xyz_id2_str_abc_id_idx
36433643
spans: [/'ap-southeast-2'/'68088706-02c6-47d1-b993-a421cd761f2b' - /'ap-southeast-2'/'68088706-02c6-47d1-b993-a421cd761f2b']
36443644

3645+
# The following should use a string of 4 lookup joins with a cost under 200.
3646+
query T retry
3647+
EXPLAIN(opt,verbose) SELECT
3648+
x.str,
3649+
a.id1,
3650+
a.id2,
3651+
a.created_at,
3652+
a.updated_at,
3653+
b.id1,
3654+
b.id2,
3655+
b.created_at,
3656+
b.updated_at
3657+
FROM
3658+
abc a
3659+
INNER JOIN xyz x ON
3660+
x.abc_id = a.id
3661+
AND x.id2 = a.id2
3662+
AND x.crdb_region = a.crdb_region
3663+
INNER JOIN abc b ON
3664+
x.abc_id = b.id
3665+
AND x.id2 = b.id2
3666+
AND x.crdb_region = b.crdb_region
3667+
WHERE
3668+
a.id1 = '6da4f356-e526-4b78-b9f9-bbb1a7fc12d6'
3669+
AND a.id2 = '68088706-02c6-47d1-b993-a421cd761f2b'
3670+
AND a.crdb_region = 'ap-southeast-2'
3671+
AND b.id1 = '6da4f356-e526-4b78-b9f9-bbb1a7fc12d6'
3672+
AND b.id2 = '68088706-02c6-47d1-b993-a421cd761f2b'
3673+
AND b.crdb_region = 'ap-southeast-2'
3674+
AND x.crdb_region = 'ap-southeast-2';
3675+
----
3676+
project
3677+
├── columns: str:10 id1:2 id2:5 created_at:3 updated_at:4 id1:17 id2:20 created_at:18 updated_at:19
3678+
├── immutable
3679+
├── stats: [rows=1.031997]
3680+
├── cost: 112.377461
3681+
├── fd: ()-->(2,5,17,20), (2)==(17), (17)==(2), (3)==(18), (18)==(3), (4)==(19), (19)==(4)
3682+
├── distribution: ap-southeast-2
3683+
├── prune: (2-5,10,17-20)
3684+
└── inner-join (lookup abc [as=a])
3685+
├── columns: a.id:1 a.id1:2 a.created_at:3 a.updated_at:4 a.id2:5 a.crdb_region:6 str:10 abc_id:11 x.id2:12 x.crdb_region:13 b.id:16 b.id1:17 b.created_at:18 b.updated_at:19 b.id2:20 b.crdb_region:21
3686+
├── key columns: [6 1] = [6 1]
3687+
├── lookup columns are key
3688+
├── immutable
3689+
├── stats: [rows=1.031997, distinct(11)=0.936667, null(11)=0, distinct(12)=0.936667, null(12)=0, distinct(13)=0.936667, null(13)=0, distinct(16)=0.936667, null(16)=0, distinct(20)=0.936667, null(20)=0, distinct(21)=0.936667, null(21)=0]
3690+
├── cost: 112.347141
3691+
├── fd: ()-->(2,5,6,12,13,17,20,21), (1)-->(3,4), (1)==(11,16), (11)==(1,16), (5)==(12,20), (12)==(5,20), (6)==(13,21), (13)==(6,21), (16)-->(18,19), (16)==(1,11), (20)==(5,12), (21)==(6,13), (2)==(17), (17)==(2), (3)==(18), (18)==(3), (4)==(19), (19)==(4)
3692+
├── distribution: ap-southeast-2
3693+
├── inner-join (lookup abc@abc_id1_id2_idx [as=a])
3694+
│ ├── columns: a.id:1 a.id1:2 a.id2:5 a.crdb_region:6 str:10 abc_id:11 x.id2:12 x.crdb_region:13 b.id:16 b.id1:17 b.created_at:18 b.updated_at:19 b.id2:20 b.crdb_region:21
3695+
│ ├── key columns: [13 17 12 11] = [6 2 5 1]
3696+
│ ├── lookup columns are key
3697+
│ ├── immutable
3698+
│ ├── stats: [rows=0.01031997, distinct(1)=0.01032, null(1)=0, distinct(2)=0.01032, null(2)=0, distinct(5)=0.01032, null(5)=0, distinct(6)=0.01032, null(6)=0, distinct(10)=0.0102714, null(10)=0, distinct(11)=0.01032, null(11)=0, distinct(12)=0.01032, null(12)=0, distinct(13)=0.01032, null(13)=0, distinct(16)=0.0102638, null(16)=0, distinct(17)=0.01032, null(17)=0, distinct(18)=0.010244, null(18)=0, distinct(19)=0.010244, null(19)=0, distinct(20)=0.0102638, null(20)=0, distinct(21)=0.0102638, null(21)=0, distinct(2,5,6)=0.01032, null(2,5,6)=0]
3699+
│ ├── cost: 112.088874
3700+
│ ├── fd: ()-->(2,5,6,12,13,17,20,21), (16)-->(18,19), (11)==(1,16), (16)==(1,11), (12)==(5,20), (20)==(5,12), (13)==(6,21), (21)==(6,13), (6)==(13,21), (2)==(17), (17)==(2), (5)==(12,20), (1)==(11,16)
3701+
│ ├── distribution: ap-southeast-2
3702+
│ ├── inner-join (lookup abc [as=b])
3703+
│ │ ├── columns: str:10 abc_id:11 x.id2:12 x.crdb_region:13 b.id:16 b.id1:17 b.created_at:18 b.updated_at:19 b.id2:20 b.crdb_region:21
3704+
│ │ ├── key columns: [21 16] = [21 16]
3705+
│ │ ├── lookup columns are key
3706+
│ │ ├── immutable
3707+
│ │ ├── stats: [rows=1.101776, distinct(10)=1.08174, null(10)=0, distinct(11)=0.936667, null(11)=0, distinct(12)=0.936667, null(12)=0, distinct(13)=0.936667, null(13)=0, distinct(16)=0.936667, null(16)=0, distinct(17)=0.709904, null(17)=0, distinct(18)=0.693547, null(18)=0, distinct(19)=0.693547, null(19)=0, distinct(20)=0.936667, null(20)=0, distinct(21)=0.936667, null(21)=0]
3708+
│ │ ├── cost: 107.514948
3709+
│ │ ├── fd: ()-->(12,13,17,20,21), (16)-->(18,19), (11)==(16), (16)==(11), (12)==(20), (20)==(12), (13)==(21), (21)==(13)
3710+
│ │ ├── distribution: ap-southeast-2
3711+
│ │ ├── interesting orderings: (+11 opt(12,13)) (+10,+11 opt(12,13)) (+16 opt(17,20,21))
3712+
│ │ ├── inner-join (lookup abc@abc_id1_id2_idx [as=b])
3713+
│ │ │ ├── columns: str:10 abc_id:11 x.id2:12 x.crdb_region:13 b.id:16 b.id1:17 b.id2:20 b.crdb_region:21
3714+
│ │ │ ├── key columns: [13 28 12 11] = [21 17 20 16]
3715+
│ │ │ ├── lookup columns are key
3716+
│ │ │ ├── immutable
3717+
│ │ │ ├── stats: [rows=0.03434444, distinct(11)=0.0343444, null(11)=0, distinct(12)=0.0343444, null(12)=0, distinct(13)=0.0343444, null(13)=0, distinct(16)=0.0343444, null(16)=0, distinct(17)=0.0343444, null(17)=0, distinct(20)=0.0343444, null(20)=0, distinct(21)=0.0343444, null(21)=0, distinct(28)=0.0343444, null(28)=0, distinct(17,20,21)=0.0343444, null(17,20,21)=0]
3718+
│ │ │ ├── cost: 88.4621065
3719+
│ │ │ ├── fd: ()-->(12,13,17,20,21), (13)==(21), (21)==(13), (12)==(20), (20)==(12), (11)==(16), (16)==(11)
3720+
│ │ │ ├── distribution: ap-southeast-2
3721+
│ │ │ ├── interesting orderings: (+(11|16) opt(12,13,17,20,21,28)) (+10,+(11|16) opt(12,13,17,20,21,28))
3722+
│ │ │ ├── project
3723+
│ │ │ │ ├── columns: "lookup_join_const_col_@17":28 str:10 abc_id:11 x.id2:12 x.crdb_region:13
3724+
│ │ │ │ ├── immutable
3725+
│ │ │ │ ├── stats: [rows=3.666667, distinct(10)=3.11719, null(10)=0, distinct(11)=3.11719, null(11)=0, distinct(12)=1, null(12)=0, distinct(13)=1, null(13)=0, distinct(28)=1, null(28)=0]
3726+
│ │ │ │ ├── cost: 73.3666668
3727+
│ │ │ │ ├── fd: ()-->(12,13,28)
3728+
│ │ │ │ ├── distribution: ap-southeast-2
3729+
│ │ │ │ ├── interesting orderings: (+11 opt(12,13,28)) (+10,+11 opt(12,13,28))
3730+
│ │ │ │ ├── scan xyz@xyz_id2_str_abc_id_idx [as=x]
3731+
│ │ │ │ │ ├── columns: str:10 abc_id:11 x.id2:12 x.crdb_region:13
3732+
│ │ │ │ │ ├── constraint: /13/12/10/11/9: [/'ap-southeast-2'/'68088706-02c6-47d1-b993-a421cd761f2b' - /'ap-southeast-2'/'68088706-02c6-47d1-b993-a421cd761f2b']
3733+
│ │ │ │ │ ├── immutable
3734+
│ │ │ │ │ ├── stats: [rows=3.666667, distinct(10)=3.11719, null(10)=0, distinct(11)=3.11719, null(11)=0, distinct(12)=1, null(12)=0, distinct(13)=1, null(13)=0, distinct(12,13)=1, null(12,13)=0]
3735+
│ │ │ │ │ │ histogram(13)= 0 3.6667
3736+
│ │ │ │ │ │ <--- 'ap-southeast-2'
3737+
│ │ │ │ │ ├── cost: 73.2733335
3738+
│ │ │ │ │ ├── fd: ()-->(12,13)
3739+
│ │ │ │ │ ├── distribution: ap-southeast-2
3740+
│ │ │ │ │ ├── prune: (10,11)
3741+
│ │ │ │ │ └── interesting orderings: (+11 opt(12,13)) (+10,+11 opt(12,13))
3742+
│ │ │ │ └── projections
3743+
│ │ │ │ └── '6da4f356-e526-4b78-b9f9-bbb1a7fc12d6' [as="lookup_join_const_col_@17":28]
3744+
│ │ │ └── filters
3745+
│ │ │ ├── b.id2:20 = '68088706-02c6-47d1-b993-a421cd761f2b' [outer=(20), constraints=(/20: [/'68088706-02c6-47d1-b993-a421cd761f2b' - /'68088706-02c6-47d1-b993-a421cd761f2b']; tight), fd=()-->(20)]
3746+
│ │ │ └── b.crdb_region:21 = 'ap-southeast-2' [outer=(21), immutable, constraints=(/21: [/'ap-southeast-2' - /'ap-southeast-2']; tight), fd=()-->(21)]
3747+
│ │ └── filters (true)
3748+
│ └── filters
3749+
│ ├── a.id2:5 = '68088706-02c6-47d1-b993-a421cd761f2b' [outer=(5), constraints=(/5: [/'68088706-02c6-47d1-b993-a421cd761f2b' - /'68088706-02c6-47d1-b993-a421cd761f2b']; tight), fd=()-->(5)]
3750+
│ ├── a.crdb_region:6 = 'ap-southeast-2' [outer=(6), immutable, constraints=(/6: [/'ap-southeast-2' - /'ap-southeast-2']; tight), fd=()-->(6)]
3751+
│ └── a.id1:2 = '6da4f356-e526-4b78-b9f9-bbb1a7fc12d6' [outer=(2), constraints=(/2: [/'6da4f356-e526-4b78-b9f9-bbb1a7fc12d6' - /'6da4f356-e526-4b78-b9f9-bbb1a7fc12d6']; tight), fd=()-->(2)]
3752+
└── filters
3753+
├── a.created_at:3 = b.created_at:18 [outer=(3,18), constraints=(/3: (/NULL - ]; /18: (/NULL - ]), fd=(3)==(18), (18)==(3)]
3754+
└── a.updated_at:4 = b.updated_at:19 [outer=(4,19), constraints=(/4: (/NULL - ]; /19: (/NULL - ]), fd=(4)==(19), (19)==(4)]

pkg/sql/opt/distribution/distribution.go

Lines changed: 124 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -149,22 +149,111 @@ func GetDEnumAsStringFromConstantExpr(expr opt.Expr) (enumAsString string, ok bo
149149
return "", false
150150
}
151151

152-
// BuildLookupJoinLookupTableDistribution builds the Distribution that results
153-
// from performing lookups of a LookupJoin, if that distribution can be
154-
// statically determined. If crdbRegionColID is non-zero, it is the column ID
155-
// of the input REGIONAL BY ROW table holding the crdb_region column, and
156-
// inputDistribution is the distribution of the operation on that table
157-
// (Scan or LocalityOptimizedSearch).
158-
// The distribution of the lookup join is returned, plus the first lookup index
159-
// column, as matched in the lookup with crdbRegionColID (if it can be
160-
// determined, otherwise zero).
152+
// getCRBDRegionColSetFromInput finds the set of column ids in the input to a
153+
// lookup join which are known to all be `crdb_region` columns, either in a Scan
154+
// or by being a `crdb_region` lookup table key column in a lookup join or chain
155+
// of lookup joins, all connected by `crdb_region` key column lookups. This
156+
// column set plus the distribution of the lookup join's input relation is
157+
// returned.
158+
func getCRBDRegionColSetFromInput(
159+
ctx context.Context,
160+
evalCtx *eval.Context,
161+
join *memo.LookupJoinExpr,
162+
required *physical.Required,
163+
maybeGetBestCostRelation func(grp memo.RelExpr, required *physical.Required) (best memo.RelExpr, ok bool),
164+
) (crdbRegionColSet opt.ColSet, inputDistribution physical.Distribution) {
165+
var needRemap bool
166+
var setOpCols opt.ColSet
167+
168+
if bestCostInputRel, ok := maybeGetBestCostRelation(join.Input, required); ok {
169+
maybeScan := bestCostInputRel
170+
var projectExpr *memo.ProjectExpr
171+
if projectExpr, ok = maybeScan.(*memo.ProjectExpr); ok {
172+
maybeScan, ok = maybeGetBestCostRelation(projectExpr.Input, required)
173+
if !ok {
174+
return crdbRegionColSet, physical.Distribution{}
175+
}
176+
}
177+
if selectExpr, ok := maybeScan.(*memo.SelectExpr); ok {
178+
maybeScan, ok = maybeGetBestCostRelation(selectExpr.Input, required)
179+
if !ok {
180+
return crdbRegionColSet, physical.Distribution{}
181+
}
182+
}
183+
if indexJoinExpr, ok := maybeScan.(*memo.IndexJoinExpr); ok {
184+
maybeScan, ok = maybeGetBestCostRelation(indexJoinExpr.Input, required)
185+
if !ok {
186+
return crdbRegionColSet, physical.Distribution{}
187+
}
188+
}
189+
if lookupJoinExpr, ok := maybeScan.(*memo.LookupJoinExpr); ok {
190+
crdbRegionColSet, inputDistribution =
191+
BuildLookupJoinLookupTableDistribution(
192+
ctx, evalCtx, lookupJoinExpr, required, maybeGetBestCostRelation)
193+
return crdbRegionColSet, inputDistribution
194+
}
195+
if localityOptimizedScan, ok := maybeScan.(*memo.LocalityOptimizedSearchExpr); ok {
196+
maybeScan = localityOptimizedScan.Local
197+
needRemap = true
198+
setOpCols = localityOptimizedScan.Relational().OutputCols
199+
}
200+
scanExpr, ok := maybeScan.(*memo.ScanExpr)
201+
if !ok {
202+
return crdbRegionColSet, physical.Distribution{}
203+
}
204+
tab := maybeScan.Memo().Metadata().Table(scanExpr.Table)
205+
if !tab.IsRegionalByRow() {
206+
return crdbRegionColSet, physical.Distribution{}
207+
}
208+
inputDistribution =
209+
BuildProvided(ctx, evalCtx, scanExpr, &required.Distribution)
210+
index := tab.Index(scanExpr.Index)
211+
crdbRegionColID := scanExpr.Table.IndexColumnID(index, 0)
212+
if needRemap {
213+
scanCols := scanExpr.Relational().OutputCols
214+
if scanCols.Len() == setOpCols.Len() {
215+
destCol, _ := setOpCols.Next(0)
216+
for srcCol, ok := scanCols.Next(0); ok; srcCol, ok = scanCols.Next(srcCol + 1) {
217+
if srcCol == crdbRegionColID {
218+
crdbRegionColID = destCol
219+
break
220+
}
221+
destCol, _ = setOpCols.Next(destCol + 1)
222+
}
223+
}
224+
}
225+
if projectExpr != nil {
226+
if !projectExpr.Passthrough.Contains(crdbRegionColID) {
227+
return crdbRegionColSet, physical.Distribution{}
228+
}
229+
}
230+
crdbRegionColSet.Add(crdbRegionColID)
231+
}
232+
return crdbRegionColSet, inputDistribution
233+
}
234+
235+
// BuildLookupJoinLookupTableDistribution builds and returns the Distribution of
236+
// a lookup table in a lookup join if that distribution can be statically
237+
// determined. It also finds the set of column ids in the input to the lookup
238+
// join which are known to all be `crdb_region` columns, either in a Scan or by
239+
// being a `crdb_region` lookup table key column in a lookup join or chain of
240+
// lookup joins, all connected by `crdb_region` key column lookups. This column
241+
// set plus the distribution of the lookup join's lookup table is returned.
242+
// Parameter `maybeGetBestCostRelation` is expected to be a function that looks
243+
// up the best cost relation in the `grp` relation's memo group. Typically this
244+
// is `xform.Coster.MaybeGetBestCostRelation`. It's passed as a function since
245+
// `BuildLookupJoinLookupTableDistribution` may be called from packages not
246+
// allowed to import the `xform` package due to import cycles.
161247
func BuildLookupJoinLookupTableDistribution(
162248
ctx context.Context,
163249
evalCtx *eval.Context,
164250
lookupJoin *memo.LookupJoinExpr,
165-
crdbRegionColID opt.ColumnID,
166-
inputDistribution physical.Distribution,
167-
) (firstLookupIndexCol opt.ColumnID, provided physical.Distribution) {
251+
required *physical.Required,
252+
maybeGetBestCostRelation func(grp memo.RelExpr, required *physical.Required) (best memo.RelExpr, ok bool),
253+
) (crdbRegionColSet opt.ColSet, provided physical.Distribution) {
254+
localCrdbRegionColSet, inputDistribution :=
255+
getCRBDRegionColSetFromInput(ctx, evalCtx, lookupJoin, required, maybeGetBestCostRelation)
256+
168257
lookupTableMeta := lookupJoin.Memo().Metadata().TableMeta(lookupJoin.Table)
169258
lookupTable := lookupTableMeta.Table
170259

@@ -175,13 +264,13 @@ func BuildLookupJoinLookupTableDistribution(
175264

176265
if lookupJoin.LocalityOptimized || lookupJoin.ChildOfLocalityOptimizedSearch {
177266
provided.FromLocality(evalCtx.Locality)
178-
return 0 /* firstLookupIndexCol */, provided
267+
return crdbRegionColSet, provided
179268
} else if lookupTable.IsGlobalTable() {
180269
provided.FromLocality(evalCtx.Locality)
181-
return 0 /* firstLookupIndexCol */, provided
270+
return crdbRegionColSet, provided
182271
} else if homeRegion, ok := lookupTable.HomeRegion(); ok {
183272
provided.Regions = []string{homeRegion}
184-
return 0 /* firstLookupIndexCol */, provided
273+
return crdbRegionColSet, provided
185274
} else if lookupTable.IsRegionalByRow() {
186275
if len(lookupJoin.KeyCols) > 0 {
187276
inputExpr := lookupJoin.Input
@@ -190,46 +279,56 @@ func BuildLookupJoinLookupTableDistribution(
190279
if filterExpr, ok := invertedJoinExpr.GetConstExprFromFilter(firstKeyColID); ok {
191280
if homeRegion, ok = GetDEnumAsStringFromConstantExpr(filterExpr); ok {
192281
provided.Regions = []string{homeRegion}
193-
return colIDOfFirstLookupIndexColumn, provided
282+
crdbRegionColSet.UnionWith(localCrdbRegionColSet)
283+
crdbRegionColSet.Add(colIDOfFirstLookupIndexColumn)
284+
return crdbRegionColSet, provided
194285
}
195286
}
196287
} else if projectExpr, ok := inputExpr.(*memo.ProjectExpr); ok {
197288
regionName := projectExpr.GetProjectedEnumConstant(firstKeyColID)
198289
if regionName != "" {
199290
provided.Regions = []string{regionName}
200-
return colIDOfFirstLookupIndexColumn, provided
291+
crdbRegionColSet.UnionWith(localCrdbRegionColSet)
292+
crdbRegionColSet.Add(colIDOfFirstLookupIndexColumn)
293+
return crdbRegionColSet, provided
201294
}
202295
}
203-
if crdbRegionColID == firstKeyColID {
296+
if localCrdbRegionColSet.Contains(firstKeyColID) {
204297
provided.FromIndexScan(ctx, evalCtx, lookupTableMeta, lookupJoin.Index, nil)
205298
if !inputDistribution.Any() &&
206299
(provided.Any() || len(provided.Regions) > len(inputDistribution.Regions)) {
207-
return colIDOfFirstLookupIndexColumn, inputDistribution
300+
crdbRegionColSet.UnionWith(localCrdbRegionColSet)
301+
crdbRegionColSet.Add(colIDOfFirstLookupIndexColumn)
302+
return crdbRegionColSet, inputDistribution
208303
}
209-
return 0 /* firstLookupIndexCol */, provided
304+
return crdbRegionColSet, provided
210305
}
211306
} else if len(lookupJoin.LookupJoinPrivate.LookupExpr) > 0 {
212307
if filterIdx, ok := lookupJoin.GetConstPrefixFilter(lookupJoin.Memo().Metadata()); ok {
213308
firstIndexColEqExpr := lookupJoin.LookupJoinPrivate.LookupExpr[filterIdx].Condition
214309
if firstIndexColEqExpr.Op() == opt.EqOp {
215310
if regionName, ok := GetDEnumAsStringFromConstantExpr(firstIndexColEqExpr.Child(1)); ok {
216311
provided.Regions = []string{regionName}
217-
return colIDOfFirstLookupIndexColumn, provided
312+
crdbRegionColSet.UnionWith(localCrdbRegionColSet)
313+
crdbRegionColSet.Add(colIDOfFirstLookupIndexColumn)
314+
return crdbRegionColSet, provided
218315
}
219316
}
220-
} else if lookupJoin.ColIsEquivalentWithLookupIndexPrefix(lookupJoin.Memo().Metadata(), crdbRegionColID) {
317+
} else if lookupJoin.LookupIndexPrefixIsEquatedWithColInColSet(lookupJoin.Memo().Metadata(), localCrdbRegionColSet) {
221318
// We have a `crdb_region = crdb_region` term in `LookupJoinPrivate.LookupExpr`.
222319
provided.FromIndexScan(ctx, evalCtx, lookupTableMeta, lookupJoin.Index, nil)
223320
if !inputDistribution.Any() &&
224321
(provided.Any() || len(provided.Regions) > len(inputDistribution.Regions)) {
225-
return colIDOfFirstLookupIndexColumn, inputDistribution
322+
crdbRegionColSet.UnionWith(localCrdbRegionColSet)
323+
crdbRegionColSet.Add(colIDOfFirstLookupIndexColumn)
324+
return crdbRegionColSet, inputDistribution
226325
}
227-
return 0 /* firstLookupIndexCol */, provided
326+
return crdbRegionColSet, provided
228327
}
229328
}
230329
}
231330
provided.FromIndexScan(ctx, evalCtx, lookupTableMeta, lookupJoin.Index, nil)
232-
return 0 /* firstLookupIndexCol */, provided
331+
return crdbRegionColSet, provided
233332
}
234333

235334
// BuildInvertedJoinLookupTableDistribution builds the Distribution that results

pkg/sql/opt/memo/expr.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -920,24 +920,22 @@ func (lj *LookupJoinPrivate) GetConstPrefixFilter(md *opt.Metadata) (pos int, ok
920920
return 0, false
921921
}
922922

923-
// ColIsEquivalentWithLookupIndexPrefix returns true if there is a term in
924-
// `LookupExpr` equating the first column in the lookup index with `col`.
925-
func (lj *LookupJoinPrivate) ColIsEquivalentWithLookupIndexPrefix(
926-
md *opt.Metadata, col opt.ColumnID,
923+
// LookupIndexPrefixIsEquatedWithColInColSet returns true if there is a term in
924+
// `LookupExpr` equating the first column in the lookup index with a column in
925+
// `colSet`.
926+
func (lj *LookupJoinPrivate) LookupIndexPrefixIsEquatedWithColInColSet(
927+
md *opt.Metadata, colSet opt.ColSet,
927928
) bool {
928929
lookupTable := md.Table(lj.Table)
929930
lookupIndex := lookupTable.Index(lj.Index)
930931

931932
idxCol := lj.Table.IndexColumnID(lookupIndex, 0)
932-
var desiredEquivalentCols opt.ColSet
933-
desiredEquivalentCols.Add(idxCol)
934-
desiredEquivalentCols.Add(col)
935933

936934
for i := range lj.LookupExpr {
937935
props := lj.LookupExpr[i].ScalarProps()
938936

939937
equivCols := props.FuncDeps.ComputeEquivGroup(idxCol)
940-
if desiredEquivalentCols.SubsetOf(equivCols) {
938+
if colSet.Intersects(equivCols) {
941939
return true
942940
}
943941
}

0 commit comments

Comments
 (0)