diff --git a/project/ui/qprof-ui.ipynb b/project/ui/qprof-ui.ipynb index c57b5f07..3735a782 100644 --- a/project/ui/qprof-ui.ipynb +++ b/project/ui/qprof-ui.ipynb @@ -82,11 +82,12 @@ "import plotly.graph_objects as go\n", "from collections import defaultdict, Counter\n", "import textwrap\n", - "from verticapy.performance.vertica import QueryProfilerInterface, QueryProfiler\n", + "from verticapy.performance.vertica import QueryProfilerInterface, QueryProfiler, QueryProfilerComparison\n", "logging.info('[Query Profile Tree Page] Successfully Imported Libraries ')\n", "output_initial = widgets.Output()\n", "global qprof\n", "global qprof2\n", + "comparison = False\n", "with output_initial:\n", " %store -r query_val\n", " %store -r key_val\n", @@ -98,6 +99,19 @@ " %store -r key_val_2\n", " %store -r transaction_statement_list_val\n", " %store -r control_query_val\n", + " %store -r transaction_comp1_val\n", + " %store -r statement_comp1_val\n", + " %store -r target_schema_comp1_val\n", + " %store -r key_comp1_val\n", + " %store -r query_comp1_val\n", + " %store -r session_control_1_val\n", + " %store -r transaction_comp2_val\n", + " %store -r statement_comp2_val\n", + " %store -r target_schema_comp2_val\n", + " %store -r key_comp2_val\n", + " %store -r query_comp2_val\n", + " %store -r session_control_2_val\n", + "\n", " if \"file_val\" in globals():\n", " if not \"key_val\" in globals():\n", " characters = string.ascii_letters + string.digits # includes 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'\n", @@ -145,7 +159,46 @@ " target_schema = target_schema_val_2 if \"target_schema_val_2\" in globals() else None,\n", " key_id = key_val_2 if \"key_val_2\" in globals() else None,\n", " check_tables = False,\n", - " )\n" + " )\n", + "\n", + " else:\n", + " comparison = True\n", + " if \"transaction_comp1_val\" in globals():\n", + " qprof1 = QueryProfilerInterface(\n", + " transactions = (eval(transaction_comp1_val),eval(statement_comp1_val)),\n", + " check_tables = False,\n", + " )\n", + " elif \"target_schema_comp1_val\" in globals():\n", + " qprof1 = QueryProfilerInterface(\n", + " target_schema = target_schema_comp1_val,\n", + " key_id = key_comp1_val,\n", + " check_tables = False,\n", + " )\n", + " elif \"query_comp1_val\" in globals():\n", + " qprof1 = QueryProfilerInterface(\n", + " query_comp1_val,\n", + " check_tables = False,\n", + " session_control = session_control_1_val if \"session_control_1_val\" in globals() else None,\n", + " )\n", + " if \"transaction_comp2_val\" in globals(): # Changed from transaction_comp1_val to transaction_comp2_val\n", + " qprof2 = QueryProfilerInterface( # Changed from qprof1 to qprof2\n", + " transactions = (eval(transaction_comp2_val),eval(statement_comp2_val)), # Changed from transaction_comp1_val to transaction_comp2_val\n", + " check_tables = False,\n", + " )\n", + " elif \"target_schema_comp2_val\" in globals(): # Changed from target_schema_comp1_val to target_schema_comp2_val\n", + " qprof2 = QueryProfilerInterface( # Changed from qprof1 to qprof2\n", + " target_schema = target_schema_comp2_val, # Changed from target_schema_comp1_val to target_schema_comp2_val\n", + " key_id = key_comp2_val, # Changed from key_comp1_val to key_comp2_val\n", + " check_tables = False,\n", + " )\n", + " elif \"query_comp2_val\" in globals(): # Changed from query_comp1_val to query_comp2_val\n", + " qprof2 = QueryProfilerInterface( # Changed from qprof1 to qprof2\n", + " query_comp2_val, # Changed from query_comp1_val to query_comp2_val\n", + " check_tables = False,\n", + " session_control = session_control_2_val if \"session_control_2_val\" in globals() else None, # Changed from session_control_1_val to session_control_2_val\n", + " )\n", + " qprof_comparison = QueryProfilerComparison(qprof1, qprof2)\n", + " " ] }, { @@ -334,6 +387,8 @@ "outputs": [], "source": [ "top_accordion = widgets.Accordion(children=[qprof_save], titles=('Downloads',))\n", + "if comparison:\n", + " button_qprof_save.disabled = True\n", "display(top_accordion)" ] }, @@ -1329,6 +1384,41 @@ " drop_down_query_select = widgets.HTML(f\"

The following error occured:

{e}

\")" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "57dec0ac-048c-400a-a0fa-32347a2f6982", + "metadata": {}, + "outputs": [], + "source": [ + "# Info/Warning Box\n", + "import ipywidgets as widgets\n", + "\n", + "def show_notification():\n", + " close_button = widgets.Button(\n", + " description=\"x\",\n", + " button_style=\"danger\",\n", + " layout={'width': '30px', 'height': '30px', 'margin': '0 0 0 10px'}\n", + " )\n", + "\n", + " def close_notification(_):\n", + " notification.close()\n", + " close_button.close()\n", + "\n", + " close_button.on_click(close_notification)\n", + "\n", + " notification = widgets.HTML(\n", + " value=\"
\"\n", + " \"Important: If you do not see the trees, please click on the tab 'Tree Style' and then click on 'Apply'. This will refresh the tree.\"\n", + " \"
\",\n", + " layout={'margin': '10px 0'}\n", + " )\n", + "\n", + " display(widgets.HBox([notification, close_button]))\n", + "\n", + "show_notification()" + ] + }, { "cell_type": "code", "execution_count": null, @@ -1340,7 +1430,10 @@ "\n", "with output_tree:\n", " logging.info(f'[Query Profile Tree Page] Trying to display the tree')\n", - " qprof.get_qplan_tree()\n", + " if comparison:\n", + " qprof_comparison.display()\n", + " else:\n", + " qprof.get_qplan_tree()\n", " logging.info(f'[Query Profile Tree Page] Finished trying to display the tree')\n", " \n", "tabs = widgets.Tab()\n", @@ -1351,19 +1444,22 @@ "child_4 = widgets.VBox([button_get_queries, output_get_queries])\n", "child_5 = widgets.VBox([plot_tabs_main])\n", "child_6 = widgets.VBox([other_info])\n", - "\n", - "tabs.children = [child_1, \n", - " child_2, \n", - " child_3, \n", - " child_4, \n", - " child_5, \n", - " child_6]\n", - "tabs.titles = [\"Tree\", \n", - " \"Query Events\", \n", - " \"Query Engine\", \n", - " \"Transaction List\", \n", - " \"Plots\",\n", - " \"Other info\"]\n", + "if comparison:\n", + " tabs.children = [child_1]\n", + " tabs.titles = [\"Tree\"]\n", + "else:\n", + " tabs.children = [child_1, \n", + " child_2, \n", + " child_3, \n", + " child_4, \n", + " child_5, \n", + " child_6]\n", + " tabs.titles = [\"Tree\", \n", + " \"Query Events\", \n", + " \"Query Engine\", \n", + " \"Transaction List\", \n", + " \"Plots\",\n", + " \"Other info\"]\n", "\n", "# Define the observer function\n", "def on_tab_change(change):\n", @@ -1543,41 +1639,103 @@ }, "outputs": [], "source": [ - "button_run_explain_plan = widgets.Button(description=\"Run Explain Plan\")\n", - "explain_output = widgets.Output()\n", - "try:\n", - " explain_dropdown_options = [i for i in range(len(qprof.transactions))]\n", - " explain_dropdown_disabled = False\n", - "except Exception as e:\n", - " explain_dropdown_options = []\n", - " explain_dropdown_disabled = True\n", + "if comparison:\n", + " button_run_explain_plan_1 = widgets.Button(description=\"Run Explain Plan\")\n", + " explain_output_1 = widgets.Output()\n", + " try:\n", + " explain_dropdown_options_1 = [i for i in range(len(qprof1.transactions))]\n", + " explain_dropdown_disabled_1 = False\n", + " except Exception as e:\n", + " explain_dropdown_options_1 = []\n", + " explain_dropdown_disabled_1 = True\n", + " \n", + " explain_dropdown_1 = widgets.Dropdown(\n", + " options=explain_dropdown_options_1,\n", + " description='Select Query Index',\n", + " disabled=explain_dropdown_disabled_1,\n", + " layout={'width': \"300px\"}\n", + " )\n", + " explain_dropdown_1.style.description_width = '130px'\n", " \n", - "explain_dropdown = widgets.Dropdown(\n", - " options=explain_dropdown_options,\n", - " description='Select Query Index',\n", - " disabled=explain_dropdown_disabled,\n", - " layout={'width': \"300px\"}\n", - ")\n", - "explain_dropdown.style.description_width = '130px'\n", - "\n", - "def on_button_clicked_run_explain_plan(b):\n", - " explain_output.clear_output()\n", - " with explain_output:\n", - " qprof.set_position(explain_dropdown.value)\n", - " qprof.get_qplan_explain()\n", - "\n", + " def on_button_clicked_run_explain_plan_1(b):\n", + " explain_output_1.clear_output()\n", + " with explain_output_1:\n", + " qprof1.set_position(explain_dropdown_1.value)\n", + " qprof1.get_qplan_explain()\n", "\n", - "def on_button_clicked_run_query(b):\n", - " output_run_query.clear_output(wait=True)\n", - " global query_val, target_schema_val_2, key_val_2\n", - " with output_run_query:\n", - " query_val = query.value\n", - " logging.info(f\"\"\"[Query Profile Tree Page] Running the following custom query requested by the user :{query_val}.\"\"\")\n", - " run_query_result = vp.vDataFrame(query_val)\n", - " display(widgets.HTML(run_query_result._repr_html_()))\n", + " button_run_explain_plan_1.on_click(on_button_clicked_run_explain_plan_1)\n", + " \n", + " button_run_explain_plan_2 = widgets.Button(description=\"Run Explain Plan\")\n", + " explain_output_2 = widgets.Output()\n", + " try:\n", + " explain_dropdown_options_2 = [i for i in range(len(qprof2.transactions))]\n", + " explain_dropdown_disabled_2 = False\n", + " except Exception as e:\n", + " explain_dropdown_options_2 = []\n", + " explain_dropdown_disabled_2 = True\n", + " \n", + " explain_dropdown_2 = widgets.Dropdown(\n", + " options=explain_dropdown_options_2,\n", + " description='Select Query Index',\n", + " disabled=explain_dropdown_disabled_2, # Updated to use explain_dropdown_disabled_2\n", + " layout={'width': \"300px\"}\n", + " )\n", + " explain_dropdown_2.style.description_width = '130px'\n", + " \n", + " def on_button_clicked_run_explain_plan_2(b):\n", + " explain_output_2.clear_output()\n", + " with explain_output_2:\n", + " qprof2.set_position(explain_dropdown_2.value)\n", + " qprof2.get_qplan_explain()\n", + " \n", + " button_run_explain_plan_2.on_click(on_button_clicked_run_explain_plan_2)\n", + " left_side = widgets.VBox([explain_dropdown_1, button_run_explain_plan_1, explain_output_1])\n", + " left_side.layout.width = '50%'\n", + " right_side = widgets.VBox([explain_dropdown_2, button_run_explain_plan_2, explain_output_2])\n", + " right_side.layout.width = '50%'\n", "\n", - "button_run_explain_plan.on_click(on_button_clicked_run_explain_plan)\n", - "explain_plan_widget = widgets.VBox([explain_dropdown, button_run_explain_plan, explain_output]) " + " vertica_border_line = widgets.HTML(\"\"\"\n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " \n", + " \n", + " \"\"\") \n", + " explain_plan_widget = widgets.HBox([left_side,vertica_border_line, right_side])\n", + "else:\n", + " button_run_explain_plan = widgets.Button(description=\"Run Explain Plan\")\n", + " explain_output = widgets.Output()\n", + " try:\n", + " explain_dropdown_options = [i for i in range(len(qprof.transactions))]\n", + " explain_dropdown_disabled = False\n", + " except Exception as e:\n", + " explain_dropdown_options = []\n", + " explain_dropdown_disabled = True\n", + " \n", + " explain_dropdown = widgets.Dropdown(\n", + " options=explain_dropdown_options,\n", + " description='Select Query Index',\n", + " disabled=explain_dropdown_disabled,\n", + " layout={'width': \"300px\"}\n", + " )\n", + " explain_dropdown.style.description_width = '130px'\n", + " \n", + " def on_button_clicked_run_explain_plan(b):\n", + " explain_output.clear_output()\n", + " with explain_output:\n", + " qprof.set_position(explain_dropdown.value)\n", + " qprof.get_qplan_explain()\n", + " \n", + " button_run_explain_plan.on_click(on_button_clicked_run_explain_plan)\n", + " explain_plan_widget = widgets.VBox([explain_dropdown, button_run_explain_plan, explain_output]) \n", + " " ] }, { @@ -1595,7 +1753,11 @@ " consistency_check_out.clear_output(wait=True)\n", " with consistency_check_out:\n", " try:\n", - " qprof._check_v_table(ignore_operators_check=False)\n", + " if comparison:\n", + " qprof1._check_v_table(ignore_operators_check=False)\n", + " qprof2._check_v_table(ignore_operators_check=False)\n", + " else:\n", + " qprof._check_v_table(ignore_operators_check=False)\n", " except Exception as e:\n", " print(e)\n", " consistency_check_button.disabled = False\n", diff --git a/project/ui/qprof_main.ipynb b/project/ui/qprof_main.ipynb index 22767626..19895cc0 100644 --- a/project/ui/qprof_main.ipynb +++ b/project/ui/qprof_main.ipynb @@ -85,7 +85,29 @@ "metadata": {}, "outputs": [], "source": [ - "def reset_values(query_val = None, key_val = None, target_schema_val = None, transaction_val = None, statement_val = None, file_val = None, key_val_2 = None, target_schema_val_2 = None, transaction_statement_list_val = None, control_query_val = None): \n", + "def reset_values(query_val = None, \n", + " key_val = None, \n", + " target_schema_val = None, \n", + " transaction_val = None, \n", + " statement_val = None, \n", + " file_val = None, \n", + " key_val_2 = None, \n", + " target_schema_val_2 = None, \n", + " transaction_statement_list_val = None, \n", + " control_query_val = None,\n", + " transaction_comp1_val = None,\n", + " statement_comp1_val = None, \n", + " target_schema_comp1_val = None, \n", + " key_comp1_val = None, \n", + " query_comp1_val = None,\n", + " session_control_1_val = None,\n", + " transaction_comp2_val = None, \n", + " statement_comp2_val = None, \n", + " target_schema_comp2_val = None, \n", + " key_comp2_val = None, \n", + " query_comp2_val = None,\n", + " session_control_2_val = None\n", + " ):\n", " if query_val:\n", " %store query_val\n", " else:\n", @@ -126,6 +148,80 @@ " %store control_query_val\n", " else:\n", " %store -d control_query_val\n", + " \n", + " # Check and store for transaction_comp1_val\n", + " if transaction_comp1_val:\n", + " %store transaction_comp1_val\n", + " else:\n", + " %store -d transaction_comp1_val\n", + " \n", + " # Check and store for statement_comp1_val\n", + " if statement_comp1_val:\n", + " %store statement_comp1_val\n", + " else:\n", + " %store -d statement_comp1_val\n", + " \n", + " # Check and store for target_schema_comp1_val\n", + " if target_schema_comp1_val:\n", + " %store target_schema_comp1_val\n", + " else:\n", + " %store -d target_schema_comp1_val\n", + " \n", + " # Check and store for key_comp1_val\n", + " if key_comp1_val:\n", + " %store key_comp1_val\n", + " else:\n", + " %store -d key_comp1_val\n", + " \n", + " # Check and store for query_comp1_val\n", + " if query_comp1_val:\n", + " %store query_comp1_val\n", + " else:\n", + " %store -d query_comp1_val\n", + "\n", + " # Check and store for session_control_1_val\n", + " if session_control_1_val:\n", + " %store session_control_1_val\n", + " else:\n", + " %store -d session_control_1_val \n", + " \n", + " # Check and store for transaction_comp2_val\n", + " if transaction_comp2_val:\n", + " %store transaction_comp2_val\n", + " else:\n", + " %store -d transaction_comp2_val\n", + " \n", + " # Check and store for statement_comp2_val\n", + " if statement_comp2_val:\n", + " %store statement_comp2_val\n", + " else:\n", + " %store -d statement_comp2_val\n", + " \n", + " # Check and store for target_schema_comp2_val\n", + " if target_schema_comp2_val:\n", + " %store target_schema_comp2_val\n", + " else:\n", + " %store -d target_schema_comp2_val\n", + " \n", + " # Check and store for key_comp2_val\n", + " if key_comp2_val:\n", + " %store key_comp2_val\n", + " else:\n", + " %store -d key_comp2_val\n", + " \n", + " # Check and store for query_comp2_val\n", + " if query_comp2_val:\n", + " %store query_comp2_val\n", + " else:\n", + " %store -d query_comp2_val\n", + "\n", + " # Check and store for session_control_2_val\n", + " if session_control_2_val:\n", + " %store session_control_2_val\n", + " else:\n", + " %store -d session_control_2_val \n", + "\n", + " \n", " notebook_url = '/voila/render/ui/qprof-ui.ipynb'\n", " display(HTML(f\"\"))" ] @@ -353,9 +449,6 @@ "metadata": {}, "outputs": [], "source": [ - "import ipywidgets as widgets\n", - "from IPython.display import display\n", - "\n", "def create_tooltip(text):\n", " # Create an info icon using HTML\n", " info_icon = widgets.HTML(\n", @@ -702,6 +795,90 @@ "\"\"\")" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "9119a634-0e74-4018-b983-4a47c4c1da27", + "metadata": {}, + "outputs": [], + "source": [ + "# FOR COMPARISON SECTION\n", + "# Function to update the options of key_dropdown_comp1 based on the selection of schema_dropdown_comp1\n", + "def update_key_dropdown_comp1_options(change):\n", + " selected_schema = change.new\n", + " length_to_remove = len(\"qprof_dc_explain_plans_\") + 1\n", + " query = f\"SELECT SUBSTR(table_name, {length_to_remove}) AS 'table_name' FROM (SELECT DISTINCT table_name FROM tables WHERE table_name LIKE '%_dc_explain_plans_%' AND table_schema = '{selected_schema}') as foo order by 1;\"\n", + " vdf = vp.vDataFrame(query)\n", + " key_dropdown_comp1.options = [i[0] for i in vdf.to_list()]\n", + "\n", + "# Function to observe the value of key_dropdown_comp1 and schema_dropdown_comp1, disabling both if user values are present\n", + "def observe_value_change_comp1(change):\n", + " if key_1.value or target_schema_1.value:\n", + " schema_dropdown_comp1.disabled = True\n", + " key_dropdown_comp1.disabled = True\n", + " else:\n", + " schema_dropdown_comp1.disabled = False\n", + " key_dropdown_comp1.disabled = False\n", + "\n", + "# Create schema_dropdown_comp1\n", + "schema_dropdown_comp1 = widgets.Dropdown(\n", + " options=schema_dropdown_options,\n", + " value=None,\n", + " description='Schema List',\n", + " disabled=False,\n", + " layout={'width': \"250px\"}\n", + ")\n", + "schema_dropdown_comp1.style.description_width = '100px'\n", + "\n", + "# Create key_dropdown_comp1\n", + "key_dropdown_comp1 = widgets.Dropdown(\n", + " options=[], # Initial options, will be updated dynamically\n", + " description='Key List',\n", + " disabled=False,\n", + " layout={'width': \"250px\"}\n", + ")\n", + "key_dropdown_comp1.style.description_width = '100px'\n", + "\n", + "\n", + "\n", + "# Function to update the options of key_dropdown_comp2 based on the selection of schema_dropdown_comp2\n", + "def update_key_dropdown_comp2_options(change):\n", + " selected_schema = change.new\n", + " length_to_remove = len(\"qprof_dc_explain_plans_\") + 1\n", + " query = f\"SELECT SUBSTR(table_name, {length_to_remove}) AS 'table_name' FROM (SELECT DISTINCT table_name FROM tables WHERE table_name LIKE '%_dc_explain_plans_%' AND table_schema = '{selected_schema}') as foo order by 1;\"\n", + " vdf = vp.vDataFrame(query)\n", + " key_dropdown_comp2.options = [i[0] for i in vdf.to_list()]\n", + "\n", + "# Function to observe the value of key_dropdown_comp2 and schema_dropdown_comp2, disabling both if user values are present\n", + "def observe_value_change_comp2(change):\n", + " if key_2.value or target_schema_2.value:\n", + " schema_dropdown_comp2.disabled = True\n", + " key_dropdown_comp2.disabled = True\n", + " else:\n", + " schema_dropdown_comp2.disabled = False\n", + " key_dropdown_comp2.disabled = False\n", + "\n", + "# Create schema_dropdown_comp2\n", + "schema_dropdown_comp2 = widgets.Dropdown(\n", + " options=schema_dropdown_options,\n", + " value=None,\n", + " description='Schema List',\n", + " disabled=False,\n", + " layout={'width': \"250px\"}\n", + ")\n", + "schema_dropdown_comp2.style.description_width = '100px'\n", + "\n", + "# Create key_dropdown_comp2\n", + "key_dropdown_comp2 = widgets.Dropdown(\n", + " options=[], # Initial options, will be updated dynamically\n", + " description='Key List',\n", + " disabled=False,\n", + " layout={'width': \"250px\"}\n", + ")\n", + "key_dropdown_comp2.style.description_width = '100px'\n", + "\n" + ] + }, { "cell_type": "code", "execution_count": null, @@ -714,6 +891,225 @@ "left_section" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "72d293fa-141f-4a2a-813b-3d59b986c282", + "metadata": {}, + "outputs": [], + "source": [ + "comparison_section_heading = widgets.HTML(\"\"\"

Compare any two queries

\"\"\")\n", + "\n", + "# Query # 1 Section\n", + "comparison_section_heading_query_1 = widgets.HTML(\"\"\"

Query # 1

\"\"\")\n", + "target_schema_1 = widgets.Text(description=\"Target Schema\", placeholder=\"Schema for Query # 1\", layout=widgets.Layout(width='300px'))\n", + "target_schema_1.style.description_width = '100px'\n", + "target_schema_1_combo = widgets.HBox([target_schema_1, \n", + " create_tooltip(\"Enter the Target Schema of the saved query profile. If you enter this, the below transaction id and statement id will not be used.\"),\n", + " widgets.HTML(html_arrow),\n", + " schema_dropdown_comp1])\n", + "key_1 = widgets.Text(description=\"Key ID\", placeholder=\"Key ID for Query # 1\", layout=widgets.Layout(width='300px'))\n", + "key_1.style.description_width = '100px'\n", + "key_1_combo = widgets.HBox([key_1,create_tooltip(\"Enter the unique Key ID. If you enter this, the below transaction id and statement id will not be used\"),\n", + " widgets.HTML(html_arrow),\n", + " key_dropdown_comp1\n", + " ])\n", + "\n", + "\n", + "# Set observers for schema_dropdown_comp1 and key_dropdown_comp1\n", + "schema_dropdown_comp1.observe(update_key_dropdown_comp1_options, names='value')\n", + "key_1.observe(observe_value_change_comp1, names='value')\n", + "target_schema_1.observe(observe_value_change_comp1, names='value')\n", + "\n", + "\n", + "transaction_id_1 = widgets.Text(description=\"Transaction ID\", placeholder=\"Transaction ID for Query # 1\", layout=widgets.Layout(width='300px'))\n", + "transaction_id_1.style.description_width = '100px'\n", + "transaction_id_1_combo = widgets.HBox([transaction_id_1, create_tooltip(\"Enter the transaction ID of the query that you want to profile.\")])\n", + "statement_id_1 = widgets.Text(description=\"Statement ID\", placeholder=\"Statement ID for Query # 1\", layout=widgets.Layout(width='300px'))\n", + "statement_id_1.style.description_width = '100px'\n", + "statement_id_1_combo = widgets.HBox([statement_id_1, create_tooltip(\"Enter the statement ID of the query that you want to profile.\")])\n", + "query_1 = widgets.Text(description=\"SQL Query\", placeholder=\"SQL for Query # 1\", layout=widgets.Layout(width='600px'))\n", + "query_1.style.description_width = '100px'\n", + "query_1_combo = widgets.HBox([query_1, create_tooltip(\"Enter the SQL Query for Query # 1.\")])\n", + "session_control_1 = widgets.Text( \n", + " placeholder='E.g. ALTER SESSION SET statement_mem = 100000000;',\n", + " description='Session Control SQL:',\n", + " disabled=False,\n", + " layout=widgets.Layout(width='600px')\n", + ")\n", + "session_control_1.style.description_width = '150px'\n", + "session_control_1_combo = widgets.HBox([session_control_1, create_tooltip(\"Enter the session control SQL that you want to run before your query. This is useful if you want to control the session parameters for your query. For example, you can use this to set the statement memory for your query. You can even enter multiple statements by separating them with a semicolon.\"),])\n", + "\n", + "\n", + "comparison_section_query_1 = widgets.VBox([comparison_section_heading_query_1, target_schema_1_combo, key_1_combo, transaction_id_1_combo, statement_id_1_combo, query_1_combo, session_control_1_combo])\n", + "comparison_section_query_1.layout.width = \"50%\"\n", + "# Query # 2 Section\n", + "comparison_section_heading_query_2 = widgets.HTML(\"\"\"

Query # 2

\"\"\")\n", + "target_schema_2 = widgets.Text(description=\"Target Schema\", placeholder=\"Schema for Query # 2\", layout=widgets.Layout(width='300px'))\n", + "target_schema_2.style.description_width = '100px'\n", + "target_schema_2_combo = widgets.HBox([target_schema_2,\n", + " create_tooltip(\"Enter the Target Schema of the saved query profile. If you enter this, the below transaction id and statement id will not be used.\"),\n", + " widgets.HTML(html_arrow),schema_dropdown_comp2])\n", + "key_2 = widgets.Text(description=\"Key ID\", placeholder=\"Key ID for Query # 2\", layout=widgets.Layout(width='300px'))\n", + "key_2.style.description_width = '100px'\n", + "key_2_combo = widgets.HBox([key_2,\n", + " create_tooltip(\"Enter the unique Key ID. If you enter this, the below transaction id and statement id will not be used\"),\n", + " widgets.HTML(html_arrow),\n", + " key_dropdown_comp2])\n", + "# Set observers for schema_dropdown_comp2 and\n", + "schema_dropdown_comp2.observe(update_key_dropdown_comp2_options, names='value')\n", + "key_2.observe(observe_value_change_comp2, names='value')\n", + "target_schema_2.observe(observe_value_change_comp2, names='value')\n", + "\n", + "transaction_id_2 = widgets.Text(description=\"Transaction ID\", placeholder=\"Transaction ID for Query # 2\", layout=widgets.Layout(width='300px'))\n", + "transaction_id_2.style.description_width = '100px'\n", + "transaction_id_2_combo = widgets.HBox([transaction_id_2, create_tooltip(\"Enter the transaction ID of the query that you want to profile.\")])\n", + "statement_id_2 = widgets.Text(description=\"Statement ID\", placeholder=\"Statement ID for Query # 2\", layout=widgets.Layout(width='300px'))\n", + "statement_id_2.style.description_width = '100px'\n", + "statement_id_2_combo = widgets.HBox([statement_id_2, create_tooltip(\"Enter the statement ID of the query that you want to profile.\")])\n", + "query_2 = widgets.Text(description=\"SQL Query\", placeholder=\"SQL for Query # 2\", layout=widgets.Layout(width='600px'))\n", + "query_2.style.description_width = '100px'\n", + "query_2_combo = widgets.HBox([query_2, create_tooltip(\"Enter the SQL Query for Query # 2.\")])\n", + "session_control_2 = widgets.Text( \n", + " placeholder='E.g. ALTER SESSION SET statement_mem = 100000000;',\n", + " description='Session Control SQL:',\n", + " disabled=False,\n", + " layout=widgets.Layout(width='600px')\n", + ")\n", + "session_control_2.style.description_width = '150px'\n", + "session_control_2_combo = widgets.HBox([session_control_2, create_tooltip(\"Enter the session control SQL that you want to run before your query. This is useful if you want to control the session parameters for your query. For example, you can use this to set the statement memory for your query. You can even enter multiple statements by separating them with a semicolon.\"),])\n", + "\n", + "comparison_section_query_2 = widgets.VBox([comparison_section_heading_query_2, target_schema_2_combo, key_2_combo, transaction_id_2_combo, statement_id_2_combo, query_2_combo, session_control_2_combo])\n", + "comparison_section_query_2.layout.width = \"50%\"\n", + "# Combine both query sections in a HBox\n", + "comparison_section_boxes = widgets.HBox([comparison_section_query_1, comparison_section_query_2])\n", + "\n", + "\n", + "\n", + "comparison_section_button = widgets.Button(description=\"Compare\")\n", + "output_comparison_section = widgets.Output()\n", + "transaction_comp1_val = None\n", + "statement_comp1_val = None\n", + "target_schema_comp1_val = None\n", + "key_comp1_val = None\n", + "query_comp1_val = None\n", + "session_control_1_val = None\n", + "transaction_comp2_val = None\n", + "statement_comp2_val = None\n", + "target_schema_comp2_val = None\n", + "key_comp2_val = None\n", + "query_comp2_val = None\n", + "session_control_2_val = None\n", + "# ... existing code ...\n", + "def on_button_clicked_comparison(b):\n", + " output_comparison_section.clear_output(wait=True)\n", + " global transaction_comp1_val, statement_comp1_val, target_schema_comp1_val, key_comp1_val, query_comp1_val, session_control_1_val\n", + " global transaction_comp2_val, statement_comp2_val, target_schema_comp2_val, key_comp2_val, query_comp2_val, session_control_2_val\n", + " \n", + " with output_comparison_section:\n", + " # Capture input values\n", + " transaction_comp1_val = transaction_id_1.value\n", + " statement_comp1_val = statement_id_1.value # Capture Statement ID\n", + " target_schema_comp1_val = target_schema_1.value if target_schema_1.value != \"\" else schema_dropdown_comp1.value # Capture Target Schema\n", + " key_comp1_val = key_1.value if key_1.value != \"\" else key_dropdown_comp1.value # Capture Key ID\n", + " query_comp1_val = query_1.value # Capture SQL Query\n", + " session_control_1_val = session_control_1.value\n", + " \n", + " transaction_comp2_val = transaction_id_2.value\n", + " statement_comp2_val = statement_id_2.value # Capture Statement ID\n", + " target_schema_comp2_val = target_schema_2.value if target_schema_2.value != \"\" else schema_dropdown_comp2.value # Capture Target Schema\n", + " key_comp2_val = key_2.value if key_2.value != \"\" else key_dropdown_comp2.value # Capture Key ID\n", + " query_comp2_val = query_2.value # Capture SQL Query\n", + " session_control_2_val = session_control_2.value\n", + " \n", + " # Determine cases for Query # 1\n", + " case_1 = None\n", + " if transaction_comp1_val:\n", + " if statement_comp1_val:\n", + " case_1 = 0\n", + " else:\n", + " print(\"\\033[91m\\033[1m Error! Missing Statement ID for Query # 1. \\033[0m\\033[0m\")\n", + " return # Added return to exit the function\n", + " elif target_schema_comp1_val or key_comp1_val:\n", + " case_1 = 1 \n", + " if not schema_exists(target_schema_comp1_val):\n", + " print(\"\\033[91m\\033[1m Error! The schema does not exist for Query # 1. \\033[0m\\033[0m\")\n", + " return\n", + " elif query_comp1_val:\n", + " case_1 = 2\n", + " if not query_check(query_comp1_val):\n", + " print(\"\\033[91m\\033[1m Error! Re-check your query for Query # 1. \\033[0m\\033[0m\")\n", + " return\n", + " else:\n", + " print(\"\\033[91m\\033[1m Error! No details for Query # 1. \\033[0m\\033[0m\")\n", + " return\n", + " \n", + " # Determine cases for Query # 2\n", + " case_2 = None\n", + " if transaction_comp2_val:\n", + " if statement_comp2_val:\n", + " case_2 = 0\n", + " else:\n", + " print(\"\\033[91m\\033[1m Error! Missing Statement ID for Query # 2. \\033[0m\\033[0m\")\n", + " return # Added return to exit the function\n", + " elif target_schema_comp2_val or key_comp2_val:\n", + " case_2 = 1 \n", + " if not schema_exists(target_schema_comp2_val):\n", + " print(\"\\033[91m\\033[1m Error! The schema does not exist for Query # 2. \\033[0m\\033[0m\")\n", + " return\n", + " elif query_comp2_val:\n", + " case_2 = 2\n", + " if not query_check(query_comp2_val):\n", + " print(\"\\033[91m\\033[1m Error! Re-check your query for Query # 2. \\033[0m\\033[0m\")\n", + " return\n", + " else:\n", + " print(\"\\033[91m\\033[1m Error! No details for Query # 2. \\033[0m\\033[0m\")\n", + " return\n", + " \n", + " # Call reset function based on cases\n", + " reset_params = {}\n", + " \n", + " # Populate reset_params based on case combinations\n", + " if case_1 == 0:\n", + " reset_params.update({\n", + " 'transaction_comp1_val': transaction_comp1_val,\n", + " 'statement_comp1_val': statement_comp1_val\n", + " })\n", + " if case_1 == 1:\n", + " reset_params.update({\n", + " 'target_schema_comp1_val': target_schema_comp1_val,\n", + " 'key_comp1_val': key_comp1_val\n", + " })\n", + " if case_1 == 2:\n", + " reset_params.update({\n", + " 'query_comp1_val': query_comp1_val,\n", + " 'session_control_2_val': session_control_2_val if session_control_2_val != \"\" else None\n", + " })\n", + " \n", + " if case_2 == 0:\n", + " reset_params.update({\n", + " 'transaction_comp2_val': transaction_comp2_val,\n", + " 'statement_comp2_val': statement_comp2_val\n", + " })\n", + " if case_2 == 1:\n", + " reset_params.update({\n", + " 'target_schema_comp2_val': target_schema_comp2_val,\n", + " 'key_comp2_val': key_comp2_val\n", + " })\n", + " if case_2 == 2:\n", + " reset_params.update({\n", + " 'query_comp2_val': query_comp2_val,\n", + " 'session_control_1_val': session_control_1_val if session_control_1_val != \"\" else None\n", + " })\n", + " \n", + " # Call the reset function with the collected parameters\n", + " reset_values(**reset_params)\n", + " \n", + "comparison_section_button.on_click(on_button_clicked_comparison)\n", + "\n", + "comparison_section = widgets.VBox([comparison_section_heading, comparison_section_boxes, comparison_section_button, output_comparison_section], layout= {\"margin\" :\"0px 0px 0px 50px\"})" + ] + }, { "cell_type": "markdown", "id": "394c1468-eb63-4638-8035-e3170a1265b0", @@ -740,6 +1136,24 @@ "_____" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "1611f857-055f-432f-98c8-e4d4a069b34a", + "metadata": {}, + "outputs": [], + "source": [ + "comparison_section" + ] + }, + { + "cell_type": "markdown", + "id": "b598d686-902d-4dee-925d-58ccb26a06df", + "metadata": {}, + "source": [ + "_____" + ] + }, { "cell_type": "code", "execution_count": null,