@@ -18,17 +18,21 @@ const metricAllowlist: Record<NodeType, Array<string>> = {
1818 "number of file splits read" ,
1919 "output columnar batches" ,
2020 "number of bytes pruned" ,
21- "number of files pruned"
21+ "number of files pruned" ,
2222 ] ,
2323 output : [
2424 "number of written files" ,
2525 "number of output rows" ,
2626 "written output" ,
2727 "number of dynamic part" ,
2828 ] ,
29- join : [ "number of output rows" , "output columnar batches" ,
30- ] ,
31- transformation : [ "number of output rows" , "output columnar batches" , "output rows" , "data sent to Python workers" , "data returned from Python workers"
29+ join : [ "number of output rows" , "output columnar batches" ] ,
30+ transformation : [
31+ "number of output rows" ,
32+ "output columnar batches" ,
33+ "output rows" ,
34+ "data sent to Python workers" ,
35+ "data returned from Python workers" ,
3236 ] ,
3337 shuffle : [
3438 "number of partitions" ,
@@ -38,7 +42,7 @@ const metricAllowlist: Record<NodeType, Array<string>> = {
3842 "num bytes read" ,
3943 "num bytes written" ,
4044 "output columnar batches" ,
41- "partition data size"
45+ "partition data size" ,
4246 ] ,
4347
4448 broadcast : [ "number of output rows" , "data size" , "output columnar batches" ] ,
@@ -261,6 +265,22 @@ export function bytesToHumanReadableSize(
261265 }
262266}
263267
268+ function getCommonOperationPrefix ( operations : string [ ] ) : string | null {
269+ if ( operations . length === 0 ) {
270+ return null ;
271+ }
272+
273+ if ( operations . length === 1 ) {
274+ return operations [ 0 ] ;
275+ }
276+
277+ // Check if all operations are the same
278+ const firstOperation = operations [ 0 ] ;
279+ const allSame = operations . every ( ( op ) => op === firstOperation ) ;
280+
281+ return allSame ? firstOperation : null ;
282+ }
283+
264284export function nodeEnrichedNameBuilder (
265285 name : string ,
266286 plan : ParsedNodePlan | undefined ,
@@ -271,12 +291,43 @@ export function nodeEnrichedNameBuilder(
271291 if ( plan . plan . functions . length == 0 ) {
272292 return "Distinct" ;
273293 }
274- return (
275- "Aggregate" +
276- ( plan . plan . operations . length > 0 && plan . plan . operations . length < 3
277- ? ` (${ plan . plan . operations . join ( ", " ) } )`
278- : "" )
279- ) ;
294+
295+ // Build enriched name based on operations
296+ if ( plan . plan . operations . length > 0 ) {
297+ // Extract common prefix from all operations
298+ const commonPrefix = getCommonOperationPrefix ( plan . plan . operations ) ;
299+
300+ if ( commonPrefix ) {
301+ // Use common prefix as the operation name
302+ let operationName : string ;
303+ if ( commonPrefix . startsWith ( "partial_" ) ) {
304+ operationName = commonPrefix . substring ( 8 ) + " within partition" ; // Remove "partial_" and add suffix
305+ } else if ( commonPrefix . startsWith ( "merge_" ) ) {
306+ operationName = commonPrefix . substring ( 6 ) + " by merge" ; // Remove "merge_" and add suffix
307+ } else if ( commonPrefix . startsWith ( "finalmerge_" ) ) {
308+ operationName = commonPrefix . substring ( 11 ) + " by merge" ; // Remove "finalmerge_" and add suffix
309+ } else {
310+ operationName = commonPrefix ;
311+ }
312+ return `${ operationName } ` ;
313+ } else if ( plan . plan . operations . length < 3 ) {
314+ // Fallback to showing individual operations if no common prefix and few operations
315+ const formattedOperations = plan . plan . operations . map ( ( op ) => {
316+ if ( op . startsWith ( "partial_" ) ) {
317+ return op . substring ( 8 ) + " within partition" ;
318+ } else if ( op . startsWith ( "merge_" ) ) {
319+ return op . substring ( 6 ) + " by merge" ;
320+ } else if ( op . startsWith ( "finalmerge_" ) ) {
321+ return op . substring ( 11 ) + " by merge" ;
322+ } else {
323+ return op ;
324+ }
325+ } ) ;
326+ return `Aggregate (${ formattedOperations . join ( ", " ) } )` ;
327+ }
328+ }
329+
330+ return "Aggregate" ;
280331 case "Generate" :
281332 if ( plan ?. plan ?. operation !== undefined ) {
282333 return plan . plan . operation ;
@@ -287,8 +338,7 @@ export function nodeEnrichedNameBuilder(
287338 case "Exchange" :
288339 if ( plan . plan . isBroadcast ) {
289340 return "Broadcast" ;
290- }
291- else if ( plan . plan . type === "hashpartitioning" ) {
341+ } else if ( plan . plan . type === "hashpartitioning" ) {
292342 return `Repartition By Hash` ;
293343 } else if ( plan . plan . type === "rangepartitioning" ) {
294344 return `Repartition By Range` ;
0 commit comments