Added GENERIC_PLAN, MEMORY, SERIALIZE option to EXPLAIN/EXPLAIN ANALYZE command. #6456
							parent
							
								
									1f7fbb91f7
								
							
						
					
					
						commit
						559c6cfa65
					
				
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 81 KiB  | 
| 
						 | 
				
			
			@ -140,20 +140,27 @@ Query Execution
 | 
			
		|||
   |                      |                                                                                                   |                |
 | 
			
		||||
   |                      | Navigate through the *Explain Options* menu to select options for the EXPLAIN command:            |                |
 | 
			
		||||
   |                      |                                                                                                   |                |
 | 
			
		||||
   |                      |  * Select *Verbose* to display additional information regarding the query plan.                   |                |
 | 
			
		||||
   |                      |  * Select *Buffers* to include information on buffer usage.                                       |                |
 | 
			
		||||
   |                      |                                                                                                   |                |
 | 
			
		||||
   |                      |  * Select *Costs* to include information on the estimated startup and total cost of each          |                |
 | 
			
		||||
   |                      |    plan node, as well as the estimated number of rows and the estimated width of each             |                |
 | 
			
		||||
   |                      |    row.                                                                                           |                |
 | 
			
		||||
   |                      |                                                                                                   |                |
 | 
			
		||||
   |                      |  * Select *Buffers* to include information on buffer usage.                                       |                |
 | 
			
		||||
   |                      |  * Select *Generic Plan* to include the information on the Generic Plan.                          |                |
 | 
			
		||||
   |                      |                                                                                                   |                |
 | 
			
		||||
   |                      |  * Select *Memory* to include the information on memory consumption by the query planning phase.  |                |
 | 
			
		||||
   |                      |                                                                                                   |                |
 | 
			
		||||
   |                      |  * Select *Serialize* to include information on the cost of serializing the query's output data,  |                |
 | 
			
		||||
   |                      |    that is converting it to text or binary format to send to the client.                          |                |
 | 
			
		||||
   |                      |                                                                                                   |                |
 | 
			
		||||
   |                      |  * Select *Settings* to include the information on the configuration parameters.                  |                |
 | 
			
		||||
   |                      |                                                                                                   |                |
 | 
			
		||||
   |                      |  * Select *Summary* to include the summary information about the query plan.                      |                |
 | 
			
		||||
   |                      |                                                                                                   |                |
 | 
			
		||||
   |                      |  * Select *Timing* to include information about the startup time and the amount of time           |                |
 | 
			
		||||
   |                      |    spent in each node of the query.                                                               |                |
 | 
			
		||||
   |                      |                                                                                                   |                |
 | 
			
		||||
   |                      |  * Select *Summary* to include the summary information about the query plan.                      |                |
 | 
			
		||||
   |                      |                                                                                                   |                |
 | 
			
		||||
   |                      |  * Select *Settings* to include the information on the configuration parameters.                  |                |
 | 
			
		||||
   |                      |  * Select *Verbose* to display additional information regarding the query plan.                   |                |
 | 
			
		||||
   |                      |                                                                                                   |                |
 | 
			
		||||
   |                      |  * Select *Wal* to include the information on WAL record generation.                              |                |
 | 
			
		||||
   +----------------------+---------------------------------------------------------------------------------------------------+----------------+
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,6 +20,9 @@ Bundled PostgreSQL Utilities
 | 
			
		|||
New features
 | 
			
		||||
************
 | 
			
		||||
 | 
			
		||||
  | `Issue #5766 <https://github.com/pgadmin-org/pgadmin4/issues/5766>`_ -  Add support for automatic updates in the pgAdmin 4 Desktop application on macOS.
 | 
			
		||||
  | `Issue #6456 <https://github.com/pgadmin-org/pgadmin4/issues/6456>`_ -  Added GENERIC_PLAN, MEMORY, SERIALIZE option to EXPLAIN/EXPLAIN ANALYZE command.
 | 
			
		||||
  | `Issue #8917 <https://github.com/pgadmin-org/pgadmin4/issues/8917>`_ -  Add support for server tag-based filtering in the Object Explorer.
 | 
			
		||||
 | 
			
		||||
Housekeeping
 | 
			
		||||
************
 | 
			
		||||
| 
						 | 
				
			
			@ -30,7 +33,11 @@ Housekeeping
 | 
			
		|||
Bug fixes
 | 
			
		||||
*********
 | 
			
		||||
 | 
			
		||||
  | `Issue #8149 <https://github.com/pgadmin-org/pgadmin4/issues/8149>`_ -  Fixed an issue where pgAdmin failed to update the server connection status when the server was disconnected in the background and a refresh was performed on that server.
 | 
			
		||||
  | `Issue #8650 <https://github.com/pgadmin-org/pgadmin4/issues/8650>`_ -  Make Dashboard tables to be vertically resizable.
 | 
			
		||||
  | `Issue #8756 <https://github.com/pgadmin-org/pgadmin4/issues/8756>`_ -  Fixed an issue in Firefox where the query window would shift to the left after opening the history tab or selecting a column header in the results grid.
 | 
			
		||||
  | `Issue #8867 <https://github.com/pgadmin-org/pgadmin4/issues/8867>`_ -  Ensure DB restriction type is preserved while import and export server.
 | 
			
		||||
  | `Issue #8969 <https://github.com/pgadmin-org/pgadmin4/issues/8969>`_ -  Fixed incorrect behaviour of the option deduplicate items after creating the index.
 | 
			
		||||
  | `Issue #8969 <https://github.com/pgadmin-org/pgadmin4/issues/8969>`_ -  Fixed incorrect behaviour of the option deduplicate items after creating the index.
 | 
			
		||||
  | `Issue #8971 <https://github.com/pgadmin-org/pgadmin4/issues/8971>`_ -  Added PKEY index in the index statistics summary.
 | 
			
		||||
  | `Issue #9007 <https://github.com/pgadmin-org/pgadmin4/issues/9007>`_ -  Ensure the scratch pad in the Query Tool is not restored after it is closed.
 | 
			
		||||
  | `Issue #9008 <https://github.com/pgadmin-org/pgadmin4/issues/9008>`_ -  Update the documentation for parameters that require file paths.
 | 
			
		||||
| 
						 | 
				
			
			@ -57,14 +57,18 @@ PgMenu.propTypes = {
 | 
			
		|||
  menuButton: PropTypes.element,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const PgSubMenu = (({label, ...props})=>{
 | 
			
		||||
export const PgSubMenu = (({label, alignCheck, ...props})=>{
 | 
			
		||||
  if(alignCheck) {
 | 
			
		||||
    label = <><CheckIcon style={{visibility: 'hidden', width: '1.3rem'}} data-label="CheckIcon"/>{label}</>;
 | 
			
		||||
  }
 | 
			
		||||
  return (
 | 
			
		||||
    <SubMenu label={label}  itemProps={{'data-label': label}} {...props} />
 | 
			
		||||
  );
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
PgSubMenu.propTypes = {
 | 
			
		||||
  label: PropTypes.string
 | 
			
		||||
  label: PropTypes.string,
 | 
			
		||||
  alignCheck: PropTypes.bool
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const PgMenuItem = (({hasCheck=false, checked=false, accesskey, shortcut, children, closeOnCheck=false, ...props})=>{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -915,7 +915,7 @@ def start_view_data(trans_id):
 | 
			
		|||
            if response is not None:
 | 
			
		||||
                return response
 | 
			
		||||
 | 
			
		||||
        status, msg = default_conn.connect()
 | 
			
		||||
        status, _ = default_conn.connect()
 | 
			
		||||
        if not status:
 | 
			
		||||
            return service_unavailable(
 | 
			
		||||
                gettext("Connection to the server has been lost."),
 | 
			
		||||
| 
						 | 
				
			
			@ -1535,7 +1535,7 @@ def save(trans_id):
 | 
			
		|||
            if response is not None:
 | 
			
		||||
                return response
 | 
			
		||||
 | 
			
		||||
        is_error, errmsg, conn = _check_and_connect(trans_obj)
 | 
			
		||||
        is_error, _, conn = _check_and_connect(trans_obj)
 | 
			
		||||
        if is_error:
 | 
			
		||||
            return service_unavailable(
 | 
			
		||||
                gettext("Connection to the server has been lost."),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,9 +21,9 @@ import AssessmentRoundedIcon from '@mui/icons-material/AssessmentRounded';
 | 
			
		|||
import ExplicitRoundedIcon from '@mui/icons-material/ExplicitRounded';
 | 
			
		||||
import FormatListNumberedRoundedIcon from '@mui/icons-material/FormatListNumberedRounded';
 | 
			
		||||
import HelpIcon from '@mui/icons-material/HelpRounded';
 | 
			
		||||
import {QUERY_TOOL_EVENTS, CONNECTION_STATUS} from '../QueryToolConstants';
 | 
			
		||||
import {QUERY_TOOL_EVENTS, CONNECTION_STATUS, MODAL_DIALOGS} from '../QueryToolConstants';
 | 
			
		||||
import { QueryToolConnectionContext, QueryToolContext, QueryToolEventsContext } from '../QueryToolComponent';
 | 
			
		||||
import { PgMenu, PgMenuDivider, PgMenuItem, usePgMenuGroup } from '../../../../../../static/js/components/Menu';
 | 
			
		||||
import { PgMenu, PgMenuDivider, PgMenuItem, usePgMenuGroup, PgSubMenu} from '../../../../../../static/js/components/Menu';
 | 
			
		||||
import gettext from 'sources/gettext';
 | 
			
		||||
import { useKeyboardShortcuts } from '../../../../../../static/js/custom_hooks';
 | 
			
		||||
import url_for from 'sources/url_for';
 | 
			
		||||
| 
						 | 
				
			
			@ -34,7 +34,6 @@ import CustomPropTypes from '../../../../../../static/js/custom_prop_types';
 | 
			
		|||
import ConfirmTransactionContent from '../dialogs/ConfirmTransactionContent';
 | 
			
		||||
import { LayoutDocker } from '../../../../../../static/js/helpers/Layout';
 | 
			
		||||
import CloseRunningDialog from '../dialogs/CloseRunningDialog';
 | 
			
		||||
import { MODAL_DIALOGS } from '../QueryToolConstants';
 | 
			
		||||
 | 
			
		||||
const StyledBox = styled(Box)(({theme}) => ({
 | 
			
		||||
  padding: '2px 4px',
 | 
			
		||||
| 
						 | 
				
			
			@ -114,6 +113,10 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros, onAddT
 | 
			
		|||
      summary: Boolean(checkedMenuItems['explain_summary']),
 | 
			
		||||
      settings: Boolean(checkedMenuItems['explain_settings']),
 | 
			
		||||
      wal: analyze ? Boolean(checkedMenuItems['explain_wal']) : false,
 | 
			
		||||
      generic_plan: analyze ? false: Boolean(checkedMenuItems['explain_generic_plan']),
 | 
			
		||||
      memory: Boolean(checkedMenuItems['explain_memory']),
 | 
			
		||||
      serialize_binary: analyze ? Boolean(checkedMenuItems['explain_serialize_binary']) : false,
 | 
			
		||||
      serialize_text: analyze ? Boolean(checkedMenuItems['explain_serialize_text']) : false,
 | 
			
		||||
    });
 | 
			
		||||
  }, [checkedMenuItems]);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -136,9 +139,18 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros, onAddT
 | 
			
		|||
            });
 | 
			
		||||
          });
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      let otherVars = {};
 | 
			
		||||
      if (e.value === 'explain_serialize_binary' && newVal) {
 | 
			
		||||
        otherVars = { 'explain_serialize_text': false };
 | 
			
		||||
      } else if (e.value === 'explain_serialize_text' && newVal) {
 | 
			
		||||
        otherVars = { 'explain_serialize_binary': false };
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return {
 | 
			
		||||
        ...prev,
 | 
			
		||||
        [e.value]: newVal,
 | 
			
		||||
        ...otherVars,
 | 
			
		||||
      };
 | 
			
		||||
    });
 | 
			
		||||
  }, []);
 | 
			
		||||
| 
						 | 
				
			
			@ -274,8 +286,8 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros, onAddT
 | 
			
		|||
  };
 | 
			
		||||
  useEffect(()=>{
 | 
			
		||||
    if(isInTxn()) {
 | 
			
		||||
      setDisableButton('commit', queryToolCtx.params.server_cursor && !queryToolCtx.params.is_query_tool ? true : false);
 | 
			
		||||
      setDisableButton('rollback', queryToolCtx.params.server_cursor && !queryToolCtx.params.is_query_tool ? true : false);
 | 
			
		||||
      setDisableButton('commit', queryToolCtx.params.server_cursor && !queryToolCtx.params.is_query_tool);
 | 
			
		||||
      setDisableButton('rollback', queryToolCtx.params.server_cursor && !queryToolCtx.params.is_query_tool);
 | 
			
		||||
      setDisableButton('execute-options', true);
 | 
			
		||||
    } else {
 | 
			
		||||
      setDisableButton('commit', true);
 | 
			
		||||
| 
						 | 
				
			
			@ -347,6 +359,8 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros, onAddT
 | 
			
		|||
          explain_summary: queryToolPref.explain_summary,
 | 
			
		||||
          explain_settings: queryToolPref.explain_settings,
 | 
			
		||||
          explain_wal: queryToolPref.explain_wal,
 | 
			
		||||
          explain_generic_plan: queryToolPref.explain_generic_plan,
 | 
			
		||||
          explain_memory: queryToolPref.explain_memory,
 | 
			
		||||
          open_in_new_tab: queryToolPref.open_in_new_tab,
 | 
			
		||||
          server_cursor: queryToolPref.server_cursor,
 | 
			
		||||
        });
 | 
			
		||||
| 
						 | 
				
			
			@ -645,18 +659,28 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros, onAddT
 | 
			
		|||
        onClose={onMenuClose}
 | 
			
		||||
        label={gettext('Explain Options Menu')}
 | 
			
		||||
      >
 | 
			
		||||
        <PgMenuItem hasCheck value="explain_verbose" checked={checkedMenuItems['explain_verbose']}
 | 
			
		||||
          onClick={checkMenuClick}>{gettext('Verbose')}</PgMenuItem>
 | 
			
		||||
        <PgMenuItem hasCheck value="explain_costs" checked={checkedMenuItems['explain_costs']}
 | 
			
		||||
          onClick={checkMenuClick}>{gettext('Costs')}</PgMenuItem>
 | 
			
		||||
        <PgMenuItem hasCheck value="explain_buffers" checked={checkedMenuItems['explain_buffers']}
 | 
			
		||||
          onClick={checkMenuClick}>{gettext('Buffers')}</PgMenuItem>
 | 
			
		||||
        <PgMenuItem hasCheck value="explain_timing" checked={checkedMenuItems['explain_timing']}
 | 
			
		||||
          onClick={checkMenuClick}>{gettext('Timing')}</PgMenuItem>
 | 
			
		||||
        <PgMenuItem hasCheck value="explain_summary" checked={checkedMenuItems['explain_summary']}
 | 
			
		||||
          onClick={checkMenuClick}>{gettext('Summary')}</PgMenuItem>
 | 
			
		||||
        <PgMenuItem hasCheck value="explain_costs" checked={checkedMenuItems['explain_costs']}
 | 
			
		||||
          onClick={checkMenuClick}>{gettext('Costs')}</PgMenuItem>
 | 
			
		||||
        <PgMenuItem hasCheck value="explain_generic_plan" checked={checkedMenuItems['explain_generic_plan']}
 | 
			
		||||
          onClick={checkMenuClick}>{gettext('Generic Plan')}</PgMenuItem>
 | 
			
		||||
        <PgMenuItem hasCheck value="explain_memory" checked={checkedMenuItems['explain_memory']}
 | 
			
		||||
          onClick={checkMenuClick}>{gettext('Memory')}</PgMenuItem>
 | 
			
		||||
        <PgSubMenu alignCheck key="SERIALIZE" label={gettext('Serialize')}>
 | 
			
		||||
          <PgMenuItem hasCheck value="explain_serialize_text" checked={checkedMenuItems['explain_serialize_text']}
 | 
			
		||||
            onClick={checkMenuClick}>{gettext('Text')}</PgMenuItem>
 | 
			
		||||
          <PgMenuItem hasCheck value="explain_serialize_binary" checked={checkedMenuItems['explain_serialize_binary']}
 | 
			
		||||
            onClick={checkMenuClick}>{gettext('Binary')}</PgMenuItem>
 | 
			
		||||
        </PgSubMenu>
 | 
			
		||||
        <PgMenuItem hasCheck value="explain_settings" checked={checkedMenuItems['explain_settings']}
 | 
			
		||||
          onClick={checkMenuClick}>{gettext('Settings')}</PgMenuItem>
 | 
			
		||||
        <PgMenuItem hasCheck value="explain_summary" checked={checkedMenuItems['explain_summary']}
 | 
			
		||||
          onClick={checkMenuClick}>{gettext('Summary')}</PgMenuItem>
 | 
			
		||||
        <PgMenuItem hasCheck value="explain_timing" checked={checkedMenuItems['explain_timing']}
 | 
			
		||||
          onClick={checkMenuClick}>{gettext('Timing')}</PgMenuItem>
 | 
			
		||||
        <PgMenuItem hasCheck value="explain_verbose" checked={checkedMenuItems['explain_verbose']}
 | 
			
		||||
          onClick={checkMenuClick}>{gettext('Verbose')}</PgMenuItem>
 | 
			
		||||
        <PgMenuItem hasCheck value="explain_wal" checked={checkedMenuItems['explain_wal']}
 | 
			
		||||
          onClick={checkMenuClick}>{gettext('Wal')}</PgMenuItem>
 | 
			
		||||
      </PgMenu>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
{% import 'sql/macros/utils.macros' as UTILS %}
 | 
			
		||||
EXPLAIN ({% if format -%}
 | 
			
		||||
  FORMAT {{ format.upper() }}
 | 
			
		||||
{%- endif %}{% if analyze is defined -%}
 | 
			
		||||
  , ANALYZE {{ UTILS.BOOL_TEXT(analyze) }}
 | 
			
		||||
{%- endif %}{% if verbose is defined -%}
 | 
			
		||||
  , VERBOSE {{ UTILS.BOOL_TEXT(verbose) }}
 | 
			
		||||
{%- endif %}{% if costs is defined -%}
 | 
			
		||||
  , COSTS {{ UTILS.BOOL_TEXT(costs) }}
 | 
			
		||||
{%- endif %}{% if timing is defined -%}
 | 
			
		||||
  , TIMING {{ UTILS.BOOL_TEXT(timing) }}
 | 
			
		||||
{%- endif %}{% if buffers is defined -%}
 | 
			
		||||
  , BUFFERS {{ UTILS.BOOL_TEXT(buffers) }}
 | 
			
		||||
{%- endif %}{% if summary is defined -%}
 | 
			
		||||
  , SUMMARY {{ UTILS.BOOL_TEXT(summary) }}
 | 
			
		||||
{%- endif %}{% if settings is defined -%}
 | 
			
		||||
  , SETTINGS {{ UTILS.BOOL_TEXT(settings) }}
 | 
			
		||||
{%- endif %}{% if wal is defined -%}
 | 
			
		||||
  , WAL {{ UTILS.BOOL_TEXT(wal) }}
 | 
			
		||||
{%- endif %}{% if generic_plan is defined -%}
 | 
			
		||||
  , GENERIC_PLAN {{ UTILS.BOOL_TEXT(generic_plan) }}
 | 
			
		||||
{%- endif %}) {{ sql }}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,28 @@
 | 
			
		|||
{% import 'sql/macros/utils.macros' as UTILS %}
 | 
			
		||||
EXPLAIN ({% if format -%}
 | 
			
		||||
  FORMAT {{ format.upper() }}
 | 
			
		||||
{%- endif %}{% if analyze is defined -%}
 | 
			
		||||
  , ANALYZE {{ UTILS.BOOL_TEXT(analyze) }}
 | 
			
		||||
{%- endif %}{% if verbose is defined -%}
 | 
			
		||||
  , VERBOSE {{ UTILS.BOOL_TEXT(verbose) }}
 | 
			
		||||
{%- endif %}{% if costs is defined -%}
 | 
			
		||||
  , COSTS {{ UTILS.BOOL_TEXT(costs) }}
 | 
			
		||||
{%- endif %}{% if timing is defined -%}
 | 
			
		||||
  , TIMING {{ UTILS.BOOL_TEXT(timing) }}
 | 
			
		||||
{%- endif %}{% if buffers is defined -%}
 | 
			
		||||
  , BUFFERS {{ UTILS.BOOL_TEXT(buffers) }}
 | 
			
		||||
{%- endif %}{% if summary is defined -%}
 | 
			
		||||
  , SUMMARY {{ UTILS.BOOL_TEXT(summary) }}
 | 
			
		||||
{%- endif %}{% if settings is defined -%}
 | 
			
		||||
  , SETTINGS {{ UTILS.BOOL_TEXT(settings) }}
 | 
			
		||||
{%- endif %}{% if wal is defined -%}
 | 
			
		||||
  , WAL {{ UTILS.BOOL_TEXT(wal) }}
 | 
			
		||||
{%- endif %}{% if generic_plan is defined -%}
 | 
			
		||||
  , GENERIC_PLAN {{ UTILS.BOOL_TEXT(generic_plan) }}
 | 
			
		||||
{%- endif %}{% if memory is defined -%}
 | 
			
		||||
  , MEMORY {{ UTILS.BOOL_TEXT(memory) }}
 | 
			
		||||
{%- endif %}{% if serialize_binary -%}
 | 
			
		||||
  , SERIALIZE BINARY
 | 
			
		||||
{%- endif %}{% if serialize_text -%}
 | 
			
		||||
  , SERIALIZE TEXT
 | 
			
		||||
{%- endif %}) {{ sql }}
 | 
			
		||||
| 
						 | 
				
			
			@ -60,6 +60,18 @@ def register_query_tool_preferences(self):
 | 
			
		|||
        category_label=PREF_LABEL_EXPLAIN
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    self.explain_generic_plan = self.preference.register(
 | 
			
		||||
        'Explain', 'explain_generic_plan',
 | 
			
		||||
        gettext("Show generic plan?"), 'boolean', False,
 | 
			
		||||
        category_label=PREF_LABEL_EXPLAIN
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    self.explain_memory = self.preference.register(
 | 
			
		||||
        'Explain', 'explain_memory',
 | 
			
		||||
        gettext("Show memory?"), 'boolean', False,
 | 
			
		||||
        category_label=PREF_LABEL_EXPLAIN
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    self.auto_commit = self.preference.register(
 | 
			
		||||
        'Options', 'auto_commit',
 | 
			
		||||
        gettext("Auto commit?"), 'boolean', True,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue