Skip to content

Commit 5845a15

Browse files
craig[bot]RaduBerinde
andcommitted
Merge #27102
27102: opt: minor optsteps cleanup r=RaduBerinde a=RaduBerinde Separating the display code from the logic to determine the before and after expressions. Release note: None Co-authored-by: Radu Berinde <radu@cockroachlabs.com>
2 parents e3eb6e0 + 2c62e19 commit 5845a15

File tree

1 file changed

+82
-66
lines changed

1 file changed

+82
-66
lines changed

pkg/sql/opt/testutils/opt_tester.go

Lines changed: 82 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,8 @@ func fillInLazyProps(ev memo.ExprView) {
212212
}
213213
}
214214

215-
// Set parses an argument that refers to a flag. See OptTester.Handle for
216-
// supported flags.
215+
// Set parses an argument that refers to a flag.
216+
// See OptTester.RunCommand for supported flags.
217217
func (f *OptTesterFlags) Set(arg datadriven.CmdArg) error {
218218
switch arg.Key {
219219
case "format":
@@ -309,11 +309,54 @@ func (ot *OptTester) Memo() (string, error) {
309309
func (ot *OptTester) OptSteps() (string, error) {
310310
var buf bytes.Buffer
311311
var prevBest, prev, next string
312-
if ot.Flags.Verbose {
313-
fmt.Print("------ optsteps verbose output starts ------\n")
312+
313+
os := newOptSteps(ot)
314+
for {
315+
err := os.next()
316+
if err != nil {
317+
return "", err
318+
}
319+
320+
next = os.exprView().FormatString(ot.Flags.ExprFormat)
321+
322+
// This call comes after setting "next", because we want to output the
323+
// final expression, even though there were no diffs from the previous
324+
// iteration.
325+
if os.done() {
326+
break
327+
}
328+
329+
if prev == "" {
330+
// Output starting tree.
331+
ot.optStepsDisplay(&buf, "", next, os)
332+
prevBest = next
333+
} else if next == prev || next == prevBest {
334+
ot.optStepsDisplay(&buf, next, next, os)
335+
} else if os.isBetter() {
336+
// New expression is better than the previous expression. Diff
337+
// it against the previous *best* expression (might not be the
338+
// previous expression).
339+
ot.optStepsDisplay(&buf, prevBest, next, os)
340+
prevBest = next
341+
} else {
342+
// New expression is not better than the previous expression, but
343+
// still show the change. Diff it against the previous expression,
344+
// regardless if it was a "best" expression or not.
345+
ot.optStepsDisplay(&buf, prev, next, os)
346+
}
347+
348+
prev = next
314349
}
350+
351+
// Output ending tree.
352+
ot.optStepsDisplay(&buf, next, "", os)
353+
354+
return buf.String(), nil
355+
}
356+
357+
func (ot *OptTester) optStepsDisplay(buf *bytes.Buffer, before string, after string, os *optSteps) {
315358
output := func(format string, args ...interface{}) {
316-
fmt.Fprintf(&buf, format, args...)
359+
fmt.Fprintf(buf, format, args...)
317360
if ot.Flags.Verbose {
318361
fmt.Printf(format, args...)
319362
}
@@ -343,76 +386,49 @@ func (ot *OptTester) OptSteps() (string, error) {
343386
output("%s\n", strings.Repeat("-", 80))
344387
}
345388

346-
os := newOptSteps(ot)
347-
for {
348-
err := os.next()
349-
if err != nil {
350-
return "", err
389+
if before == "" {
390+
if ot.Flags.Verbose {
391+
fmt.Print("------ optsteps verbose output starts ------\n")
351392
}
393+
bestHeader(os.exprView(), "Initial expression\n")
394+
indent(after)
395+
return
396+
}
352397

353-
next = os.exprView().FormatString(ot.Flags.ExprFormat)
354-
355-
// This call comes after setting "next", because we want to output the
356-
// final expression, even though there were no diffs from the previous
357-
// iteration.
358-
if os.done() {
359-
break
360-
}
398+
if before == after {
399+
altHeader("%s (no changes)\n", os.lastRuleName())
400+
return
401+
}
361402

362-
if prev == "" {
363-
// Output starting tree.
364-
bestHeader(os.exprView(), "Initial expression\n")
365-
indent(next)
366-
prevBest = next
367-
} else if next == prev || next == prevBest {
368-
altHeader("%s (no changes)\n", os.lastRuleName())
369-
} else {
370-
var diff difflib.UnifiedDiff
371-
if os.isBetter() {
372-
// New expression is better than the previous expression. Diff
373-
// it against the previous *best* expression (might not be the
374-
// previous expression).
375-
bestHeader(os.exprView(), "%s\n", os.lastRuleName())
376-
377-
diff = difflib.UnifiedDiff{
378-
A: difflib.SplitLines(prevBest),
379-
B: difflib.SplitLines(next),
380-
Context: 100,
381-
}
382-
383-
prevBest = next
384-
} else {
385-
// New expression is not better than the previous expression, but
386-
// still show the change. Diff it against the previous expression,
387-
// regardless if it was a "best" expression or not.
388-
altHeader("%s (higher cost)\n", os.lastRuleName())
389-
390-
next = os.exprView().FormatString(ot.Flags.ExprFormat)
391-
diff = difflib.UnifiedDiff{
392-
A: difflib.SplitLines(prev),
393-
B: difflib.SplitLines(next),
394-
Context: 100,
395-
}
396-
}
403+
if after == "" {
404+
bestHeader(os.exprView(), "Final best expression\n")
405+
indent(before)
397406

398-
text, _ := difflib.GetUnifiedDiffString(diff)
399-
// Skip the "@@ ... @@" header (first line).
400-
text = strings.SplitN(text, "\n", 2)[1]
401-
indent(text)
407+
if ot.Flags.Verbose {
408+
fmt.Print("------ optsteps verbose output ends ------\n")
402409
}
403-
404-
prev = next
410+
return
405411
}
406412

407-
// Output ending tree.
408-
bestHeader(os.exprView(), "Final best expression\n")
409-
indent(next)
410-
411-
if ot.Flags.Verbose {
412-
fmt.Print("------ optsteps verbose output ends ------\n")
413+
var diff difflib.UnifiedDiff
414+
if os.isBetter() {
415+
// New expression is better than the previous expression. Diff
416+
// it against the previous *best* expression (might not be the
417+
// previous expression).
418+
bestHeader(os.exprView(), "%s\n", os.lastRuleName())
419+
} else {
420+
altHeader("%s (higher cost)\n", os.lastRuleName())
413421
}
414422

415-
return buf.String(), nil
423+
diff = difflib.UnifiedDiff{
424+
A: difflib.SplitLines(before),
425+
B: difflib.SplitLines(after),
426+
Context: 100,
427+
}
428+
text, _ := difflib.GetUnifiedDiffString(diff)
429+
// Skip the "@@ ... @@" header (first line).
430+
text = strings.SplitN(text, "\n", 2)[1]
431+
indent(text)
416432
}
417433

418434
func (ot *OptTester) buildExpr(

0 commit comments

Comments
 (0)