diff --git a/pkg/sql/explain_bundle.go b/pkg/sql/explain_bundle.go index 17cf5110b111..7b7dabe49ffb 100644 --- a/pkg/sql/explain_bundle.go +++ b/pkg/sql/explain_bundle.go @@ -310,10 +310,6 @@ func (b *stmtBundleBuilder) addOptPlans(ctx context.Context) { // addExecPlan adds the EXPLAIN (VERBOSE) plan as file plan.txt. func (b *stmtBundleBuilder) addExecPlan(plan string) { - if b.flags.RedactValues { - return - } - if plan == "" { plan = "no plan" } diff --git a/pkg/sql/explain_bundle_test.go b/pkg/sql/explain_bundle_test.go index def6f00c2618..b29ef30385fb 100644 --- a/pkg/sql/explain_bundle_test.go +++ b/pkg/sql/explain_bundle_test.go @@ -300,7 +300,7 @@ CREATE TABLE users(id UUID DEFAULT gen_random_uuid() PRIMARY KEY, promo_id INT R } } return nil - }, "env.sql schema.sql statement.sql vec.txt vec-v.txt", + }, "env.sql plan.txt schema.sql statement.sql vec-v.txt vec.txt", ) }) } diff --git a/pkg/sql/opt/exec/explain/BUILD.bazel b/pkg/sql/opt/exec/explain/BUILD.bazel index c642c53ae436..8f1f9d1b98ad 100644 --- a/pkg/sql/opt/exec/explain/BUILD.bazel +++ b/pkg/sql/opt/exec/explain/BUILD.bazel @@ -39,6 +39,7 @@ go_library( "//pkg/util/timeutil", "//pkg/util/treeprinter", "@com_github_cockroachdb_errors//:errors", + "@com_github_cockroachdb_redact//:redact", "@com_github_dustin_go_humanize//:go-humanize", ], ) diff --git a/pkg/sql/opt/exec/explain/emit.go b/pkg/sql/opt/exec/explain/emit.go index e9f0b1517f35..90c1a8241976 100644 --- a/pkg/sql/opt/exec/explain/emit.go +++ b/pkg/sql/opt/exec/explain/emit.go @@ -76,7 +76,14 @@ func Emit(plan *Plan, ob *OutputBuilder, spanFormatFn SpanFormatFn) error { // This field contains the original subquery (which could have been modified // by optimizer transformations). if s.ExprNode != nil { - ob.Attr("original sql", tree.AsStringWithFlags(s.ExprNode, tree.FmtSimple)) + flags := tree.FmtSimple + if e.ob.flags.HideValues { + flags |= tree.FmtHideConstants + } + if e.ob.flags.RedactValues { + flags |= tree.FmtMarkRedactionNode | tree.FmtOmitNameRedaction + } + ob.Attr("original sql", tree.AsStringWithFlags(s.ExprNode, flags)) } var mode string switch s.Mode { @@ -1006,7 +1013,8 @@ func (e *emitter) spansStr(table cat.Table, index cat.Index, scanParams exec.Sca } // In verbose mode show the physical spans, unless the table is virtual. - if e.ob.flags.Verbose && !table.IsVirtualTable() { + if e.ob.flags.Verbose && !e.ob.flags.HideValues && !e.ob.flags.RedactValues && + !table.IsVirtualTable() { return e.spanFormatFn(table, index, scanParams) } @@ -1017,8 +1025,8 @@ func (e *emitter) spansStr(table cat.Table, index cat.Index, scanParams exec.Sca return fmt.Sprintf("%d span%s", n, util.Pluralize(int64(n))) } - // If we must hide values, only show the count. - if e.ob.flags.HideValues { + // If we must hide or redact values, only show the count. + if e.ob.flags.HideValues || e.ob.flags.RedactValues { n := scanParams.IndexConstraint.Spans.Count() return fmt.Sprintf("%d span%s", n, util.Pluralize(int64(n))) } diff --git a/pkg/sql/opt/exec/explain/output.go b/pkg/sql/opt/exec/explain/output.go index fbbfc7ada45e..8466f867ce91 100644 --- a/pkg/sql/opt/exec/explain/output.go +++ b/pkg/sql/opt/exec/explain/output.go @@ -22,6 +22,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/util/humanizeutil" "github.com/cockroachdb/cockroach/pkg/util/treeprinter" "github.com/cockroachdb/errors" + "github.com/cockroachdb/redact" ) // OutputBuilder is used to build the output of an explain tree. @@ -148,6 +149,9 @@ func (ob *OutputBuilder) Expr(key string, expr tree.TypedExpr, varColumns colinf if ob.flags.HideValues { flags |= tree.FmtHideConstants } + if ob.flags.RedactValues { + flags |= tree.FmtMarkRedactionNode | tree.FmtOmitNameRedaction + } f := tree.NewFmtCtx( flags, tree.FmtIndexedVarFormat(func(ctx *tree.FmtCtx, idx int) { @@ -210,7 +214,11 @@ func (ob *OutputBuilder) BuildStringRows() []string { } // Add any fields for the node. for entry = popField(); entry != nil; entry = popField() { - child.AddLine(entry.fieldStr()) + field := entry.fieldStr() + if ob.flags.RedactValues { + field = string(redact.RedactableString(field).Redact()) + } + child.AddLine(field) } } result = append(result, tp.FormattedRows()...) diff --git a/pkg/sql/sem/tree/explain.go b/pkg/sql/sem/tree/explain.go index ac04e2026c16..f841bf053f16 100644 --- a/pkg/sql/sem/tree/explain.go +++ b/pkg/sql/sem/tree/explain.go @@ -264,10 +264,14 @@ func MakeExplain(options []string, stmt Statement) (Statement, error) { } if opts.Flags[ExplainFlagRedact] { - // TODO(michae2): Support redaction of other EXPLAIN variants. - if !analyze || opts.Mode != ExplainDebug { - return nil, unimplemented.New( - "EXPLAIN (REDACT)", "the REDACT flag can only be used with EXPLAIN ANALYZE (DEBUG)", + // TODO(michae2): Support redaction of other EXPLAIN modes. + switch opts.Mode { + case ExplainPlan: + case ExplainVec: + case ExplainDebug: + default: + return nil, unimplemented.Newf( + "EXPLAIN (REDACT)", "the REDACT flag cannot be used with %s", opts.Mode, ) } }