@@ -72,6 +72,8 @@ def __init__(
72
72
value = False , description = "Qsteps switch" , disabled = False , indent = False
73
73
)
74
74
75
+ self .accordions = None
76
+
75
77
# buttons to navigate through transactions
76
78
next_button = widgets .Button (description = "Next Query" )
77
79
prev_button = widgets .Button (description = "Previous Query" )
@@ -153,7 +155,7 @@ def __init__(
153
155
value = f"<h1><b>Query Execution Steps - [query_idx: { self .index_widget .value } ]</b></h1>"
154
156
)
155
157
156
- def get_qplan_tree (self , use_javascript = True , ** style_kwargs ):
158
+ def get_qplan_tree (self , use_javascript = True , hide_settings = False , ** style_kwargs ):
157
159
"""
158
160
Draws an interactive Query plan tree.
159
161
@@ -270,10 +272,10 @@ def get_qplan_tree(self, use_javascript=True, **style_kwargs):
270
272
"Query text" : self .query_display ,
271
273
}
272
274
query_text_index = list (accordion_items .keys ()).index ("Query text" )
273
- accordions = Visualizer ._accordion (
275
+ self . accordions = Visualizer ._accordion (
274
276
list (accordion_items .values ()), accordion_items .keys ()
275
277
)
276
- accordions .selected_index = query_text_index
278
+ self . accordions .selected_index = query_text_index
277
279
header_box = widgets .HBox (
278
280
[self .qpt_header ], layout = {"justify_content" : "center" }
279
281
)
@@ -292,14 +294,21 @@ def get_qplan_tree(self, use_javascript=True, **style_kwargs):
292
294
interactive_output = widgets .interactive_output (
293
295
self .update_qplan_tree , controls
294
296
)
297
+ if hide_settings :
298
+ self .accordions .layout .display = "none"
299
+ self .transaction_buttons .layout .display = "none"
300
+ self .query_select_dropdown .layout .display = "none"
301
+ self .query_display_info .layout .display = "none"
295
302
settings = [
296
- accordions ,
303
+ self . accordions ,
297
304
self .transaction_buttons ,
298
305
self .query_select_dropdown ,
299
306
self .query_display_info ,
300
307
]
301
308
viz = Visualizer (
302
- settings_wids = settings , graph_wids = [header_box , interactive_output ]
309
+ settings_wids = settings ,
310
+ graph_wids = [header_box , interactive_output ],
311
+ orientation = "v" if hide_settings else "h" ,
303
312
)
304
313
viz .display ()
305
314
@@ -533,7 +542,7 @@ def get_qsteps_(self):
533
542
list (accordion_items .values ()), accordion_items .keys ()
534
543
)
535
544
qsteps_settings = [
536
- accordions ,
545
+ self . accordions ,
537
546
self .transaction_buttons ,
538
547
]
539
548
@@ -734,3 +743,94 @@ def get_step_funcs(self):
734
743
20 : self .get_rp_status ,
735
744
21 : self .get_cluster_config ,
736
745
}
746
+
747
+
748
+ class QueryProfilerComparison :
749
+ """
750
+ Initializes a QueryProfilerComparison object with two QueryProfilerInterface instances for side-by-side comparison.
751
+
752
+ Parameters:
753
+ qprof1 (QueryProfilerInterface): The first QueryProfilerInterface instance for comparison.
754
+ qprof2 (QueryProfilerInterface): The second QueryProfilerInterface instance for comparison.
755
+ """
756
+
757
+ def __init__ (self , qprof1 , qprof2 ):
758
+ self .qprof1 = qprof1
759
+ self .qprof2 = qprof2
760
+
761
+ self .query_info = self ._create_query_info ()
762
+
763
+ # Initial update of the trees
764
+ nooutput = widgets .Output ()
765
+ with nooutput :
766
+ self .qprof1 .get_qplan_tree ()
767
+ self .qprof2 .get_qplan_tree ()
768
+
769
+ self .controls = self ._create_controls ()
770
+ self .side_by_side_ui = widgets .VBox ([self .query_info , self .controls ])
771
+
772
+ def _create_controls (self ):
773
+ def create_interactive_controls (qprof ):
774
+ controls = {
775
+ "index" : qprof .query_select_dropdown ,
776
+ "metric1" : qprof .accordions .children [0 ].children [0 ],
777
+ "metric2" : qprof .accordions .children [0 ].children [1 ],
778
+ "display_tooltip_agg_metrics" : qprof .accordions .children [0 ]
779
+ .children [3 ]
780
+ .children [0 ],
781
+ "display_tooltip_op_metrics" : qprof .accordions .children [0 ]
782
+ .children [3 ]
783
+ .children [1 ],
784
+ "display_tooltip_descriptors" : qprof .accordions .children [0 ]
785
+ .children [3 ]
786
+ .children [2 ],
787
+ "path_id" : qprof .pathid_dropdown .get_child (),
788
+ "apply_tree_clicked" : qprof .apply_tree ,
789
+ "temp_display" : qprof .accordions .children [2 ].children [0 ],
790
+ "projection_display" : qprof .accordions .children [2 ].children [1 ],
791
+ }
792
+ return widgets .interactive_output (qprof .update_qplan_tree , controls )
793
+
794
+ q1_control = self .qprof1 .accordions
795
+ q1_control .selected_index = None
796
+ q1_control .layout .width = "50%"
797
+ q1_interactive = create_interactive_controls (self .qprof1 )
798
+ q1_interactive = widgets .HBox (
799
+ [q1_interactive ],
800
+ layout = widgets .Layout (width = "50%" , border = "1px solid black" ),
801
+ )
802
+
803
+ q2_control = self .qprof2 .accordions
804
+ q2_control .selected_index = None
805
+ q2_control .layout .width = "50%"
806
+ q2_interactive = create_interactive_controls (self .qprof2 )
807
+ q2_interactive = widgets .HBox (
808
+ [q2_interactive ],
809
+ layout = widgets .Layout (width = "50%" , border = "1px solid black" ),
810
+ )
811
+
812
+ return widgets .VBox (
813
+ [
814
+ widgets .HBox ([q1_control , q2_control ]),
815
+ widgets .HBox ([q1_interactive , q2_interactive ]),
816
+ ]
817
+ )
818
+
819
+ def _create_query_info (self ):
820
+ # Get and set the layout for the query display info for both qprof1 and qprof2
821
+ q1_info = self .qprof1 .query_display_info
822
+ q1_info .layout .display = "block"
823
+ q1_info .layout .width = "50%"
824
+ q1_info .layout .border = "1px solid black"
825
+
826
+ q2_info = self .qprof2 .query_display_info
827
+ q2_info .layout .display = "block"
828
+ q2_info .layout .width = "50%"
829
+ q2_info .layout .border = "1px solid black"
830
+
831
+ # Return an HBox containing the query display information side by side
832
+ return widgets .HBox ([q1_info , q2_info ])
833
+
834
+ def display (self ):
835
+ # Display the final side-by-side UI
836
+ display (self .side_by_side_ui )
0 commit comments