All Downloads are FREE. Search and download functionalities are using the official Maven repository.

webapp.src.components.QueryDetail.jsx Maven / Gradle / Ivy

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import React from "react";
import Reactable from "reactable";

import {
    addToHistory,
    computeRate,
    formatCount,
    formatDataSize,
    formatDataSizeBytes,
    formatDuration,
    formatShortDateTime,
    getFirstParameter,
    getHostAndPort,
    getHostname,
    getPort,
    getStageNumber,
    getStageStateColor,
    getTaskIdSuffix,
    getTaskNumber,
    GLYPHICON_HIGHLIGHT,
    parseAndFormatDataSize,
    parseDataSize,
    parseDuration,
    precisionRound
} from "../utils";
import {QueryHeader} from "./QueryHeader";

const Table = Reactable.Table,
    Thead = Reactable.Thead,
    Th = Reactable.Th,
    Tr = Reactable.Tr,
    Td = Reactable.Td;

class TaskList extends React.Component {
    static removeQueryId(id) {
        const pos = id.indexOf('.');
        if (pos !== -1) {
            return id.substring(pos + 1);
        }
        return id;
    }

    static compareTaskId(taskA, taskB) {
        const taskIdArrA = TaskList.removeQueryId(taskA).split(".");
        const taskIdArrB = TaskList.removeQueryId(taskB).split(".");

        if (taskIdArrA.length > taskIdArrB.length) {
            return 1;
        }
        for (let i = 0; i < taskIdArrA.length; i++) {
            const anum = Number.parseInt(taskIdArrA[i]);
            const bnum = Number.parseInt(taskIdArrB[i]);
            if (anum !== bnum) {
                return anum > bnum ? 1 : -1;
            }
        }

        return 0;
    }

    static showPortNumbers(tasks) {
        // check if any host has multiple port numbers
        const hostToPortNumber = {};
        for (let i = 0; i < tasks.length; i++) {
            const taskUri = tasks[i].taskStatus.self;
            const hostname = getHostname(taskUri);
            const port = getPort(taskUri);
            if ((hostname in hostToPortNumber) && (hostToPortNumber[hostname] !== port)) {
                return true;
            }
            hostToPortNumber[hostname] = port;
        }

        return false;
    }

    static formatState(state, fullyBlocked) {
        if (fullyBlocked && state === "RUNNING") {
            return "BLOCKED";
        }
        else {
            return state;
        }
    }

    render() {
        const tasks = this.props.tasks;
        const taskRetriesEnabled = this.props.taskRetriesEnabled;

        if (tasks === undefined || tasks.length === 0) {
            return (
                

No threads in the selected group

); } const showPortNumbers = TaskList.showPortNumbers(tasks); const renderedTasks = tasks.map(task => { let elapsedTime = parseDuration(task.stats.elapsedTime); if (elapsedTime === 0) { elapsedTime = Date.now() - Date.parse(task.stats.createTime); } return ( {getTaskIdSuffix(task.taskStatus.taskId)} {showPortNumbers ? getHostAndPort(task.taskStatus.self) : getHostname(task.taskStatus.self)} {TaskList.formatState(task.taskStatus.state, task.stats.fullyBlocked)} {formatCount(task.stats.rawInputPositions)} {formatCount(computeRate(task.stats.rawInputPositions, elapsedTime))} {formatDataSizeBytes(parseDataSize(task.stats.rawInputDataSize))} {formatDataSizeBytes(computeRate(parseDataSize(task.stats.rawInputDataSize), elapsedTime))} {task.stats.queuedDrivers} {task.stats.runningDrivers} {task.stats.blockedDrivers} {task.stats.completedDrivers} {task.stats.elapsedTime} {task.stats.totalCpuTime} {formatDataSizeBytes(task.outputBuffers.totalBufferedBytes)} {parseAndFormatDataSize(task.stats.userMemoryReservation)} {parseAndFormatDataSize(task.stats.peakUserMemoryReservation)} {taskRetriesEnabled && {parseAndFormatDataSize(task.estimatedMemory)} } ); }); return ( {taskRetriesEnabled && } {renderedTasks}
ID Host State Rows Rows/s Bytes Bytes/s Elapsed CPU Time Mem Peak MemEst Mem
); } } const BAR_CHART_WIDTH = 800; const BAR_CHART_PROPERTIES = { type: 'bar', barSpacing: '0', height: '80px', barColor: '#747F96', zeroColor: '#8997B3', chartRangeMin: 0, tooltipClassname: 'sparkline-tooltip', tooltipFormat: 'Task {{offset:offset}} - {{value}}', disableHiddenCheck: true, }; const HISTOGRAM_WIDTH = 175; const HISTOGRAM_PROPERTIES = { type: 'bar', barSpacing: '0', height: '80px', barColor: '#747F96', zeroColor: '#747F96', zeroAxis: true, chartRangeMin: 0, tooltipClassname: 'sparkline-tooltip', tooltipFormat: '{{offset:offset}} -- {{value}} tasks', disableHiddenCheck: true, }; class StageSummary extends React.Component { constructor(props) { super(props); this.state = { expanded: false, lastRender: null, taskFilter: TASK_FILTER.ALL }; } getExpandedIcon() { return this.state.expanded ? "glyphicon-chevron-up" : "glyphicon-chevron-down"; } getExpandedStyle() { return this.state.expanded ? {} : {display: "none"}; } toggleExpanded() { this.setState({ expanded: !this.state.expanded, }) } static renderHistogram(histogramId, inputData, numberFormatter) { const numBuckets = Math.min(HISTOGRAM_WIDTH, Math.sqrt(inputData.length)); const dataMin = Math.min.apply(null, inputData); const dataMax = Math.max.apply(null, inputData); const bucketSize = (dataMax - dataMin) / numBuckets; let histogramData = []; if (bucketSize === 0) { histogramData = [inputData.length]; } else { for (let i = 0; i < numBuckets + 1; i++) { histogramData.push(0); } for (let i in inputData) { const dataPoint = inputData[i]; const bucket = Math.floor((dataPoint - dataMin) / bucketSize); histogramData[bucket] = histogramData[bucket] + 1; } } const tooltipValueLookups = {'offset': {}}; for (let i = 0; i < histogramData.length; i++) { tooltipValueLookups['offset'][i] = numberFormatter(dataMin + (i * bucketSize)) + "-" + numberFormatter(dataMin + ((i + 1) * bucketSize)); } const stageHistogramProperties = $.extend({}, HISTOGRAM_PROPERTIES, {barWidth: (HISTOGRAM_WIDTH / histogramData.length), tooltipValueLookups: tooltipValueLookups}); $(histogramId).sparkline(histogramData, stageHistogramProperties); } componentDidUpdate() { const stage = this.props.stage; const numTasks = stage.tasks.length; // sort the x-axis stage.tasks.sort((taskA, taskB) => getTaskNumber(taskA.taskStatus.taskId) - getTaskNumber(taskB.taskStatus.taskId)); const scheduledTimes = stage.tasks.map(task => parseDuration(task.stats.totalScheduledTime)); const cpuTimes = stage.tasks.map(task => parseDuration(task.stats.totalCpuTime)); // prevent multiple calls to componentDidUpdate (resulting from calls to setState or otherwise) within the refresh interval from re-rendering sparklines/charts if (this.state.lastRender === null || (Date.now() - this.state.lastRender) >= 1000) { const renderTimestamp = Date.now(); const stageId = getStageNumber(stage.stageId); StageSummary.renderHistogram('#scheduled-time-histogram-' + stageId, scheduledTimes, formatDuration); StageSummary.renderHistogram('#cpu-time-histogram-' + stageId, cpuTimes, formatDuration); if (this.state.expanded) { // this needs to be a string otherwise it will also be passed to numberFormatter const tooltipValueLookups = {'offset': {}}; for (let i = 0; i < numTasks; i++) { tooltipValueLookups['offset'][i] = getStageNumber(stage.stageId) + "." + i; } const stageBarChartProperties = $.extend({}, BAR_CHART_PROPERTIES, {barWidth: BAR_CHART_WIDTH / numTasks, tooltipValueLookups: tooltipValueLookups}); $('#scheduled-time-bar-chart-' + stageId).sparkline(scheduledTimes, $.extend({}, stageBarChartProperties, {numberFormatter: formatDuration})); $('#cpu-time-bar-chart-' + stageId).sparkline(cpuTimes, $.extend({}, stageBarChartProperties, {numberFormatter: formatDuration})); } this.setState({ lastRender: renderTimestamp }); } } renderTaskList(taskRetriesEnabled) { let tasks = this.state.expanded ? this.props.stage.tasks : []; tasks = tasks.filter(task => this.state.taskFilter(task.taskStatus.state), this); return (); } handleTaskFilterClick(filter, event) { this.setState({ taskFilter: filter }); event.preventDefault(); } renderTaskFilterListItem(taskFilter, taskFilterText) { return (
  • {taskFilterText}
  • ); } renderTaskFilter() { return (

    Tasks

      {this.renderTaskFilterListItem(TASK_FILTER.ALL, "All")} {this.renderTaskFilterListItem(TASK_FILTER.PLANNED, "Planned")} {this.renderTaskFilterListItem(TASK_FILTER.RUNNING, "Running")} {this.renderTaskFilterListItem(TASK_FILTER.FINISHED, "Finished")} {this.renderTaskFilterListItem(TASK_FILTER.FAILED, "Aborted/Canceled/Failed")}
    ); } render() { const stage = this.props.stage; const taskRetriesEnabled = this.props.taskRetriesEnabled; if (stage === undefined || !stage.hasOwnProperty('plan')) { return ( Information about this stage is unavailable. ); } const totalBufferedBytes = stage.tasks .map(task => task.outputBuffers.totalBufferedBytes) .reduce((a, b) => a + b, 0); const stageId = getStageNumber(stage.stageId); return (
    {stageId}
    Time
    Scheduled {stage.stageStats.totalScheduledTime}
    Blocked {stage.stageStats.totalBlockedTime}
    CPU {stage.stageStats.totalCpuTime}
    Failed {stage.stageStats.failedScheduledTime}
    CPU Failed {stage.stageStats.failedCpuTime}
    Memory
    Cumulative {formatDataSizeBytes(stage.stageStats.cumulativeUserMemory / 1000)}
    Current {parseAndFormatDataSize(stage.stageStats.userMemoryReservation)}
    Buffers {formatDataSize(totalBufferedBytes)}
    Peak {parseAndFormatDataSize(stage.stageStats.peakUserMemoryReservation)}
    Failed {formatDataSizeBytes(stage.stageStats.failedCumulativeUserMemory / 1000)}
    Tasks
    Pending {stage.tasks.filter(task => task.taskStatus.state === "PLANNED").length}
    Running {stage.tasks.filter(task => task.taskStatus.state === "RUNNING").length}
    Blocked {stage.tasks.filter(task => task.stats.fullyBlocked).length}
    Failed {stage.tasks.filter(task => task.taskStatus.state === "FAILED").length}
    Total {stage.tasks.length}
    Scheduled Time Skew
    CPU Time Skew
    Task Scheduled Time
    Task CPU Time
    {this.renderTaskFilter()}
    {this.renderTaskList(taskRetriesEnabled)}
    ); } } class StageList extends React.Component { getStages(stage) { if (stage === undefined || !stage.hasOwnProperty('subStages')) { return [] } return [].concat.apply(stage, stage.subStages.map(this.getStages, this)); } render() { const stages = this.getStages(this.props.outputStage); const taskRetriesEnabled = this.props.taskRetriesEnabled; if (stages === undefined || stages.length === 0) { return (
    No stage information available.
    ); } const renderedStages = stages.map(stage => ); return (
    {renderedStages}
    ); } } const SMALL_SPARKLINE_PROPERTIES = { width: '100%', height: '57px', fillColor: '#3F4552', lineColor: '#747F96', spotColor: '#1EDCFF', tooltipClassname: 'sparkline-tooltip', disableHiddenCheck: true, }; const TASK_FILTER = { ALL: function () { return true }, PLANNED: function (state) { return state === 'PLANNED' }, RUNNING: function (state) { return state === 'RUNNING' }, FINISHED: function (state) { return state === 'FINISHED' }, FAILED: function (state) { return state === 'FAILED' || state === 'ABORTED' || state === 'CANCELED' }, }; export class QueryDetail extends React.Component { constructor(props) { super(props); this.state = { query: null, lastSnapshotStages: null, lastSnapshotTasks: null, lastScheduledTime: 0, lastCpuTime: 0, lastRowInput: 0, lastByteInput: 0, lastPhysicalInput: 0, lastPhysicalTime: 0, scheduledTimeRate: [], cpuTimeRate: [], rowInputRate: [], byteInputRate: [], physicalInputRate: [], reservedMemory: [], initialized: false, queryEnded: false, renderingEnded: false, lastRefresh: null, lastRender: null, stageRefresh: true, taskRefresh: true, taskFilter: TASK_FILTER.ALL, }; this.refreshLoop = this.refreshLoop.bind(this); } static formatStackTrace(info) { return QueryDetail.formatStackTraceHelper(info, [], "", ""); } static formatStackTraceHelper(info, parentStack, prefix, linePrefix) { let s = linePrefix + prefix + QueryDetail.failureInfoToString(info) + "\n"; if (info.stack) { let sharedStackFrames = 0; if (parentStack !== null) { sharedStackFrames = QueryDetail.countSharedStackFrames(info.stack, parentStack); } for (let i = 0; i < info.stack.length - sharedStackFrames; i++) { s += linePrefix + "\tat " + info.stack[i] + "\n"; } if (sharedStackFrames !== 0) { s += linePrefix + "\t... " + sharedStackFrames + " more" + "\n"; } } if (info.suppressed) { for (let i = 0; i < info.suppressed.length; i++) { s += QueryDetail.formatStackTraceHelper(info.suppressed[i], info.stack, "Suppressed: ", linePrefix + "\t"); } } if (info.cause) { s += QueryDetail.formatStackTraceHelper(info.cause, info.stack, "Caused by: ", linePrefix); } return s; } static countSharedStackFrames(stack, parentStack) { let n = 0; const minStackLength = Math.min(stack.length, parentStack.length); while (n < minStackLength && stack[stack.length - 1 - n] === parentStack[parentStack.length - 1 - n]) { n++; } return n; } static failureInfoToString(t) { return (t.message !== null) ? (t.type + ": " + t.message) : t.type; } resetTimer() { clearTimeout(this.timeoutId); // stop refreshing when query finishes or fails if (this.state.query === null || !this.state.queryEnded) { // task.info-update-interval is set to 3 seconds by default this.timeoutId = setTimeout(this.refreshLoop, 3000); } } refreshLoop() { clearTimeout(this.timeoutId); // to stop multiple series of refreshLoop from going on simultaneously const queryId = getFirstParameter(window.location.search); $.get('/ui/api/query/' + queryId, function (query) { let lastSnapshotStages = this.state.lastSnapshotStage; if (this.state.stageRefresh) { lastSnapshotStages = query.outputStage; } let lastSnapshotTasks = this.state.lastSnapshotTasks; if (this.state.taskRefresh) { lastSnapshotTasks = query.outputStage; } let lastRefresh = this.state.lastRefresh; const lastScheduledTime = this.state.lastScheduledTime; const lastCpuTime = this.state.lastCpuTime; const lastRowInput = this.state.lastRowInput; const lastByteInput = this.state.lastByteInput; const lastPhysicalInput = this.state.lastPhysicalInput; const lastPhysicalTime = this.state.lastPhysicalTime; const alreadyEnded = this.state.queryEnded; const nowMillis = Date.now(); this.setState({ query: query, lastSnapshotStage: lastSnapshotStages, lastSnapshotTasks: lastSnapshotTasks, lastPhysicalTime: parseDuration(query.queryStats.physicalInputReadTime), lastScheduledTime: parseDuration(query.queryStats.totalScheduledTime), lastCpuTime: parseDuration(query.queryStats.totalCpuTime), lastRowInput: query.queryStats.processedInputPositions, lastByteInput: parseDataSize(query.queryStats.processedInputDataSize), lastPhysicalInput: parseDataSize(query.queryStats.physicalInputDataSize), initialized: true, queryEnded: !!query.finalQueryInfo, lastRefresh: nowMillis, }); // i.e. don't show sparklines if we've already decided not to update or if we don't have one previous measurement if (alreadyEnded || (lastRefresh === null && query.state === "RUNNING")) { this.resetTimer(); return; } if (lastRefresh === null) { lastRefresh = nowMillis - parseDuration(query.queryStats.elapsedTime); } const elapsedSecsSinceLastRefresh = (nowMillis - lastRefresh) / 1000.0; if (elapsedSecsSinceLastRefresh >= 0) { const currentScheduledTimeRate = (parseDuration(query.queryStats.totalScheduledTime) - lastScheduledTime) / (elapsedSecsSinceLastRefresh * 1000); const currentCpuTimeRate = (parseDuration(query.queryStats.totalCpuTime) - lastCpuTime) / (elapsedSecsSinceLastRefresh * 1000); const currentPhysicalReadTime = (parseDuration(query.queryStats.physicalInputReadTime) - lastPhysicalTime) / 1000; const currentRowInputRate = (query.queryStats.processedInputPositions - lastRowInput) / elapsedSecsSinceLastRefresh; const currentByteInputRate = (parseDataSize(query.queryStats.processedInputDataSize) - lastByteInput) / elapsedSecsSinceLastRefresh; const currentPhysicalInputRate = currentPhysicalReadTime > 0 ? (parseDataSize(query.queryStats.physicalInputDataSize) - lastPhysicalInput) / currentPhysicalReadTime : 0; this.setState({ scheduledTimeRate: addToHistory(currentScheduledTimeRate, this.state.scheduledTimeRate), cpuTimeRate: addToHistory(currentCpuTimeRate, this.state.cpuTimeRate), rowInputRate: addToHistory(currentRowInputRate, this.state.rowInputRate), byteInputRate: addToHistory(currentByteInputRate, this.state.byteInputRate), reservedMemory: addToHistory(parseDataSize(query.queryStats.totalMemoryReservation), this.state.reservedMemory), physicalInputRate: addToHistory(currentPhysicalInputRate, this.state.physicalInputRate), }); } this.resetTimer(); }.bind(this)) .fail(() => { this.setState({ initialized: true, }); this.resetTimer(); }); } handleStageRefreshClick() { if (this.state.stageRefresh) { this.setState({ stageRefresh: false, lastSnapshotStages: this.state.query.outputStage, }); } else { this.setState({ stageRefresh: true, }); } } renderStageRefreshButton() { if (this.state.stageRefresh) { return } else { return } } componentDidMount() { this.refreshLoop(); } componentDidUpdate() { // prevent multiple calls to componentDidUpdate (resulting from calls to setState or otherwise) within the refresh interval from re-rendering sparklines/charts if (this.state.lastRender === null || (Date.now() - this.state.lastRender) >= 1000 || (this.state.ended && !this.state.renderingEnded)) { const renderTimestamp = Date.now(); $('#scheduled-time-rate-sparkline').sparkline(this.state.scheduledTimeRate, $.extend({}, SMALL_SPARKLINE_PROPERTIES, { chartRangeMin: 0, numberFormatter: precisionRound })); $('#cpu-time-rate-sparkline').sparkline(this.state.cpuTimeRate, $.extend({}, SMALL_SPARKLINE_PROPERTIES, {chartRangeMin: 0, numberFormatter: precisionRound})); $('#row-input-rate-sparkline').sparkline(this.state.rowInputRate, $.extend({}, SMALL_SPARKLINE_PROPERTIES, {numberFormatter: formatCount})); $('#byte-input-rate-sparkline').sparkline(this.state.byteInputRate, $.extend({}, SMALL_SPARKLINE_PROPERTIES, {numberFormatter: formatDataSize})); $('#reserved-memory-sparkline').sparkline(this.state.reservedMemory, $.extend({}, SMALL_SPARKLINE_PROPERTIES, {numberFormatter: formatDataSize})); $('#physical-input-rate-sparkline').sparkline(this.state.physicalInputRate, $.extend({}, SMALL_SPARKLINE_PROPERTIES, {numberFormatter: formatDataSize})); if (this.state.lastRender === null) { $('#query').each((i, block) => { hljs.highlightBlock(block); }); $('#prepared-query').each((i, block) => { hljs.highlightBlock(block); }); } this.setState({ renderingEnded: this.state.ended, lastRender: renderTimestamp, }); } $('[data-toggle="tooltip"]').tooltip(); new window.ClipboardJS('.copy-button'); } renderStages(taskRetriesEnabled) { if (this.state.lastSnapshotStage === null) { return; } return (

    Stages

    {this.renderStageRefreshButton()}
    ); } renderPreparedQuery() { const query = this.state.query; if (!query.hasOwnProperty('preparedQuery') || query.preparedQuery === null) { return; } return (

    Prepared Query

                        
                            {query.preparedQuery}
                        
                    
    ); } renderSessionProperties() { const query = this.state.query; const properties = []; for (let property in query.session.systemProperties) { if (query.session.systemProperties.hasOwnProperty(property)) { properties.push( - {property + "=" + query.session.systemProperties[property]}
    ); } } for (let catalog in query.session.catalogProperties) { if (query.session.catalogProperties.hasOwnProperty(catalog)) { for (let property in query.session.catalogProperties[catalog]) { if (query.session.catalogProperties[catalog].hasOwnProperty(property)) { properties.push( - {catalog + "." + property + "=" + query.session.catalogProperties[catalog][property]}
    ); } } } } return properties; } renderResourceEstimates() { const query = this.state.query; const estimates = query.session.resourceEstimates; const renderedEstimates = []; for (let resource in estimates) { if (estimates.hasOwnProperty(resource)) { const upperChars = resource.match(/([A-Z])/g) || []; let snakeCased = resource; for (let i = 0, n = upperChars.length; i < n; i++) { snakeCased = snakeCased.replace(new RegExp(upperChars[i]), '_' + upperChars[i].toLowerCase()); } renderedEstimates.push( - {snakeCased + "=" + query.session.resourceEstimates[resource]}
    ) } } return renderedEstimates; } renderWarningInfo() { const query = this.state.query; if (query.warnings.length > 0) { return (

    Warnings


    {query.warnings.map((warning) => )}
    {warning.warningCode.name} {warning.message}
    ); } else { return null; } } renderFailureInfo() { const query = this.state.query; if (query.failureInfo) { return (

    Error Information


    Error Type {query.errorType}
    Error Code {query.errorCode.name + " (" + this.state.query.errorCode.code + ")"}
    Stack Trace
                                                {QueryDetail.formatStackTrace(query.failureInfo)}
                                            
    ); } else { return ""; } } render() { const query = this.state.query; if (query === null || this.state.initialized === false) { let label = (
    Loading...
    ); if (this.state.initialized) { label = "Query not found"; } return (

    {label}

    ); } const taskRetriesEnabled = query.retryPolicy == "TASK"; return (

    Session


    User {query.session.user}   
    Principal {query.session.principal}
    Source {query.session.source}
    Catalog {query.session.catalog}
    Schema {query.session.schema}
    Time zone {query.session.timeZone}
    Client Address {query.session.remoteUserAddress}
    Client Tags {query.session.clientTags.join(", ")}
    Session Properties {this.renderSessionProperties()}
    Resource Estimates {this.renderResourceEstimates()}

    Execution


    Resource Group {query.resourceGroupId ? query.resourceGroupId.join(".") : "n/a"}
    Submission Time {formatShortDateTime(new Date(query.queryStats.createTime))}
    Completion Time {query.queryStats.endTime ? formatShortDateTime(new Date(query.queryStats.endTime)) : ""}
    Elapsed Time {query.queryStats.elapsedTime}
    Queued Time {query.queryStats.queuedTime}
    Analysis Time {query.queryStats.analysisTime}
    Planning Time {query.queryStats.planningTime}
    Execution Time {query.queryStats.executionTime}

    Resource Utilization Summary


    {taskRetriesEnabled && } {taskRetriesEnabled && } {taskRetriesEnabled && } {taskRetriesEnabled && } {taskRetriesEnabled && } {taskRetriesEnabled && } {taskRetriesEnabled && } {taskRetriesEnabled && } {taskRetriesEnabled && } {parseDataSize(query.queryStats.peakRevocableMemoryReservation) > 0 && } {taskRetriesEnabled && } {taskRetriesEnabled && } {taskRetriesEnabled && } {taskRetriesEnabled && } {parseDataSize(query.queryStats.spilledDataSize) > 0 && }
    CPU Time {query.queryStats.totalCpuTime} {query.queryStats.failedCpuTime}
    Planning CPU Time {query.queryStats.planningCpuTime}
    Scheduled Time {query.queryStats.totalScheduledTime} {query.queryStats.failedScheduledTime}
    Input Rows {formatCount(query.queryStats.processedInputPositions)} {query.queryStats.failedProcessedInputPositions}
    Input Data {parseAndFormatDataSize(query.queryStats.processedInputDataSize)} {query.queryStats.failedProcessedInputDataSize}
    Physical Input Rows {formatCount(query.queryStats.physicalInputPositions)} {formatCount(query.queryStats.failedPhysicalInputPositions)}
    Physical Input Data {parseAndFormatDataSize(query.queryStats.physicalInputDataSize)} {parseAndFormatDataSize(query.queryStats.failedPhysicalInputDataSize)}
    Physical Input Read Time {query.queryStats.physicalInputReadTime} {query.queryStats.failedPhysicalInputReadTime}
    Internal Network Rows {formatCount(query.queryStats.internalNetworkInputPositions)} {formatCount(query.queryStats.failedInternalNetworkInputPositions)}
    Internal Network Data {parseAndFormatDataSize(query.queryStats.internalNetworkInputDataSize)} {parseAndFormatDataSize(query.queryStats.failedInternalNetworkInputDataSize)}
    Peak User Memory {parseAndFormatDataSize(query.queryStats.peakUserMemoryReservation)}
    Peak Revocable Memory {parseAndFormatDataSize(query.queryStats.peakRevocableMemoryReservation)}
    Peak Total Memory {parseAndFormatDataSize(query.queryStats.peakTotalMemoryReservation)}
    Cumulative User Memory {formatDataSize(query.queryStats.cumulativeUserMemory / 1000.0) + "*seconds"} {formatDataSize(query.queryStats.failedCumulativeUserMemory / 1000.0) + "*seconds"}
    Output Rows {formatCount(query.queryStats.outputPositions)} {formatCount(query.queryStats.failedOutputPositions)}
    Output Data {parseAndFormatDataSize(query.queryStats.outputDataSize)} {parseAndFormatDataSize(query.queryStats.failedOutputDataSize)}
    Written Rows {formatCount(query.queryStats.writtenPositions)}
    Logical Written Data {parseAndFormatDataSize(query.queryStats.logicalWrittenDataSize)}
    Physical Written Data {parseAndFormatDataSize(query.queryStats.physicalWrittenDataSize)} {parseAndFormatDataSize(query.queryStats.failedPhysicalWrittenDataSize)}
    Spilled Data {parseAndFormatDataSize(query.queryStats.spilledDataSize)}

    Timeline


    Parallelism
    Loading ...
    {formatCount(this.state.cpuTimeRate[this.state.cpuTimeRate.length - 1])}
    Scheduled Time/s
    Loading ...
    {formatCount(this.state.scheduledTimeRate[this.state.scheduledTimeRate.length - 1])}
    Input Rows/s
    Loading ...
    {formatCount(this.state.rowInputRate[this.state.rowInputRate.length - 1])}
    Input Bytes/s
    Loading ...
    {formatDataSize(this.state.byteInputRate[this.state.byteInputRate.length - 1])}
    Physical Input Bytes/s
    Loading ...
    {formatDataSize(this.state.physicalInputRate[this.state.physicalInputRate.length - 1])}
    Memory Utilization
    Loading ...
    {formatDataSize(this.state.reservedMemory[this.state.reservedMemory.length - 1])}
    {this.renderWarningInfo()} {this.renderFailureInfo()}

    Query

                                
                                    {query.query}
                                
                            
    {this.renderPreparedQuery()}
    {this.renderStages(taskRetriesEnabled)}
    ); } }




    © 2015 - 2025 Weber Informatics LLC | Privacy Policy