Skip to content

Commit 8d17ae0

Browse files
author
Mark Sirek
committed
memo: print lookup table distribution in EXPLAIN output
This commit adds the distribution of the lookup table of lookup join to the EXPLAIN output when it is not empty. Informs: cockroachdb#105942 Release note: None
1 parent 6cd27b8 commit 8d17ae0

File tree

14 files changed

+96
-0
lines changed

14 files changed

+96
-0
lines changed

pkg/ccl/logictestccl/testdata/logic_test/multi_region_remote_access_error

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,6 +1080,7 @@ project
10801080
│ ├── fd: ()-->(11), (7)-->(9)
10811081
│ ├── limit hint: 1.00
10821082
│ ├── distribution: ap-southeast-2
1083+
│ ├── lookup table distribution: ap-southeast-2
10831084
│ ├── prune: (7)
10841085
│ ├── inner-join (inverted json_arr1_rbr@j_idx [as=t1])
10851086
│ │ ├── columns: t2.j:3 t1.k:18 crdb_region:22

pkg/ccl/logictestccl/testdata/logic_test/regional_by_row_query_behavior

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3690,6 +3690,7 @@ project
36903690
├── cost: 112.347141
36913691
├── 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)
36923692
├── distribution: ap-southeast-2
3693+
├── lookup table distribution: ap-southeast-2,ca-central-1,us-east-1
36933694
├── inner-join (lookup abc@abc_id1_id2_idx [as=a])
36943695
│ ├── 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
36953696
│ ├── key columns: [13 17 12 11] = [6 2 5 1]
@@ -3699,6 +3700,7 @@ project
36993700
│ ├── cost: 112.088874
37003701
│ ├── 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)
37013702
│ ├── distribution: ap-southeast-2
3703+
│ ├── lookup table distribution: ap-southeast-2,ca-central-1,us-east-1
37023704
│ ├── inner-join (lookup abc [as=b])
37033705
│ │ ├── 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
37043706
│ │ ├── key columns: [21 16] = [21 16]
@@ -3708,6 +3710,7 @@ project
37083710
│ │ ├── cost: 107.514948
37093711
│ │ ├── fd: ()-->(12,13,17,20,21), (16)-->(18,19), (11)==(16), (16)==(11), (12)==(20), (20)==(12), (13)==(21), (21)==(13)
37103712
│ │ ├── distribution: ap-southeast-2
3713+
│ │ ├── lookup table distribution: ap-southeast-2,ca-central-1,us-east-1
37113714
│ │ ├── interesting orderings: (+11 opt(12,13)) (+10,+11 opt(12,13)) (+16 opt(17,20,21))
37123715
│ │ ├── inner-join (lookup abc@abc_id1_id2_idx [as=b])
37133716
│ │ │ ├── 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
@@ -3718,6 +3721,7 @@ project
37183721
│ │ │ ├── cost: 88.4621065
37193722
│ │ │ ├── fd: ()-->(12,13,17,20,21), (13)==(21), (21)==(13), (12)==(20), (20)==(12), (11)==(16), (16)==(11)
37203723
│ │ │ ├── distribution: ap-southeast-2
3724+
│ │ │ ├── lookup table distribution: ap-southeast-2,ca-central-1,us-east-1
37213725
│ │ │ ├── interesting orderings: (+(11|16) opt(12,13,17,20,21,28)) (+10,+(11|16) opt(12,13,17,20,21,28))
37223726
│ │ │ ├── project
37233727
│ │ │ │ ├── columns: "lookup_join_const_col_@17":28 str:10 abc_id:11 x.id2:12 x.crdb_region:13

pkg/sql/faketreeeval/evalctx.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,11 @@ func (*DummyEvalPlanner) ExecutorConfig() interface{} {
327327
return nil
328328
}
329329

330+
// Optimizer is part of the cat.Catalog interface.
331+
func (*DummyEvalPlanner) Optimizer() interface{} {
332+
return nil
333+
}
334+
330335
var _ eval.Planner = &DummyEvalPlanner{}
331336

332337
var errEvalPlanner = pgerror.New(pgcode.ScalarOperationCannotRunWithoutFullSessionContext,

pkg/sql/opt/cat/catalog.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,4 +200,8 @@ type Catalog interface {
200200

201201
// RoleExists returns true if the role exists.
202202
RoleExists(ctx context.Context, role username.SQLUsername) (bool, error)
203+
204+
// Optimizer returns the query Optimizer used to optimize SQL statements
205+
// referencing objects in this catalog, if any.
206+
Optimizer() interface{}
203207
}

pkg/sql/opt/memo/expr_format.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,19 @@ func (f *ExprFmtCtx) formatRelational(e RelExpr, tp treeprinter.Node) {
865865
if !required.Distribution.Any() {
866866
tp.Childf("distribution: %s", required.Distribution.String())
867867
}
868+
// Show the lookup table distribution of a lookup join, if it has been set.
869+
if lookupJoinExpr, ok := e.(*LookupJoinExpr); ok && f.Catalog != nil {
870+
if optimizer := f.Catalog.Optimizer(); optimizer != nil {
871+
providedDistribution := GetLookupJoinLookupTableDistribution(
872+
lookupJoinExpr,
873+
lookupJoinExpr.RequiredPhysical(),
874+
optimizer,
875+
)
876+
if !providedDistribution.Any() {
877+
tp.Childf("lookup table distribution: %s", providedDistribution.String())
878+
}
879+
}
880+
}
868881
if distribute, ok := e.(*DistributeExpr); ok {
869882
tp.Childf("input distribution: %s", distribute.Input.ProvidedPhysical().Distribution.String())
870883
}

pkg/sql/opt/memo/memo.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,3 +580,11 @@ func (l *LiteralValuesExpr) ColList() opt.ColList {
580580
func (l *LiteralValuesExpr) Len() int {
581581
return l.Rows.Rows.NumRows()
582582
}
583+
584+
// GetLookupJoinLookupTableDistribution returns the Distribution of a lookup
585+
// table in a lookup join if that distribution can be statically determined.
586+
var GetLookupJoinLookupTableDistribution func(
587+
lookupJoin *LookupJoinExpr,
588+
required *physical.Required,
589+
optimizer interface{},
590+
) (physicalDistribution physical.Distribution)

pkg/sql/opt/metadata_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,3 +541,8 @@ func (ep *fakeGetMultiregionConfigPlanner) GetRangeDescByID(
541541
) (rangeDesc roachpb.RangeDescriptor, err error) {
542542
return
543543
}
544+
545+
// Optimizer is part of the cat.Catalog interface.
546+
func (ep *fakeGetMultiregionConfigPlanner) Optimizer() interface{} {
547+
return nil
548+
}

pkg/sql/opt/testutils/testcat/test_catalog.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,11 @@ func (tc *Catalog) RoleExists(ctx context.Context, role username.SQLUsername) (b
316316
return true, nil
317317
}
318318

319+
// Optimizer is part of the cat.Catalog interface.
320+
func (tc *Catalog) Optimizer() interface{} {
321+
return nil
322+
}
323+
319324
func (tc *Catalog) resolveSchema(toResolve *cat.SchemaName) (cat.Schema, cat.SchemaName, error) {
320325
if string(toResolve.CatalogName) != testDB {
321326
return nil, cat.SchemaName{}, pgerror.Newf(pgcode.InvalidSchemaName,

pkg/sql/opt/xform/physical_props.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,3 +298,26 @@ func BuildChildPhysicalPropsScalar(mem *memo.Memo, parent opt.Expr, nth int) *ph
298298
}
299299
return mem.InternPhysicalProps(&childProps)
300300
}
301+
302+
func init() {
303+
memo.GetLookupJoinLookupTableDistribution = func(
304+
lookupJoin *memo.LookupJoinExpr,
305+
required *physical.Required,
306+
optimizer interface{},
307+
) (physicalDistribution physical.Distribution) {
308+
if optimizer == nil {
309+
return physicalDistribution
310+
}
311+
o, ok := optimizer.(*Optimizer)
312+
if !ok {
313+
return physicalDistribution
314+
}
315+
if o.evalCtx == nil {
316+
return physicalDistribution
317+
}
318+
_, physicalDistribution = distribution.BuildLookupJoinLookupTableDistribution(
319+
o.ctx, o.evalCtx, lookupJoin, required, o.MaybeGetBestCostRelation,
320+
)
321+
return physicalDistribution
322+
}
323+
}

pkg/sql/opt_catalog.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import (
3737
"github.com/cockroachdb/cockroach/pkg/sql/rowenc"
3838
"github.com/cockroachdb/cockroach/pkg/sql/sem/catconstants"
3939
"github.com/cockroachdb/cockroach/pkg/sql/sem/catid"
40+
"github.com/cockroachdb/cockroach/pkg/sql/sem/eval"
4041
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
4142
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree/treecmp"
4243
"github.com/cockroachdb/cockroach/pkg/sql/sqlerrors"
@@ -489,6 +490,15 @@ func (oc *optCatalog) RoleExists(ctx context.Context, role username.SQLUsername)
489490
return RoleExists(ctx, oc.planner.InternalSQLTxn(), role)
490491
}
491492

493+
// Optimizer is part of the cat.Catalog interface.
494+
func (oc *optCatalog) Optimizer() interface{} {
495+
if oc.planner == nil {
496+
return nil
497+
}
498+
plannerInterface := eval.Planner(oc.planner)
499+
return plannerInterface.Optimizer()
500+
}
501+
492502
// dataSourceForDesc returns a data source wrapper for the given descriptor.
493503
// The wrapper might come from the cache, or it may be created now.
494504
func (oc *optCatalog) dataSourceForDesc(

0 commit comments

Comments
 (0)