Skip to content

Commit

Permalink
sql: add statement.sql to EXPLAIN ANALYZE (DEBUG, REDACT)
Browse files Browse the repository at this point in the history
Support redaction of statement.sql, and add it back to redacted
statement diagnostics bundles.

Part of: cockroachdb#68570

Epic: CRDB-19756

Release note: None
  • Loading branch information
michae2 committed Jan 11, 2023
1 parent a100707 commit 780ade3
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 14 deletions.
37 changes: 25 additions & 12 deletions pkg/sql/explain_bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
"github.com/cockroachdb/cockroach/pkg/util/tracing"
"github.com/cockroachdb/cockroach/pkg/util/tracing/tracingpb"
"github.com/cockroachdb/errors"
"github.com/cockroachdb/redact"
)

const noPlan = "no plan"
Expand Down Expand Up @@ -208,35 +209,47 @@ func makeStmtBundleBuilder(
flags explain.Flags,
db *kv.DB,
ie *InternalExecutor,
stmt string,
stmtRawSQL string,
plan *planTop,
trace tracingpb.Recording,
placeholders *tree.PlaceholderInfo,
sv *settings.Values,
) stmtBundleBuilder {
b := stmtBundleBuilder{
flags: flags, db: db, ie: ie, stmt: stmt, plan: plan, trace: trace, placeholders: placeholders,
sv: sv,
flags: flags, db: db, ie: ie, plan: plan, trace: trace, placeholders: placeholders, sv: sv,
}
b.buildPrettyStatement()
b.buildPrettyStatement(stmtRawSQL)
b.z.Init()
return b
}

// buildPrettyStatement saves the pretty-printed statement (without any
// placeholder arguments).
func (b *stmtBundleBuilder) buildPrettyStatement() {
func (b *stmtBundleBuilder) buildPrettyStatement(stmtRawSQL string) {
// If we hit an early error, stmt or stmt.AST might not be initialized yet. In
// this case use the original statement SQL already in the stmtBundleBuilder.
if b.plan.stmt != nil && b.plan.stmt.AST != nil {
// this case use the original raw SQL.
if b.plan.stmt == nil || b.plan.stmt.AST == nil {
b.stmt = stmtRawSQL
// If we're collecting a redacted bundle, redact the raw SQL completely.
if b.flags.RedactValues && b.stmt != "" {
b.stmt = string(redact.RedactedMarker())
}
} else {
cfg := tree.DefaultPrettyCfg()
cfg.UseTabs = false
cfg.LineWidth = 100
cfg.TabWidth = 2
cfg.Simplify = true
cfg.Align = tree.PrettyNoAlign
cfg.JSONFmt = true
cfg.ValueRedaction = b.flags.RedactValues
b.stmt = cfg.Pretty(b.plan.stmt.AST)

// If we had ValueRedaction set, Pretty surrounded all constants with
// redaction markers. We must call Redact to fully redact them.
if b.flags.RedactValues {
b.stmt = string(redact.RedactableString(b.stmt).Redact())
}
}
if b.stmt == "" {
b.stmt = "-- no statement"
Expand All @@ -246,18 +259,18 @@ func (b *stmtBundleBuilder) buildPrettyStatement() {
// addStatement adds the pretty-printed statement in b.stmt as file
// statement.txt.
func (b *stmtBundleBuilder) addStatement() {
if b.flags.RedactValues {
return
}

output := b.stmt

if b.placeholders != nil && len(b.placeholders.Values) != 0 {
var buf bytes.Buffer
buf.WriteString(output)
buf.WriteString("\n\n-- Arguments:\n")
for i, v := range b.placeholders.Values {
fmt.Fprintf(&buf, "-- %s: %v\n", tree.PlaceholderIdx(i), v)
if b.flags.RedactValues {
fmt.Fprintf(&buf, "-- %s: %s\n", tree.PlaceholderIdx(i), redact.RedactedMarker())
} else {
fmt.Fprintf(&buf, "-- %s: %v\n", tree.PlaceholderIdx(i), v)
}
}
output = buf.String()
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/sql/explain_bundle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 vec.txt vec-v.txt",
}, "env.sql schema.sql statement.sql vec.txt vec-v.txt",
)
})
}
Expand Down
7 changes: 6 additions & 1 deletion pkg/sql/sem/tree/pretty.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ type PrettyCfg struct {
// JSONFmt, when set, pretty-prints strings that are asserted or cast
// to JSON.
JSONFmt bool
// ValueRedaction, when set, surrounds literal values with redaction markers.
ValueRedaction bool
}

// DefaultPrettyCfg returns a PrettyCfg with the default
Expand Down Expand Up @@ -177,7 +179,10 @@ func (p *PrettyCfg) Doc(f NodeFormatter) pretty.Doc {
}

func (p *PrettyCfg) docAsString(f NodeFormatter) pretty.Doc {
const prettyFlags = FmtShowPasswords | FmtParsable
prettyFlags := FmtShowPasswords | FmtParsable
if p.ValueRedaction {
prettyFlags |= FmtMarkRedactionNode | FmtOmitNameRedaction
}
txt := AsStringWithFlags(f, prettyFlags)
return pretty.Text(strings.TrimSpace(txt))
}
Expand Down

0 comments on commit 780ade3

Please sign in to comment.