({
plans=[],
emptyMessage=gettext('Use the Explain/Explain Analyze button to generate the plan for a query. Alternatively, you can also execute "EXPLAIN (FORMAT JSON) [QUERY]".'),
llmEnabled: llmEnabledProp=false,
sql='',
transId=null,
onInsertSQL=null,
})
| 509 | } |
| 510 | |
| 511 | export default function Explain({ |
| 512 | plans=[], |
| 513 | emptyMessage=gettext('Use the Explain/Explain Analyze button to generate the plan for a query. Alternatively, you can also execute "EXPLAIN (FORMAT JSON) [QUERY]".'), |
| 514 | llmEnabled: llmEnabledProp=false, |
| 515 | sql='', |
| 516 | transId=null, |
| 517 | onInsertSQL=null, |
| 518 | }) { |
| 519 | |
| 520 | const [tabValue, setTabValue] = useState(0); |
| 521 | const [llmEnabled, setLlmEnabled] = useState(llmEnabledProp); |
| 522 | |
| 523 | // Fetch LLM status independently to handle timing issues |
| 524 | useEffect(() => { |
| 525 | const api = getApiInstance(); |
| 526 | api.get(url_for('llm.status')) |
| 527 | .then((res) => { |
| 528 | if (res.data?.success && res.data?.data?.enabled) { |
| 529 | setLlmEnabled(true); |
| 530 | } |
| 531 | }) |
| 532 | .catch(() => { |
| 533 | // LLM not available - this is fine |
| 534 | }); |
| 535 | }, []); |
| 536 | |
| 537 | let ctx = React.useRef({}); |
| 538 | let planData = React.useMemo(()=>{ |
| 539 | ctx.current = { |
| 540 | totalNodes: 0, |
| 541 | totalDownloadedNodes: 0, |
| 542 | isDownloaded: 0, |
| 543 | explainTable: { |
| 544 | rows: [], |
| 545 | statistics: { |
| 546 | tables: {}, |
| 547 | nodes: {}, |
| 548 | }, |
| 549 | }, |
| 550 | arrows: {}, |
| 551 | }; |
| 552 | return plans && parsePlanData(plans[0], ctx.current); |
| 553 | }, [plans]); |
| 554 | |
| 555 | if(_.isEmpty(plans)) { |
| 556 | return ( |
| 557 | <StyledBox height="100%" display="flex" flexDirection="column"> |
| 558 | {emptyMessage && <EmptyPanelMessage text={emptyMessage} />} |
| 559 | </StyledBox> |
| 560 | ); |
| 561 | } |
| 562 | return ( |
| 563 | <StyledBox height="100%" display="flex" flexDirection="column"> |
| 564 | <Box> |
| 565 | <Tabs |
| 566 | value={tabValue} |
| 567 | onChange={(_e, selTabValue) => { |
| 568 | setTabValue(selTabValue); |
nothing calls this directly
no test coverage detected