Skip to content

Commit 2c91cda

Browse files
committed
sql: fix statement bundle creation when memo isn't detached
When a memo is deemed not resuable we don't detach it from the factory and this causes problems later when we execute SetIndexRecommendations which resets the optimizer context which will reset the memo. This causes the schema.sql and opt*.txt files to be empty. Fixes: #92920 Release note: None
1 parent ae37120 commit 2c91cda

File tree

4 files changed

+28
-4
lines changed

4 files changed

+28
-4
lines changed

pkg/sql/explain_bundle.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ import (
3636
"github.com/cockroachdb/errors"
3737
)
3838

39+
const noPlan = "no plan"
40+
3941
// setExplainBundleResult sets the result of an EXPLAIN ANALYZE (DEBUG)
4042
// statement. warnings will be printed out as is in the CLI.
4143
//
@@ -242,9 +244,9 @@ func (b *stmtBundleBuilder) addStatement() {
242244
func (b *stmtBundleBuilder) addOptPlans(ctx context.Context) {
243245
if b.plan.mem == nil || b.plan.mem.RootExpr() == nil {
244246
// No optimizer plans; an error must have occurred during planning.
245-
b.z.AddFile("opt.txt", "no plan")
246-
b.z.AddFile("opt-v.txt", "no plan")
247-
b.z.AddFile("opt-vv.txt", "no plan")
247+
b.z.AddFile("opt.txt", noPlan)
248+
b.z.AddFile("opt-v.txt", noPlan)
249+
b.z.AddFile("opt-vv.txt", noPlan)
248250
return
249251
}
250252

pkg/sql/explain_bundle_test.go

+13
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,19 @@ CREATE TABLE s.a (a INT PRIMARY KEY);`)
101101
checkBundle(t, fmt.Sprintf("%+v", pqErr.Detail), "", nil, base, plans, "distsql.html")
102102
})
103103

104+
// #92920 Make sure schema and opt files are created.
105+
t.Run("memo-reset", func(t *testing.T) {
106+
rows := r.QueryStr(t, "EXPLAIN ANALYZE (DEBUG) CREATE TABLE t (i int)")
107+
checkBundle(t, fmt.Sprint(rows), "", func(name, contents string) error {
108+
if name == "opt.txt" {
109+
if contents == noPlan {
110+
return errors.Errorf("opt.txt empty")
111+
}
112+
}
113+
return nil
114+
}, base, plans, "distsql.html vec.txt vec-v.txt")
115+
})
116+
104117
// Verify that we can issue the statement with prepare (which can happen
105118
// depending on the client).
106119
t.Run("prepare", func(t *testing.T) {

pkg/sql/opt/norm/factory.go

+9
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,15 @@ func (f *Factory) DetachMemo() *memo.Memo {
170170
return m
171171
}
172172

173+
// ReleaseMemo is just like DetachMemo but it doesn't call Detach on the memo
174+
// preserving any statistics information for explain purposes (distinct, null
175+
// count etc).
176+
func (f *Factory) ReleaseMemo() *memo.Memo {
177+
m := f.mem
178+
f.mem = nil
179+
return m
180+
}
181+
173182
// DisableOptimizations disables all transformation rules. The unaltered input
174183
// expression tree becomes the output expression tree (because no transforms
175184
// are applied).

pkg/sql/plan_opt.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,7 @@ func (opc *optPlanningCtx) buildExecMemo(ctx context.Context) (_ *memo.Memo, _ e
601601
return memo, nil
602602
}
603603

604-
return f.Memo(), nil
604+
return f.ReleaseMemo(), nil
605605
}
606606

607607
// runExecBuilder execbuilds a plan using the given factory and stores the

0 commit comments

Comments
 (0)