Skip to content

Commit ae57ae0

Browse files
committed
sql/inspect: add placeholder values to logged queries
Previously, INSPECT only logged the query text without placeholder values in issue reports, making debugging more difficult. This change includes the actual placeholder values in the logged query output. This also addes a test for INSPECT and LTREE[] handling. Informs: #155483 Epic: CRDB-55075 Release note: none
1 parent 0c296a5 commit ae57ae0

File tree

2 files changed

+76
-1
lines changed

2 files changed

+76
-1
lines changed

pkg/sql/inspect/index_consistency_check.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ type indexConsistencyCheck struct {
9696
// lastQuery stores the SQL query executed for this check to help
9797
// debug internal errors by providing context about the span bounds.
9898
lastQuery string
99+
100+
// lastQueryPlaceholders stores the placeholder values used in lastQuery.
101+
lastQueryPlaceholders []interface{}
99102
}
100103

101104
var _ inspectCheck = (*indexConsistencyCheck)(nil)
@@ -272,8 +275,9 @@ func (c *indexConsistencyCheck) Start(
272275
// Wrap the query with AS OF SYSTEM TIME to ensure it uses the specified timestamp
273276
queryWithAsOf := fmt.Sprintf("SELECT * FROM (%s) AS OF SYSTEM TIME %s", checkQuery, c.asOf.AsOfSystemTime())
274277

275-
// Store the query for error reporting
278+
// Store the query and placeholders for error reporting.
276279
c.lastQuery = queryWithAsOf
280+
c.lastQueryPlaceholders = queryArgs
277281

278282
// Execute the query with AS OF SYSTEM TIME embedded in the SQL
279283
qos := getInspectQoS(&c.flowCtx.Cfg.Settings.SV)
@@ -327,6 +331,7 @@ func (c *indexConsistencyCheck) Next(
327331
details["error_type"] = "internal_query_error"
328332
details["index_name"] = c.secIndex.GetName()
329333
details["query"] = c.lastQuery // Store the query that caused the error
334+
details["query_placeholders"] = formatPlaceholders(c.lastQueryPlaceholders)
330335

331336
return &inspectIssue{
332337
ErrorType: InternalError,
@@ -391,6 +396,7 @@ func (c *indexConsistencyCheck) Next(
391396
details := make(map[redact.RedactableString]interface{})
392397
details["row_data"] = extractRowData(c.rowIter.Cur(), c.columns, dataStartIdx)
393398
details["index_name"] = c.secIndex.GetName()
399+
details["query_placeholders"] = formatPlaceholders(c.lastQueryPlaceholders)
394400

395401
return &inspectIssue{
396402
ErrorType: errorType,
@@ -920,3 +926,16 @@ func isQueryConstructionError(err error) bool {
920926
return false
921927
}
922928
}
929+
930+
// formatPlaceholders converts query placeholder values to a string slice for JSON serialization.
931+
func formatPlaceholders(placeholders []interface{}) []string {
932+
result := make([]string, len(placeholders))
933+
for i, placeholder := range placeholders {
934+
if datum, ok := placeholder.(tree.Datum); ok {
935+
result[i] = tree.AsStringWithFlags(datum, tree.FmtParsable)
936+
} else {
937+
result[i] = fmt.Sprintf("%v", placeholder)
938+
}
939+
}
940+
return result
941+
}

pkg/sql/logictest/testdata/logic_test/distsql_inspect

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@ subtest setup
55
statement ok
66
SET enable_scrub_job = true;
77

8+
statement ok
9+
SET enable_inspect_command = true;
10+
11+
statement ok
12+
CREATE VIEW last_inspect_job AS
13+
SELECT status, COALESCE(jsonb_array_length(
14+
crdb_internal.pb_to_json('cockroach.sql.jobs.jobspb.Payload', payload)->'inspectDetails'->'checks'
15+
), 0) AS num_checks
16+
FROM crdb_internal.system_jobs
17+
WHERE job_type = 'INSPECT'
18+
ORDER BY created DESC
19+
LIMIT 1
20+
821
statement ok
922
CREATE TABLE data (a INT, b INT, c FLOAT, d DECIMAL, e BOOL, PRIMARY KEY (a, b, c, d), INDEX c_idx (c, d))
1023

@@ -56,6 +69,49 @@ EXPERIMENTAL SCRUB TABLE data AS OF SYSTEM TIME '-1us' succeeded true
5669

5770
subtest end
5871

72+
subtest ltree_array_pk_column
73+
74+
statement ok
75+
CREATE TABLE table_ltree_array_leading (
76+
pk_ltree_array LTREE[] NOT NULL,
77+
pk_name NAME NOT NULL,
78+
val INT,
79+
PRIMARY KEY (pk_ltree_array, pk_name),
80+
INDEX idx_val (val)
81+
);
82+
83+
statement ok
84+
INSERT INTO table_ltree_array_leading VALUES
85+
(ARRAY['a.b.c']::LTREE[], 'key1', 1),
86+
(ARRAY['d.e.f']::LTREE[], 'key2', 2),
87+
(ARRAY['g.h.i']::LTREE[], 'key3', 3),
88+
(ARRAY['j.k.l']::LTREE[], 'key4', 4),
89+
(ARRAY['m.n.o']::LTREE[], 'key5', 5),
90+
(ARRAY['p.q.r']::LTREE[], 'key6', 6);
91+
92+
# Split the table into multiple ranges to force distributed INSPECT queries.
93+
statement ok
94+
ALTER TABLE table_ltree_array_leading SPLIT AT VALUES (ARRAY['d.e.f']::LTREE[], 'key2');
95+
96+
statement ok
97+
ALTER TABLE table_ltree_array_leading SPLIT AT VALUES (ARRAY['j.k.l']::LTREE[], 'key4');
98+
99+
statement ok
100+
ALTER TABLE table_ltree_array_leading SCATTER;
101+
102+
statement ok
103+
INSPECT TABLE table_ltree_array_leading;
104+
105+
query TI
106+
SELECT * FROM last_inspect_job;
107+
----
108+
succeeded 1
109+
110+
statement ok
111+
DROP TABLE table_ltree_array_leading;
112+
113+
subtest end
114+
59115
subtest cleanup
60116

61117
statement ok

0 commit comments

Comments
 (0)