Skip to content

Commit 8fc2e3d

Browse files
committed
explain: shorten some extremely long lines
I just saw a bundle with an ANY clause with a tuple that had 10k elements. As of 4c77e2a, we shortened the tuple itself to not pollute `plan.txt` too much, but the type declaration still had the word "string" printed 10k times. This is the case when explicit `TYPES` format of EXPLAIN is requested, or when the bundle collected via EXPLAIN ANALYZE (DEBUG) (in which case we always request the `TYPES` flag). This commit applies the same shortening logic to the type string as we did in the change mentioned above - if `FmtShortenConstants` flag is set, then only the first two and the last tuple elements are printed, reducing the redundant information (chances are all elements within the tuple are of the same type anyway). When `VERBOSE` option is set, we show physical spans via `SpanFormatFn`. This function could be called for Scan, Vector Search, and Delete Range operators. Unlike in non-verbose case (where we only print the first 4 logical spans), previously we would print any number of physical plans in the verbose mode. In the same bundle we had 10k of spans which significantly polluted `plan.txt`, so this commit introduces a hard limit - now the first 20 physical spans will be printed. Release note: None
1 parent be2cc31 commit 8fc2e3d

File tree

5 files changed

+91
-27
lines changed

5 files changed

+91
-27
lines changed

pkg/sql/explain_plan.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,12 @@ func emitExplain(
223223
if err != nil {
224224
return err.Error()
225225
}
226+
// Show up to 20 physical spans.
227+
var more string
228+
if maxSpans := 20; len(spans) > maxSpans {
229+
more = fmt.Sprintf(" … (%d more)", len(spans)-maxSpans)
230+
spans = spans[:maxSpans]
231+
}
226232
// skip is how many fields to skip when pretty-printing spans.
227233
// Usually 2, but can be 4 when running EXPLAIN from a tenant since there
228234
// will be an extra tenant prefix and ID. For example:
@@ -235,7 +241,7 @@ func emitExplain(
235241
if !codec.ForSystemTenant() {
236242
skip = 4
237243
}
238-
return catalogkeys.PrettySpans(idx, spans, skip)
244+
return catalogkeys.PrettySpans(idx, spans, skip) + more
239245
}
240246

241247
return explain.Emit(ctx, evalCtx, explainPlan, ob, spanFormatFn, createPostQueryPlanIfMissing)

pkg/sql/opt/exec/execbuilder/testdata/explain

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2462,3 +2462,34 @@ vectorized: true
24622462
estimated row count: 1,000,000,000,000 (100% of the table; stats collected <hidden> ago)
24632463
table: very_large_table@very_large_table_pkey
24642464
spans: FULL SCAN
2465+
2466+
statement ok
2467+
CREATE TABLE t_float (k FLOAT PRIMARY KEY);
2468+
2469+
# A query with relatively large number of physical spans.
2470+
query T
2471+
EXPLAIN (VERBOSE) SELECT count(*) FROM t_float
2472+
WHERE k = ANY (
2473+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2474+
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
2475+
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
2476+
31, 32, 33, 34, 35, 36, 37, 38, 39, 40
2477+
);
2478+
----
2479+
distribution: local
2480+
vectorized: true
2481+
·
2482+
• group (scalar)
2483+
│ columns: (count)
2484+
│ estimated row count: 1 (missing stats)
2485+
│ aggregate 0: count_rows()
2486+
2487+
└── • project
2488+
│ columns: ()
2489+
2490+
└── • scan
2491+
columns: (k)
2492+
estimated row count: 40 (missing stats)
2493+
table: t_float@t_float_pkey
2494+
spans: /1/0 /2/0 /3/0 /4/0 /5/0 /6/0 /7/0 /8/0 /9/0 /10/0 /11/0 /12/0 /13/0 /14/0 /15/0 /16/0 /17/0 /18/0 /19/0 /20/0 … (20 more)
2495+
parallel

pkg/sql/opt/exec/execbuilder/testdata/hash_sharded_index

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ ALTER TABLE sharded_primary INJECT STATISTICS '[
1515
]'
1616

1717
query T
18-
EXPLAIN (VERBOSE) INSERT INTO sharded_primary (a) VALUES (1), (2)
18+
EXPLAIN (VERBOSE, TYPES) INSERT INTO sharded_primary (a) VALUES (1), (2)
1919
----
2020
distribution: local
2121
vectorized: true
@@ -27,21 +27,21 @@ vectorized: true
2727
│ auto commit
2828
2929
└── • render
30-
│ columns: (crdb_internal_a_shard_11_comp, column1, check1)
31-
│ render check1: crdb_internal_a_shard_11_comp IN (0, 1, __more1_10__, 10)
32-
│ render column1: column1
33-
│ render crdb_internal_a_shard_11_comp: crdb_internal_a_shard_11_comp
30+
│ columns: (crdb_internal_a_shard_11_comp int, column1 int, check1 bool)
31+
│ render check1: ((crdb_internal_a_shard_11_comp)[int] IN (((0)[int], (1)[int], __more1_10__, (10)[int]))[tuple{int, int, __more1_10__, int}])[bool]
32+
│ render column1: (column1)[int]
33+
│ render crdb_internal_a_shard_11_comp: (crdb_internal_a_shard_11_comp)[int]
3434
3535
└── • render
36-
│ columns: (crdb_internal_a_shard_11_comp, column1)
37-
│ render crdb_internal_a_shard_11_comp: mod(fnv32(md5(crdb_internal.datums_to_bytes(column1))), 11)
38-
│ render column1: column1
36+
│ columns: (crdb_internal_a_shard_11_comp int, column1 int)
37+
│ render crdb_internal_a_shard_11_comp: (mod((fnv32((md5((crdb_internal.datums_to_bytes((column1)[int]))[bytes]))[string]))[int], (11)[int]))[int]
38+
│ render column1: (column1)[int]
3939
4040
└── • values
41-
columns: (column1)
41+
columns: (column1 int)
4242
size: 1 column, 2 rows
43-
row 0, expr 0: 1
44-
row 1, expr 0: 2
43+
row 0, expr 0: (1)[int]
44+
row 1, expr 0: (2)[int]
4545

4646
query T
4747
EXPLAIN (VERBOSE) SELECT * FROM sharded_primary WHERE (a % 2) = 0 ORDER BY a LIMIT 10;
@@ -294,7 +294,7 @@ statement ok
294294
CREATE TABLE sharded_secondary (a INT8, INDEX (a) USING HASH WITH (bucket_count=12))
295295

296296
query T
297-
EXPLAIN (VERBOSE) INSERT INTO sharded_secondary (a) VALUES (1), (2)
297+
EXPLAIN (VERBOSE, TYPES) INSERT INTO sharded_secondary (a) VALUES (1), (2)
298298
----
299299
distribution: local
300300
vectorized: true
@@ -306,23 +306,23 @@ vectorized: true
306306
│ auto commit
307307
308308
└── • render
309-
│ columns: (column1, crdb_internal_a_shard_12_comp, rowid_default, check1)
310-
│ render check1: crdb_internal_a_shard_12_comp IN (0, 1, __more1_10__, 11)
311-
│ render column1: column1
312-
│ render rowid_default: rowid_default
313-
│ render crdb_internal_a_shard_12_comp: crdb_internal_a_shard_12_comp
309+
│ columns: (column1 int, crdb_internal_a_shard_12_comp int, rowid_default int, check1 bool)
310+
│ render check1: ((crdb_internal_a_shard_12_comp)[int] IN (((0)[int], (1)[int], __more1_10__, (11)[int]))[tuple{int, int, __more1_10__, int}])[bool]
311+
│ render column1: (column1)[int]
312+
│ render rowid_default: (rowid_default)[int]
313+
│ render crdb_internal_a_shard_12_comp: (crdb_internal_a_shard_12_comp)[int]
314314
315315
└── • render
316-
│ columns: (crdb_internal_a_shard_12_comp, rowid_default, column1)
317-
│ render crdb_internal_a_shard_12_comp: mod(fnv32(md5(crdb_internal.datums_to_bytes(column1))), 12)
318-
│ render rowid_default: unique_rowid()
319-
│ render column1: column1
316+
│ columns: (crdb_internal_a_shard_12_comp int, rowid_default int, column1 int)
317+
│ render crdb_internal_a_shard_12_comp: (mod((fnv32((md5((crdb_internal.datums_to_bytes((column1)[int]))[bytes]))[string]))[int], (12)[int]))[int]
318+
│ render rowid_default: (unique_rowid())[int]
319+
│ render column1: (column1)[int]
320320
321321
└── • values
322-
columns: (column1)
322+
columns: (column1 int)
323323
size: 1 column, 2 rows
324-
row 0, expr 0: 1
325-
row 1, expr 0: 2
324+
row 0, expr 0: (1)[int]
325+
row 1, expr 0: (2)[int]
326326

327327
query T
328328
EXPLAIN (VERBOSE) SELECT * FROM sharded_secondary WHERE a > 100 ORDER BY a LIMIT 10;

pkg/sql/opt/exec/execbuilder/testdata/inverted_index

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3281,7 +3281,7 @@ vectorized: true
32813281
columns: (k, geom_inverted_key)
32823282
estimated row count: 111 (missing stats)
32833283
table: geo_table@geom_index
3284-
spans: /"B\xfd\x10\x00\x00\x00\x00\x00\x00\x00"-/"B\xfd\x10\x00\x00\x00\x00\x00\x00\x01" /"B\xfd\x10\x00\x00\x00\x00\x00\x00\x01"-/"B\xfd\x10\x00\x00\x00\x00\x00\x00\x02" /"B\xfd\x10\x00\x00\x00\x00\x00\x00\x04"-/"B\xfd\x10\x00\x00\x00\x00\x00\x00\x05" /"B\xfd\x10\x00\x00\x00\x00\x00\x00\x10"-/"B\xfd\x10\x00\x00\x00\x00\x00\x00\x11" /"B\xfd\x10\x00\x00\x00\x00\x00\x00@"-/"B\xfd\x10\x00\x00\x00\x00\x00\x00A" /"B\xfd\x10\x00\x00\x00\x00\x00\x01\x00"-/"B\xfd\x10\x00\x00\x00\x00\x00\x01\x01" /"B\xfd\x10\x00\x00\x00\x00\x00\x04\x00"-/"B\xfd\x10\x00\x00\x00\x00\x00\x04\x01" /"B\xfd\x10\x00\x00\x00\x00\x00\x10\x00"-/"B\xfd\x10\x00\x00\x00\x00\x00\x10\x01" /"B\xfd\x10\x00\x00\x00\x00\x00@\x00"-/"B\xfd\x10\x00\x00\x00\x00\x00@\x01" /"B\xfd\x10\x00\x00\x00\x00\x01\x00\x00"-/"B\xfd\x10\x00\x00\x00\x00\x01\x00\x01" /"B\xfd\x10\x00\x00\x00\x00\x04\x00\x00"-/"B\xfd\x10\x00\x00\x00\x00\x04\x00\x01" /"B\xfd\x10\x00\x00\x00\x00\x10\x00\x00"-/"B\xfd\x10\x00\x00\x00\x00\x10\x00\x01" /"B\xfd\x10\x00\x00\x00\x00@\x00\x00"-/"B\xfd\x10\x00\x00\x00\x00@\x00\x01" /"B\xfd\x10\x00\x00\x00\x01\x00\x00\x00"-/"B\xfd\x10\x00\x00\x00\x01\x00\x00\x01" /"B\xfd\x10\x00\x00\x00\x04\x00\x00\x00"-/"B\xfd\x10\x00\x00\x00\x04\x00\x00\x01" /"B\xfd\x10\x00\x00\x00\x10\x00\x00\x00"-/"B\xfd\x10\x00\x00\x00\x10\x00\x00\x01" /"B\xfd\x10\x00\x00\x00@\x00\x00\x00"-/"B\xfd\x10\x00\x00\x00@\x00\x00\x01" /"B\xfd\x10\x00\x00\x01\x00\x00\x00\x00"-/"B\xfd\x10\x00\x00\x01\x00\x00\x00\x01" /"B\xfd\x10\x00\x00\x04\x00\x00\x00\x00"-/"B\xfd\x10\x00\x00\x04\x00\x00\x00\x01" /"B\xfd\x10\x00\x00\x10\x00\x00\x00\x00"-/"B\xfd\x10\x00\x00\x10\x00\x00\x00\x01" /"B\xfd\x10\x00\x00@\x00\x00\x00\x00"-/"B\xfd\x10\x00\x00@\x00\x00\x00\x01" /"B\xfd\x10\x00\x01\x00\x00\x00\x00\x00"-/"B\xfd\x10\x00\x01\x00\x00\x00\x00\x01" /"B\xfd\x10\x00\x04\x00\x00\x00\x00\x00"-/"B\xfd\x10\x00\x04\x00\x00\x00\x00\x01" /"B\xfd\x10\x00\x10\x00\x00\x00\x00\x00"-/"B\xfd\x10\x00\x10\x00\x00\x00\x00\x01" /"B\xfd\x10\x00@\x00\x00\x00\x00\x00"-/"B\xfd\x10\x00@\x00\x00\x00\x00\x01" /"B\xfd\x10\x01\x00\x00\x00\x00\x00\x00"-/"B\xfd\x10\x01\x00\x00\x00\x00\x00\x01" /"B\xfd\x10\x04\x00\x00\x00\x00\x00\x00"-/"B\xfd\x10\x04\x00\x00\x00\x00\x00\x01" /"B\xfd\x10\x10\x00\x00\x00\x00\x00\x00"-/"B\xfd\x10\x10\x00\x00\x00\x00\x00\x01" /"B\xfd\x10@\x00\x00\x00\x00\x00\x00"-/"B\xfd\x10@\x00\x00\x00\x00\x00\x01" /"B\xfd\x11\x00\x00\x00\x00\x00\x00\x00"-/"B\xfd\x11\x00\x00\x00\x00\x00\x00\x01" /"B\xfd\x14\x00\x00\x00\x00\x00\x00\x00"-/"B\xfd\x14\x00\x00\x00\x00\x00\x00\x01"
3284+
spans: /"B\xfd\x10\x00\x00\x00\x00\x00\x00\x00"-/"B\xfd\x10\x00\x00\x00\x00\x00\x00\x01" /"B\xfd\x10\x00\x00\x00\x00\x00\x00\x01"-/"B\xfd\x10\x00\x00\x00\x00\x00\x00\x02" /"B\xfd\x10\x00\x00\x00\x00\x00\x00\x04"-/"B\xfd\x10\x00\x00\x00\x00\x00\x00\x05" /"B\xfd\x10\x00\x00\x00\x00\x00\x00\x10"-/"B\xfd\x10\x00\x00\x00\x00\x00\x00\x11" /"B\xfd\x10\x00\x00\x00\x00\x00\x00@"-/"B\xfd\x10\x00\x00\x00\x00\x00\x00A" /"B\xfd\x10\x00\x00\x00\x00\x00\x01\x00"-/"B\xfd\x10\x00\x00\x00\x00\x00\x01\x01" /"B\xfd\x10\x00\x00\x00\x00\x00\x04\x00"-/"B\xfd\x10\x00\x00\x00\x00\x00\x04\x01" /"B\xfd\x10\x00\x00\x00\x00\x00\x10\x00"-/"B\xfd\x10\x00\x00\x00\x00\x00\x10\x01" /"B\xfd\x10\x00\x00\x00\x00\x00@\x00"-/"B\xfd\x10\x00\x00\x00\x00\x00@\x01" /"B\xfd\x10\x00\x00\x00\x00\x01\x00\x00"-/"B\xfd\x10\x00\x00\x00\x00\x01\x00\x01" /"B\xfd\x10\x00\x00\x00\x00\x04\x00\x00"-/"B\xfd\x10\x00\x00\x00\x00\x04\x00\x01" /"B\xfd\x10\x00\x00\x00\x00\x10\x00\x00"-/"B\xfd\x10\x00\x00\x00\x00\x10\x00\x01" /"B\xfd\x10\x00\x00\x00\x00@\x00\x00"-/"B\xfd\x10\x00\x00\x00\x00@\x00\x01" /"B\xfd\x10\x00\x00\x00\x01\x00\x00\x00"-/"B\xfd\x10\x00\x00\x00\x01\x00\x00\x01" /"B\xfd\x10\x00\x00\x00\x04\x00\x00\x00"-/"B\xfd\x10\x00\x00\x00\x04\x00\x00\x01" /"B\xfd\x10\x00\x00\x00\x10\x00\x00\x00"-/"B\xfd\x10\x00\x00\x00\x10\x00\x00\x01" /"B\xfd\x10\x00\x00\x00@\x00\x00\x00"-/"B\xfd\x10\x00\x00\x00@\x00\x00\x01" /"B\xfd\x10\x00\x00\x01\x00\x00\x00\x00"-/"B\xfd\x10\x00\x00\x01\x00\x00\x00\x01" /"B\xfd\x10\x00\x00\x04\x00\x00\x00\x00"-/"B\xfd\x10\x00\x00\x04\x00\x00\x00\x01" /"B\xfd\x10\x00\x00\x10\x00\x00\x00\x00"-/"B\xfd\x10\x00\x00\x10\x00\x00\x00\x01" … (11 more)
32853285

32863286
statement ok
32873287
CREATE TABLE geo_table2(

pkg/sql/sem/tree/format.go

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ const (
169169

170170
// FmtShortenConstants shortens long lists in tuples, VALUES and array
171171
// expressions. FmtHideConstants takes precedence over it.
172+
//
173+
// It also affects printing the tuple type when FmtShowTypes is set.
172174
FmtShortenConstants
173175

174176
// FmtCollapseLists instructs the pretty-printer to shorten lists
@@ -631,7 +633,32 @@ func (ctx *FmtCtx) FormatNode(n NodeFormatter) {
631633
// further.
632634
ctx.Printf("??? %v", te)
633635
} else {
634-
ctx.WriteString(rt.String())
636+
if len(rt.TupleContents()) > numElementsForShortenedList && f.HasFlags(FmtShortenConstants) {
637+
// If we have a tuple with more than 3 elements, and we are
638+
// requested to shorten the constants, we'll also shorten
639+
// the tuple type description in the same fashion (showing
640+
// the first two and the last element types).
641+
//
642+
// Note that for simplicity we'll omit tuple labels that are
643+
// printed in types.T.String() when present.
644+
contents := rt.TupleContents()
645+
var buf bytes.Buffer
646+
buf.WriteString("tuple")
647+
if len(contents) != 0 && !types.IsWildcardTupleType(rt) {
648+
buf.WriteByte('{')
649+
for _, element := range contents[:numElementsForShortenedList-1] {
650+
buf.WriteString(element.String())
651+
buf.WriteString(", ")
652+
}
653+
buf.WriteString(arityString(len(contents) - numElementsForShortenedList))
654+
buf.WriteString(", ")
655+
buf.WriteString(contents[len(contents)-1].String())
656+
buf.WriteByte('}')
657+
}
658+
ctx.WriteString(buf.String())
659+
} else {
660+
ctx.WriteString(rt.String())
661+
}
635662
}
636663
ctx.WriteByte(']')
637664
return

0 commit comments

Comments
 (0)