@@ -144,6 +144,9 @@ public class GenericPlanNode {
144144 private Map <String , Long > longMetricsActual = new LinkedHashMap <>();
145145 private Map <String , Double > doubleMetricsActual = new LinkedHashMap <>();
146146 private Map <String , String > stringMetricsActual = new LinkedHashMap <>();
147+ private Map <String , Long > longMetricsPlanned = new LinkedHashMap <>();
148+ private Map <String , Double > doubleMetricsPlanned = new LinkedHashMap <>();
149+ private Map <String , String > stringMetricsPlanned = new LinkedHashMap <>();
147150
148151 // true if this node introduces a new scope
149152 private Boolean newScope ;
@@ -403,6 +406,11 @@ public void setRuntimeTelemetryEnabled(boolean runtimeTelemetryEnabled) {
403406 this .runtimeTelemetryEnabled = runtimeTelemetryEnabled ;
404407 }
405408
409+ @ JsonIgnore
410+ public boolean isRuntimeTelemetryEnabled () {
411+ return runtimeTelemetryEnabled ;
412+ }
413+
406414 public void setEstimateStabilityMetricsEnabled (boolean estimateStabilityMetricsEnabled ) {
407415 this .estimateStabilityMetricsEnabled = estimateStabilityMetricsEnabled ;
408416 }
@@ -502,6 +510,66 @@ public void setStringMetricActual(String metricName, String metricValue) {
502510 stringMetricsActual .put (metricName , metricValue );
503511 }
504512
513+ public Map <String , Long > getLongMetricsPlanned () {
514+ return longMetricsPlanned .isEmpty () ? null : longMetricsPlanned ;
515+ }
516+
517+ public void setLongMetricsPlanned (Map <String , Long > longMetricsPlanned ) {
518+ this .longMetricsPlanned = longMetricsPlanned == null ? new LinkedHashMap <>()
519+ : new LinkedHashMap <>(longMetricsPlanned );
520+ }
521+
522+ public Long getLongMetricPlanned (String metricName ) {
523+ return longMetricsPlanned .get (metricName );
524+ }
525+
526+ public void setLongMetricPlanned (String metricName , Long metricValue ) {
527+ if (metricName == null || metricValue == null || metricValue < 0 ) {
528+ return ;
529+ }
530+ longMetricsPlanned .put (metricName , metricValue );
531+ }
532+
533+ public Map <String , Double > getDoubleMetricsPlanned () {
534+ return doubleMetricsPlanned .isEmpty () ? null : doubleMetricsPlanned ;
535+ }
536+
537+ public void setDoubleMetricsPlanned (Map <String , Double > doubleMetricsPlanned ) {
538+ this .doubleMetricsPlanned = doubleMetricsPlanned == null ? new LinkedHashMap <>()
539+ : new LinkedHashMap <>(doubleMetricsPlanned );
540+ }
541+
542+ public Double getDoubleMetricPlanned (String metricName ) {
543+ return doubleMetricsPlanned .get (metricName );
544+ }
545+
546+ public void setDoubleMetricPlanned (String metricName , Double metricValue ) {
547+ if (metricName == null || metricValue == null || metricValue < 0 ) {
548+ return ;
549+ }
550+ doubleMetricsPlanned .put (metricName , metricValue );
551+ }
552+
553+ public Map <String , String > getStringMetricsPlanned () {
554+ return stringMetricsPlanned .isEmpty () ? null : stringMetricsPlanned ;
555+ }
556+
557+ public void setStringMetricsPlanned (Map <String , String > stringMetricsPlanned ) {
558+ this .stringMetricsPlanned = stringMetricsPlanned == null ? new LinkedHashMap <>()
559+ : new LinkedHashMap <>(stringMetricsPlanned );
560+ }
561+
562+ public String getStringMetricPlanned (String metricName ) {
563+ return stringMetricsPlanned .get (metricName );
564+ }
565+
566+ public void setStringMetricPlanned (String metricName , String metricValue ) {
567+ if (metricName == null || metricValue == null || metricValue .isEmpty ()) {
568+ return ;
569+ }
570+ stringMetricsPlanned .put (metricName , metricValue );
571+ }
572+
505573 public void setTimedOut (Boolean timedOut ) {
506574 this .timedOut = timedOut ;
507575 }
@@ -919,6 +987,8 @@ private Long sourceRowsFilteredForDisplay() {
919987 }
920988
921989 private void appendMapTelemetry (Map <String , String > metrics ) {
990+ appendPlannedMapTelemetry (metrics );
991+
922992 Map <String , Long > visibleLongMetrics = getLongMetricsActual ();
923993 if (visibleLongMetrics != null ) {
924994 for (Map .Entry <String , Long > entry : visibleLongMetrics .entrySet ()) {
@@ -962,13 +1032,66 @@ private void appendMapTelemetry(Map<String, String> metrics) {
9621032 }
9631033 }
9641034
1035+ private void appendPlannedMapTelemetry (Map <String , String > metrics ) {
1036+ for (Map .Entry <String , Long > entry : longMetricsPlanned .entrySet ()) {
1037+ Long metricValue = entry .getValue ();
1038+ if (metricValue == null || metricValue < 0 || metrics .containsKey (entry .getKey ())) {
1039+ continue ;
1040+ }
1041+ putIfKnown (metrics , entry .getKey (), toHumanReadableNumber (metricValue ));
1042+ }
1043+ for (Map .Entry <String , Double > entry : doubleMetricsPlanned .entrySet ()) {
1044+ Double metricValue = entry .getValue ();
1045+ if (metricValue == null || metricValue < 0 || metrics .containsKey (entry .getKey ())) {
1046+ continue ;
1047+ }
1048+ putIfKnown (metrics , entry .getKey (), toHumanReadableNumber (metricValue ));
1049+ }
1050+ for (Map .Entry <String , String > entry : orderedStringMetricsPlanned ()) {
1051+ String metricName = entry .getKey ();
1052+ String metricValue = entry .getValue ();
1053+ if (metricValue == null || metricValue .isEmpty () || metrics .containsKey (metricName )) {
1054+ continue ;
1055+ }
1056+ metrics .put (metricName , metricValue );
1057+ }
1058+ }
1059+
1060+ private List <Map .Entry <String , String >> orderedStringMetricsPlanned () {
1061+ List <Map .Entry <String , String >> orderedEntries = new ArrayList <>();
1062+ appendPreferredStringMetric (orderedEntries , stringMetricsPlanned , TelemetryMetricNames .PLANNED_INDEX_NAME );
1063+ appendPreferredStringMetric (orderedEntries , stringMetricsPlanned ,
1064+ TelemetryMetricNames .PLANNED_INDEX_ACCESS_MODE );
1065+ appendPreferredStringMetric (orderedEntries , stringMetricsPlanned ,
1066+ TelemetryMetricNames .PLANNED_LOOKUP_COMPONENTS );
1067+ appendPreferredStringMetric (orderedEntries , stringMetricsPlanned ,
1068+ TelemetryMetricNames .PLANNED_MISSING_LOOKUP_COMPONENTS );
1069+ appendPreferredStringMetric (orderedEntries , stringMetricsPlanned , TelemetryMetricNames .PLANNED_BOUND_VARS );
1070+ appendPreferredStringMetric (orderedEntries , stringMetricsPlanned , TelemetryMetricNames .PLANNER_ID );
1071+ appendPreferredStringMetric (orderedEntries , stringMetricsPlanned , TelemetryMetricNames .PLANNER_ALGORITHM );
1072+ appendPreferredStringMetric (orderedEntries , stringMetricsPlanned , TelemetryMetricNames .PLANNER_PATH );
1073+ for (Map .Entry <String , String > entry : stringMetricsPlanned .entrySet ()) {
1074+ if (orderedEntries .stream ().anyMatch (ordered -> ordered .getKey ().equals (entry .getKey ()))) {
1075+ continue ;
1076+ }
1077+ orderedEntries .add (entry );
1078+ }
1079+ return orderedEntries ;
1080+ }
1081+
9651082 private List <Map .Entry <String , String >> orderedStringMetricsActual () {
9661083 Map <String , String > visibleStringMetrics = visibleStringMetricsActual ();
9671084 List <Map .Entry <String , String >> orderedEntries = new ArrayList <>();
9681085 appendPreferredStringMetric (orderedEntries , visibleStringMetrics , TelemetryMetricNames .BINDING_STATE );
9691086 appendPreferredStringMetric (orderedEntries , visibleStringMetrics , TelemetryMetricNames .JOIN_TYPE );
9701087 appendPreferredStringMetric (orderedEntries , visibleStringMetrics , TelemetryMetricNames .INDEX_NAME );
9711088 appendPreferredStringMetric (orderedEntries , visibleStringMetrics , TelemetryMetricNames .INDEX_NAMES );
1089+ appendPreferredStringMetric (orderedEntries , visibleStringMetrics , TelemetryMetricNames .OPTIMIZER_PLANNER_ID );
1090+ appendPreferredStringMetric (orderedEntries , visibleStringMetrics , TelemetryMetricNames .OPTIMIZER_PLANNER_PATH );
1091+ appendPreferredStringMetric (orderedEntries , visibleStringMetrics ,
1092+ TelemetryMetricNames .OPTIMIZER_PLANNER_REJECTED_FACTOR );
1093+ appendPreferredStringMetric (orderedEntries , visibleStringMetrics ,
1094+ TelemetryMetricNames .OPTIMIZER_PLANNER_DIAGNOSTICS );
9721095 for (Map .Entry <String , String > entry : visibleStringMetrics .entrySet ()) {
9731096 if (isPreferredExplainAnnotationMetric (entry .getKey ())) {
9741097 continue ;
@@ -1470,13 +1593,24 @@ private String toDotInternal(double maxResultSizeActual, double maxTotalTime, do
14701593 private void appendExplainAnnotationDotRows (List <String > rows ) {
14711594 appendExplainAnnotationDotRow (rows , "Binding state" , TelemetryMetricNames .BINDING_STATE );
14721595 appendExplainAnnotationDotRow (rows , "Join type" , TelemetryMetricNames .JOIN_TYPE );
1596+ appendPlannedExplainAnnotationDotRow (rows , "Planned index" , TelemetryMetricNames .PLANNED_INDEX_NAME );
1597+ appendPlannedExplainAnnotationDotRow (rows , "Planned bound vars" , TelemetryMetricNames .PLANNED_BOUND_VARS );
14731598 if (getStringMetricActual (TelemetryMetricNames .INDEX_NAME ) != null ) {
14741599 appendExplainAnnotationDotRow (rows , "Index" , TelemetryMetricNames .INDEX_NAME );
14751600 } else {
14761601 appendExplainAnnotationDotRow (rows , "Indexes" , TelemetryMetricNames .INDEX_NAMES );
14771602 }
14781603 }
14791604
1605+ private void appendPlannedExplainAnnotationDotRow (List <String > rows , String label , String metricName ) {
1606+ String metricValue = getStringMetricPlanned (metricName );
1607+ if (metricValue == null || metricValue .isEmpty ()) {
1608+ return ;
1609+ }
1610+ rows .add ("<tr><td>" + StringEscapeUtils .escapeHtml4 (label ) + "</td><td>"
1611+ + StringEscapeUtils .escapeHtml4 (metricValue ) + "</td></tr>" );
1612+ }
1613+
14801614 private void appendExplainAnnotationDotRow (List <String > rows , String label , String metricName ) {
14811615 String metricValue = getStringMetricActual (metricName );
14821616 if (metricValue == null || metricValue .isEmpty ()) {
0 commit comments