///////////////////////////////////////////////////////////// // // pgAdmin 4 - PostgreSQL Tools // // Copyright (C) 2013 - 2024, The pgAdmin Development Team // This software is released under the PostgreSQL Licence // ////////////////////////////////////////////////////////////// import { makeStyles } from '@material-ui/styles'; import React from 'react'; import clsx from 'clsx'; import _ from 'lodash'; import ArrowRightAltIcon from '@material-ui/icons/ArrowRightAlt'; import FiberManualRecordIcon from '@material-ui/icons/FiberManualRecord'; import HTMLReactParse from 'html-react-parser'; import { commonTableStyles } from '../Theme'; import PropTypes from 'prop-types'; import gettext from 'sources/gettext'; const useStyles = makeStyles((theme)=>({ collapsible: { cursor: 'pointer', }, collapseParent: { borderBottom: '2px dashed '+theme.palette.primary.main, }, level2: { backgroundColor: theme.otherVars.explain.sev2.bg, color: theme.otherVars.explain.sev2.color, }, level3: { backgroundColor: theme.otherVars.explain.sev3.bg, color: theme.otherVars.explain.sev3.color, }, level4: { backgroundColor: theme.otherVars.explain.sev4.bg, color: theme.otherVars.explain.sev4.color, }, textRight: { textAlign: 'right', }, })); function getRowClassname(classes, data, collapseParent) { let className = []; if(data['Plans']?.length > 0) { className.push(classes.collapsible); } if(collapseParent) { className.push(classes.collapseParent); } return className; } function NodeText({displayText, extraInfo}) { return ( <> {displayText} {extraInfo?.length > 0 && } ); } NodeText.propTypes = { displayText: PropTypes.string, extraInfo: PropTypes.array, }; function ExplainRow({row, show, activeExId, setActiveExId, collapsedExId, toggleCollapseExId}) { let data = row['data']; const classes = useStyles(); const exId = `pga_ex_${data['level'].join('_')}`; const parentExId = `pga_ex_${data['parent_node']}`; const collapsed = collapsedExId.findIndex((v)=>parentExId.startsWith(v)) > -1; const className = getRowClassname(classes, data, collapsedExId.indexOf(exId) > -1); let onRowClick = (e)=>{ toggleCollapseExId(e.currentTarget.getAttribute('data-ex-id'), data['Plans']?.length); }; return ( {setActiveExId(e.currentTarget.getAttribute('data-ex-id'));}} onMouseLeave={()=>{setActiveExId(null);}} className={clsx(className)} data-parent={parentExId} data-ex-id={`pga_ex_${data['level'].join('_')}`} style={collapsed ? {display: 'none'} : {}} onClick={onRowClick}> {data['_serial']}. {data['exclusive'] && (data['exclusive']+' ms')} {data['inclusive'] && (data['inclusive']+' ms')} {!_.isUndefined(data['rowsx_flag']) && (data['rowsx_direction'] == 'positive' ? <>↑ : <>↓) } {data['rowsx']} {data['Actual Rows']} {data['Plan Rows']} {data['Actual Loops']} ); } ExplainRow.propTypes = { row: PropTypes.shape({ data: PropTypes.shape({ Plans: PropTypes.array, level: PropTypes.array, _serial: PropTypes.number, parent_node: PropTypes.string, exclusive: PropTypes.number, exclusive_flag: PropTypes.string, inclusive: PropTypes.number, inclusive_flag: PropTypes.string, rowsx_direction: PropTypes.string, rowsx: PropTypes.number, rowsx_flag: PropTypes.oneOfType([PropTypes.number,PropTypes.string]), 'Actual Rows': PropTypes.number, 'Plan Rows': PropTypes.number, 'Actual Loops': PropTypes.number, }), node_extra_info: PropTypes.array, display_text: PropTypes.string, tooltip_text: PropTypes.string, }), show: PropTypes.shape({ show_timings: PropTypes.bool, show_rowsx: PropTypes.bool, show_rows: PropTypes.bool, show_plan_rows: PropTypes.bool, }), activeExId: PropTypes.string, setActiveExId: PropTypes.func, collapsedExId: PropTypes.array, toggleCollapseExId: PropTypes.func, }; export default function Analysis({explainTable}) { const tableClasses = commonTableStyles(); const [activeExId, setActiveExId] = React.useState(); const [collapsedExId, setCollapsedExId] = React.useState([]); const toggleCollapseExId = (exId, hasPlans=true)=>{ if(hasPlans) { setCollapsedExId((prev)=>{ if(prev.indexOf(exId) > -1) { return prev.filter((v)=>v!=exId); } return [...prev, exId]; }); } }; return {_.sortBy(explainTable.rows,(r)=>r['data']['_serial']).map((row)=>{ return ; })}
; } Analysis.propTypes = { explainTable: PropTypes.object, };