Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
118424: opt: add normsteps and normstepsweb commands to opttester r=mgartner a=mgartner

See the changes to the opttester's documentation for details.

Epic: None

Release note: None

Co-authored-by: Marcus Gartner <[email protected]>
  • Loading branch information
craig[bot] and mgartner committed Jan 29, 2024
2 parents a68bc94 + 520b008 commit 826569e
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 7 deletions.
47 changes: 40 additions & 7 deletions pkg/sql/opt/testutils/opttester/opt_tester.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,10 +370,18 @@ func New(catalog cat.Catalog, sql string) *OptTester {
// Outputs the lowest cost tree for each step in optimization using the
// standard unified diff format. Used for debugging the optimizer.
//
// - normsteps [flags]
//
// Similar to optsteps, but only runs normalization rules.
//
// - optstepsweb [flags]
//
// Similar to optsteps, but outputs a URL which displays the results.
//
// - normstepsweb [flags]
//
// Similar to optstepsweb, but only runs normalization rules.
//
// - exploretrace [flags]
//
// Outputs information about exploration rule application. Used for debugging
Expand Down Expand Up @@ -725,14 +733,28 @@ func (ot *OptTester) RunCommand(tb testing.TB, d *datadriven.TestData) string {
return tp.String()

case "optsteps":
result, err := ot.OptSteps()
result, err := ot.OptSteps(true /* explore */)
if err != nil {
d.Fatalf(tb, "%+v", err)
}
return result

case "normsteps":
result, err := ot.OptSteps(false /* explore */)
if err != nil {
d.Fatalf(tb, "%+v", err)
}
return result

case "optstepsweb":
result, err := ot.OptStepsWeb()
result, err := ot.OptStepsWeb(true /* explore */)
if err != nil {
d.Fatalf(tb, "%+v", err)
}
return result

case "normstepsweb":
result, err := ot.OptStepsWeb(false /* explore */)
if err != nil {
d.Fatalf(tb, "%+v", err)
}
Expand Down Expand Up @@ -1492,7 +1514,7 @@ func (ot *OptTester) RuleStats() (string, error) {
// a better plan has been found, and weaker "----" header delimiters when not.
// In both cases, the output shows the expressions that were changed or added by
// the rule, even if the total expression tree cost worsened.
func (ot *OptTester) OptSteps() (string, error) {
func (ot *OptTester) OptSteps(explore bool) (string, error) {
var prevBest, prev, next string
ot.builder.Reset()

Expand All @@ -1512,6 +1534,14 @@ func (ot *OptTester) OptSteps() (string, error) {
break
}

if !explore {
rule := os.LastRuleName()
if rule.IsExplore() {
// Stop at the first exploration rule.
break
}
}

if prev == "" {
// Output starting tree.
ot.optStepsDisplay("", next, os)
Expand Down Expand Up @@ -1543,15 +1573,18 @@ func (ot *OptTester) OptSteps() (string, error) {
// OptStepsWeb is similar to Optsteps but it uses a special web page for
// formatting the output. The result will be an URL which contains the encoded
// data.
func (ot *OptTester) OptStepsWeb() (string, error) {
func (ot *OptTester) OptStepsWeb(explore bool) (string, error) {
normDiffStr, err := ot.optStepsNormDiff()
if err != nil {
return "", err
}

exploreDiffStr, err := ot.optStepsExploreDiff()
if err != nil {
return "", err
var exploreDiffStr string
if explore {
exploreDiffStr, err = ot.optStepsExploreDiff()
if err != nil {
return "", err
}
}
url, err := ot.encodeOptstepsURL(normDiffStr, exploreDiffStr)
if err != nil {
Expand Down
93 changes: 93 additions & 0 deletions pkg/sql/opt/testutils/opttester/testdata/opt-steps
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,99 @@ Final best expression
├── key: (1)
└── fd: ()-->(2)

normsteps
SELECT * FROM ab WHERE b=1
----
================================================================================
Initial expression
Cost: 1098.77
================================================================================
project
├── columns: a:1(int!null) b:2(int!null)
├── key: (1)
├── fd: ()-->(2)
└── select
├── columns: a:1(int!null) b:2(int!null) crdb_internal_mvcc_timestamp:3(decimal) tableoid:4(oid)
├── key: (1)
├── fd: ()-->(2), (1)-->(3,4)
├── scan ab
│ ├── columns: a:1(int!null) b:2(int) crdb_internal_mvcc_timestamp:3(decimal) tableoid:4(oid)
│ ├── key: (1)
│ └── fd: (1)-->(2-4)
└── filters
└── eq [type=bool, outer=(2), constraints=(/2: [/1 - /1]; tight), fd=()-->(2)]
├── variable: b:2 [type=int]
└── const: 1 [type=int]
================================================================================
PruneSelectCols
Cost: 1078.57
================================================================================
project
├── columns: a:1(int!null) b:2(int!null)
├── key: (1)
├── fd: ()-->(2)
└── select
- ├── columns: a:1(int!null) b:2(int!null) crdb_internal_mvcc_timestamp:3(decimal) tableoid:4(oid)
+ ├── columns: a:1(int!null) b:2(int!null)
├── key: (1)
- ├── fd: ()-->(2), (1)-->(3,4)
+ ├── fd: ()-->(2)
├── scan ab
- │ ├── columns: a:1(int!null) b:2(int) crdb_internal_mvcc_timestamp:3(decimal) tableoid:4(oid)
+ │ ├── columns: a:1(int!null) b:2(int)
│ ├── key: (1)
- │ └── fd: (1)-->(2-4)
+ │ └── fd: (1)-->(2)
└── filters
└── eq [type=bool, outer=(2), constraints=(/2: [/1 - /1]; tight), fd=()-->(2)]
├── variable: b:2 [type=int]
└── const: 1 [type=int]
================================================================================
EliminateProject
Cost: 1078.45
================================================================================
-project
+select
├── columns: a:1(int!null) b:2(int!null)
├── key: (1)
├── fd: ()-->(2)
- └── select
- ├── columns: a:1(int!null) b:2(int!null)
- ├── key: (1)
- ├── fd: ()-->(2)
- ├── scan ab
- │ ├── columns: a:1(int!null) b:2(int)
- │ ├── key: (1)
- │ └── fd: (1)-->(2)
- └── filters
- └── eq [type=bool, outer=(2), constraints=(/2: [/1 - /1]; tight), fd=()-->(2)]
- ├── variable: b:2 [type=int]
- └── const: 1 [type=int]
+ ├── scan ab
+ │ ├── columns: a:1(int!null) b:2(int)
+ │ ├── key: (1)
+ │ └── fd: (1)-->(2)
+ └── filters
+ └── eq [type=bool, outer=(2), constraints=(/2: [/1 - /1]; tight), fd=()-->(2)]
+ ├── variable: b:2 [type=int]
+ └── const: 1 [type=int]
================================================================================
Final best expression
Cost: 1078.45
================================================================================
select
├── columns: a:1(int!null) b:2(int!null)
├── key: (1)
├── fd: ()-->(2)
├── scan ab@ab_b_idx
│ ├── columns: a:1(int!null) b:2(int)
│ ├── key: (1)
│ └── fd: (1)-->(2)
└── filters
└── eq [type=bool, outer=(2), constraints=(/2: [/1 - /1]; tight), fd=()-->(2)]
├── variable: b:2 [type=int]
└── const: 1 [type=int]

exec-ddl
CREATE TABLE customers (
id INT8 NOT NULL,
Expand Down

0 comments on commit 826569e

Please sign in to comment.