Skip to content

Commit 60882cc

Browse files
committed
opt: improve outside-histogram optimizer tests
This commit makes the following improvements to the `outside-histogram` optimizer test: * Fixes a minor mistake in the test, where the upper bounds on a histogram for a unique column were incorrect. * Simplifies the test code for setting session variable defaults. * Adds comments explaining each test case. Epic: None Release note: None
1 parent 5e07f09 commit 60882cc

File tree

4 files changed

+114
-59
lines changed

4 files changed

+114
-59
lines changed

pkg/sql/opt/testutils/opttester/opt_tester.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,13 @@ func New(catalog cat.Catalog, sqlStr string) *OptTester {
568568
// - max-stack: sets the maximum stack size for the goroutine that optimizes
569569
// the query. See debug.SetMaxStack.
570570
func (ot *OptTester) RunCommand(tb testing.TB, d *datadriven.TestData) string {
571+
// Apply "session" defaults.
572+
ot.catalog.(*testcat.Catalog).ForEachSessionVar(func(name string, value string) {
573+
if err := sql.TestingSetSessionVariable(ot.ctx, ot.evalCtx, name, value); err != nil {
574+
panic(err)
575+
}
576+
})
577+
571578
// Allow testcases to override the flags.
572579
for _, a := range d.CmdArgs {
573580
if err := ot.Flags.Set(a); err != nil {

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

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,32 @@ import (
1111
"github.com/cockroachdb/errors"
1212
)
1313

14-
// SetVar implements the 'SET ...' SQL statement. Currently, it supports only
15-
// statements that set the current role (e.g., SET ROLE <user>).
14+
// SetVar implements the 'SET ...' SQL statement.
1615
func (tc *Catalog) SetVar(n *tree.SetVar) {
17-
if n.Name != "role" {
18-
panic(errors.Newf("SET only supports SET ROLE: %q", n.Name))
19-
}
2016
if len(n.Values) != 1 {
2117
panic(errors.Newf("Only support 1 value with SET"))
2218
}
2319
if n.ResetAll {
2420
panic(errors.Newf("RESET ALL is not supported with SET"))
2521
}
26-
newUser, err := username.MakeSQLUsernameFromUserInput(n.Values[0].String(), username.PurposeValidation)
27-
if err != nil {
28-
panic(err)
29-
}
30-
if _, found := tc.users[newUser]; !found {
31-
panic(errors.Newf("User %q does not exist", newUser.Normalized()))
22+
if n.Name == "role" {
23+
newUser, err := username.MakeSQLUsernameFromUserInput(n.Values[0].String(), username.PurposeValidation)
24+
if err != nil {
25+
panic(err)
26+
}
27+
if _, found := tc.users[newUser]; !found {
28+
panic(errors.Newf("User %q does not exist", newUser.Normalized()))
29+
}
30+
tc.currentUser = newUser
31+
} else if _, isReset := n.Values[0].(tree.DefaultVal); isReset {
32+
// "SET var = DEFAULT" means RESET.
33+
if tc.sessionVars != nil {
34+
delete(tc.sessionVars, n.Name)
35+
}
36+
} else {
37+
if tc.sessionVars == nil {
38+
tc.sessionVars = make(map[string]string)
39+
}
40+
tc.sessionVars[n.Name] = n.Values[0].String()
3241
}
33-
tc.currentUser = newUser
3442
}

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ type Catalog struct {
6060

6161
users map[username.SQLUsername]roleMembership
6262
currentUser username.SQLUsername
63+
64+
sessionVars map[string]string
6365
}
6466

6567
type roleMembership struct {
@@ -533,6 +535,14 @@ func (tc *Catalog) LeaseByStableID(ctx context.Context, id cat.StableID) (uint64
533535
return 1, nil
534536
}
535537

538+
// ForEachSessionVar applies the given function to the session variable
539+
// name-value pairs determined by previous SET statements.
540+
func (tc *Catalog) ForEachSessionVar(fn func(name string, value string)) {
541+
for k, v := range tc.sessionVars {
542+
fn(k, v)
543+
}
544+
}
545+
536546
// ExecuteMultipleDDL parses the given semicolon-separated DDL SQL statements
537547
// and applies each of them to the test catalog.
538548
func (tc *Catalog) ExecuteMultipleDDL(sql string) error {

pkg/sql/opt/xform/testdata/coster/outside-histogram

Lines changed: 77 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ ALTER TABLE t INJECT STATISTICS '[
2626
"histo_buckets": [
2727
{"num_eq": 0, "num_range": 0, "distinct_range": 0, "upper_bound": "0"},
2828
{"num_eq": 1, "num_range": 99, "distinct_range": 99, "upper_bound": "100"},
29-
{"num_eq": 1, "num_range": 199, "distinct_range": 199, "upper_bound": "200"},
30-
{"num_eq": 1, "num_range": 299, "distinct_range": 299, "upper_bound": "300"},
31-
{"num_eq": 1, "num_range": 399, "distinct_range": 399, "upper_bound": "400"}
29+
{"num_eq": 1, "num_range": 199, "distinct_range": 199, "upper_bound": "300"},
30+
{"num_eq": 1, "num_range": 299, "distinct_range": 299, "upper_bound": "600"},
31+
{"num_eq": 1, "num_range": 399, "distinct_range": 399, "upper_bound": "1000"}
3232
]
3333
},
3434
{
@@ -66,11 +66,26 @@ ALTER TABLE t INJECT STATISTICS '[
6666
]'
6767
----
6868

69-
# --------------------------------------------------
69+
exec-ddl
70+
SET optimizer_prefer_bounded_cardinality = false;
71+
----
72+
73+
exec-ddl
74+
SET optimizer_min_row_count = 0;
75+
----
76+
77+
exec-ddl
78+
SET enable_zigzag_join = false;
79+
----
80+
81+
# ------------------------------------------------------------------------------
7082
# Q1
71-
# --------------------------------------------------
83+
#
84+
# Choose between 4 single-row equality spans on "k" and a single unbounded
85+
# equality span on "i". The "i" span is outside the histogram range.
86+
# ------------------------------------------------------------------------------
7287

73-
opt set=(optimizer_prefer_bounded_cardinality=false,optimizer_min_row_count=0)
88+
opt
7489
SELECT * FROM t WHERE k IN (110, 120, 130, 140) AND i = 500
7590
----
7691
index-join t
@@ -99,7 +114,7 @@ index-join t
99114
├── key: (1)
100115
└── fd: ()-->(2)
101116

102-
opt set=(optimizer_prefer_bounded_cardinality=true,optimizer_min_row_count=0)
117+
opt set=optimizer_prefer_bounded_cardinality=true
103118
SELECT * FROM t WHERE k IN (110, 120, 130, 140) AND i = 500
104119
----
105120
index-join t
@@ -128,7 +143,7 @@ index-join t
128143
├── key: (1)
129144
└── fd: ()-->(2)
130145

131-
opt set=(optimizer_prefer_bounded_cardinality=false,optimizer_min_row_count=1)
146+
opt set=optimizer_min_row_count=1
132147
SELECT * FROM t WHERE k IN (110, 120, 130, 140) AND i = 500
133148
----
134149
select
@@ -158,11 +173,14 @@ select
158173
└── filters
159174
└── i:2 = 500 [outer=(2), constraints=(/2: [/500 - /500]; tight), fd=()-->(2)]
160175

161-
# --------------------------------------------------
176+
# ------------------------------------------------------------------------------
162177
# Q2
163-
# --------------------------------------------------
178+
#
179+
# Choose between 4 single-row equality spans on "k" and a single unbounded
180+
# inequality span on "i". The "i" span is outside the histogram range.
181+
# ------------------------------------------------------------------------------
164182

165-
opt set=(optimizer_prefer_bounded_cardinality=false,optimizer_min_row_count=0)
183+
opt
166184
SELECT * FROM t WHERE k IN (100, 110, 120, 130) AND i > 500
167185
----
168186
index-join t
@@ -189,15 +207,15 @@ index-join t
189207
│ ├── constraint: /2/1: [/501/100 - ]
190208
│ ├── stats: [rows=2e-07, distinct(1)=2e-07, null(1)=0, distinct(2)=2e-07, null(2)=0]
191209
│ │ histogram(1)= 0 0 1.98e-08 2e-10 3.98e-08 2e-10 5.98e-08 2e-10 7.98e-08 2e-10
192-
│ │ <--- 0 ---------- 100 ---------- 200 ---------- 300 ---------- 400
210+
│ │ <--- 0 ---------- 100 ---------- 300 ---------- 600 ---------- 1000
193211
│ │ histogram(2)=
194212
│ ├── cost: 18.0200002
195213
│ ├── key: (1)
196214
│ └── fd: (1)-->(2)
197215
└── filters
198216
└── k:1 IN (100, 110, 120, 130) [outer=(1), constraints=(/1: [/100 - /100] [/110 - /110] [/120 - /120] [/130 - /130]; tight)]
199217

200-
opt set=(optimizer_prefer_bounded_cardinality=true,optimizer_min_row_count=0)
218+
opt set=optimizer_prefer_bounded_cardinality=true
201219
SELECT * FROM t WHERE k IN (100, 110, 120, 130) AND i > 500
202220
----
203221
select
@@ -227,7 +245,7 @@ select
227245
└── filters
228246
└── i:2 > 500 [outer=(2), constraints=(/2: [/501 - ]; tight)]
229247

230-
opt set=(optimizer_prefer_bounded_cardinality=false,optimizer_min_row_count=1)
248+
opt set=optimizer_min_row_count=1
231249
SELECT * FROM t WHERE k IN (100, 110, 120, 130) AND i > 500
232250
----
233251
select
@@ -257,12 +275,15 @@ select
257275
└── filters
258276
└── i:2 > 500 [outer=(2), constraints=(/2: [/501 - ]; tight)]
259277

260-
# --------------------------------------------------
278+
# ------------------------------------------------------------------------------
261279
# Q3
262-
# --------------------------------------------------
280+
#
281+
# Choose between 3 single-row equality spans on "k" and a single unbounded
282+
# equality span on "i". The "i" and "k" spans are outside the histogram range.
283+
# ------------------------------------------------------------------------------
263284

264-
opt set=(optimizer_prefer_bounded_cardinality=false,optimizer_min_row_count=0)
265-
SELECT * FROM t WHERE k IN (410, 420, 430) AND i > 500
285+
opt
286+
SELECT * FROM t WHERE k IN (1010, 1020, 1030) AND i > 500
266287
----
267288
index-join t
268289
├── columns: k:1!null i:2!null s:3
@@ -283,19 +304,19 @@ index-join t
283304
├── fd: (1)-->(2)
284305
├── scan t@t_i_idx
285306
│ ├── columns: k:1!null i:2!null
286-
│ ├── constraint: /2/1: [/501/410 - ]
307+
│ ├── constraint: /2/1: [/501/1010 - ]
287308
│ ├── stats: [rows=2e-07, distinct(1)=2e-07, null(1)=0, distinct(2)=2e-07, null(2)=0]
288309
│ │ histogram(1)= 0 0 1.98e-08 2e-10 3.98e-08 2e-10 5.98e-08 2e-10 7.98e-08 2e-10
289-
│ │ <--- 0 ---------- 100 ---------- 200 ---------- 300 ---------- 400
310+
│ │ <--- 0 ---------- 100 ---------- 300 ---------- 600 ---------- 1000
290311
│ │ histogram(2)=
291312
│ ├── cost: 18.0200002
292313
│ ├── key: (1)
293314
│ └── fd: (1)-->(2)
294315
└── filters
295-
└── k:1 IN (410, 420, 430) [outer=(1), constraints=(/1: [/410 - /410] [/420 - /420] [/430 - /430]; tight)]
316+
└── k:1 IN (1010, 1020, 1030) [outer=(1), constraints=(/1: [/1010 - /1010] [/1020 - /1020] [/1030 - /1030]; tight)]
296317

297-
opt set=(optimizer_prefer_bounded_cardinality=true,optimizer_min_row_count=0)
298-
SELECT * FROM t WHERE k IN (410, 420, 430) AND i > 500
318+
opt set=optimizer_prefer_bounded_cardinality=true
319+
SELECT * FROM t WHERE k IN (1010, 1020, 1030) AND i > 500
299320
----
300321
select
301322
├── columns: k:1!null i:2!null s:3
@@ -309,9 +330,9 @@ select
309330
├── scan t
310331
│ ├── columns: k:1!null i:2 s:3
311332
│ ├── constraint: /1
312-
│ │ ├── [/410 - /410]
313-
│ │ ├── [/420 - /420]
314-
│ │ └── [/430 - /430]
333+
│ │ ├── [/1010 - /1010]
334+
│ │ ├── [/1020 - /1020]
335+
│ │ └── [/1030 - /1030]
315336
│ ├── cardinality: [0 - 3]
316337
│ ├── stats: [rows=2e-07, distinct(1)=2e-07, null(1)=0]
317338
│ │ histogram(1)=
@@ -321,8 +342,8 @@ select
321342
└── filters
322343
└── i:2 > 500 [outer=(2), constraints=(/2: [/501 - ]; tight)]
323344

324-
opt set=(optimizer_prefer_bounded_cardinality=false,optimizer_min_row_count=1)
325-
SELECT * FROM t WHERE k IN (410, 420, 430) AND i > 500
345+
opt set=optimizer_min_row_count=1
346+
SELECT * FROM t WHERE k IN (1010, 1020, 1030) AND i > 500
326347
----
327348
select
328349
├── columns: k:1!null i:2!null s:3
@@ -336,9 +357,9 @@ select
336357
├── scan t
337358
│ ├── columns: k:1!null i:2 s:3
338359
│ ├── constraint: /1
339-
│ │ ├── [/410 - /410]
340-
│ │ ├── [/420 - /420]
341-
│ │ └── [/430 - /430]
360+
│ │ ├── [/1010 - /1010]
361+
│ │ ├── [/1020 - /1020]
362+
│ │ └── [/1030 - /1030]
342363
│ ├── cardinality: [0 - 3]
343364
│ ├── stats: [rows=6e-07, distinct(1)=6e-07, null(1)=0]
344365
│ │ histogram(1)=
@@ -348,11 +369,14 @@ select
348369
└── filters
349370
└── i:2 > 500 [outer=(2), constraints=(/2: [/501 - ]; tight)]
350371

351-
# --------------------------------------------------
372+
# ------------------------------------------------------------------------------
352373
# Q4
353-
# --------------------------------------------------
374+
#
375+
# Choose between equality spans on "k" and "i", all inside the histogram, vs an
376+
# inequality span on "s", which falls outside the histogram.
377+
# ------------------------------------------------------------------------------
354378

355-
opt set=(optimizer_prefer_bounded_cardinality=false,optimizer_min_row_count=0)
379+
opt
356380
SELECT * FROM t WHERE k IN (100, 110, 120, 130) AND i = 400 AND s < 'apple'
357381
----
358382
select
@@ -388,7 +412,7 @@ select
388412
│ │ ├── constraint: /3/1: (/NULL - /'apple')
389413
│ │ ├── stats: [rows=2e-07, distinct(1)=2e-07, null(1)=0, distinct(3)=2e-07, null(3)=0]
390414
│ │ │ histogram(1)= 0 0 1.98e-08 2e-10 3.98e-08 2e-10 5.98e-08 2e-10 7.98e-08 2e-10
391-
│ │ │ <--- 0 ---------- 100 ---------- 200 ---------- 300 ---------- 400
415+
│ │ │ <--- 0 ---------- 100 ---------- 300 ---------- 600 ---------- 1000
392416
│ │ │ histogram(3)=
393417
│ │ ├── cost: 18.0200002
394418
│ │ ├── key: (1)
@@ -398,7 +422,7 @@ select
398422
└── filters
399423
└── i:2 = 400 [outer=(2), constraints=(/2: [/400 - /400]; tight), fd=()-->(2)]
400424

401-
opt set=(optimizer_prefer_bounded_cardinality=true,optimizer_min_row_count=0)
425+
opt set=optimizer_prefer_bounded_cardinality=true
402426
SELECT * FROM t WHERE k IN (100, 110, 120, 130) AND i = 400 AND s < 'apple'
403427
----
404428
select
@@ -431,7 +455,7 @@ select
431455
├── i:2 = 400 [outer=(2), constraints=(/2: [/400 - /400]; tight), fd=()-->(2)]
432456
└── s:3 < 'apple' [outer=(3), constraints=(/3: (/NULL - /'apple'); tight)]
433457

434-
opt set=(optimizer_prefer_bounded_cardinality=false,optimizer_min_row_count=1)
458+
opt set=optimizer_min_row_count=1
435459
SELECT * FROM t WHERE k IN (100, 110, 120, 130) AND i = 400 AND s < 'apple'
436460
----
437461
select
@@ -464,11 +488,14 @@ select
464488
├── i:2 = 400 [outer=(2), constraints=(/2: [/400 - /400]; tight), fd=()-->(2)]
465489
└── s:3 < 'apple' [outer=(3), constraints=(/3: (/NULL - /'apple'); tight)]
466490

467-
# --------------------------------------------------
491+
# ------------------------------------------------------------------------------
468492
# Q5
469-
# --------------------------------------------------
493+
#
494+
# Choose between an unbounded equality span on "i" inside the histogram vs an
495+
# inequality span on "s" outside its histogram.
496+
# ------------------------------------------------------------------------------
470497

471-
opt set=(enable_zigzag_join=false,optimizer_prefer_bounded_cardinality=false,optimizer_min_row_count=0)
498+
opt
472499
SELECT * FROM t WHERE i = 400 AND s > 'z'
473500
----
474501
select
@@ -497,7 +524,7 @@ select
497524
└── filters
498525
└── i:2 = 400 [outer=(2), constraints=(/2: [/400 - /400]; tight), fd=()-->(2)]
499526

500-
opt set=(enable_zigzag_join=false,optimizer_prefer_bounded_cardinality=true,optimizer_min_row_count=0)
527+
opt set=optimizer_prefer_bounded_cardinality=true
501528
SELECT * FROM t WHERE i = 400 AND s > 'z'
502529
----
503530
select
@@ -529,7 +556,7 @@ select
529556
└── filters
530557
└── i:2 = 400 [outer=(2), constraints=(/2: [/400 - /400]; tight), fd=()-->(2)]
531558

532-
opt set=(enable_zigzag_join=false,optimizer_prefer_bounded_cardinality=false,optimizer_min_row_count=1)
559+
opt set=optimizer_min_row_count=1
533560
SELECT * FROM t WHERE i = 400 AND s > 'z'
534561
----
535562
select
@@ -558,11 +585,14 @@ select
558585
└── filters
559586
└── i:2 = 400 [outer=(2), constraints=(/2: [/400 - /400]; tight), fd=()-->(2)]
560587

561-
# --------------------------------------------------
588+
# ------------------------------------------------------------------------------
562589
# Q6
563-
# --------------------------------------------------
590+
#
591+
# Choose between equality spans on "k", "i", and "s". The "k" span is inside the
592+
# histogram, while the "i" and "s" spans are outside their histograms.
593+
# ------------------------------------------------------------------------------
564594

565-
opt set=(optimizer_prefer_bounded_cardinality=false,optimizer_min_row_count=0)
595+
opt
566596
SELECT * FROM t WHERE k = 100 AND i = 500 AND s = 'zzz'
567597
----
568598
select
@@ -597,7 +627,7 @@ select
597627
└── filters
598628
└── s:3 = 'zzz' [outer=(3), constraints=(/3: [/'zzz' - /'zzz']; tight), fd=()-->(3)]
599629

600-
opt set=(optimizer_prefer_bounded_cardinality=true,optimizer_min_row_count=0)
630+
opt set=optimizer_prefer_bounded_cardinality=true
601631
SELECT * FROM t WHERE k = 100 AND i = 500 AND s = 'zzz'
602632
----
603633
select
@@ -632,7 +662,7 @@ select
632662
└── filters
633663
└── s:3 = 'zzz' [outer=(3), constraints=(/3: [/'zzz' - /'zzz']; tight), fd=()-->(3)]
634664

635-
opt set=(optimizer_prefer_bounded_cardinality=false,optimizer_min_row_count=1)
665+
opt set=optimizer_min_row_count=1
636666
SELECT * FROM t WHERE k = 100 AND i = 500 AND s = 'zzz'
637667
----
638668
select

0 commit comments

Comments
 (0)