Line data Source code
1 : import * as arrow from 'apache-arrow';
2 :
3 : import type { DashQLShellCommand } from './api.js';
4 : import { QueryType, type QueryMetadata } from '../query/query_execution_state.js';
5 : import { detectPlanEngine } from '../views/query_profile/plan_engine.js';
6 :
7 : /// The metadata of the queries that users enter in the shell
8 1 : export const SHELL_QUERY_METADATA: QueryMetadata = {
9 1 : queryType: QueryType.USER_PROVIDED,
10 1 : title: 'Shell Query',
11 1 : description: null,
12 1 : issuer: 'DashQL Shell',
13 1 : userProvided: true,
14 1 : };
15 :
16 : /// Report a timing to an optional observer, observers must not interrupt the query execution
17 1 : export function reportShellTiming(onTiming: ((label: string, elapsedMs: number) => void) | undefined, label: string, elapsedMs: number): void {
18 1 : try {
19 1 : onTiming?.(label, elapsedMs);
20 1 : } catch {
21 : // Timing observers must not interrupt query execution.
22 0 : }
23 1 : }
24 :
25 1 : export function getPlanResultText(table: arrow.Table | null): string | null {
26 1 : if (table == null || table.numRows !== 1 || table.numCols !== 1) return null;
27 1 : const value = table.getChildAt(0)?.get(0);
28 1 : if (typeof value !== 'string') return null;
29 1 : if (detectPlanEngine(value) == null) return null;
30 1 : try {
31 1 : const parsed = JSON.parse(value);
32 1 : if (parsed == null || typeof parsed !== 'object' || Array.isArray(parsed)) return null;
33 : // A Hyper plan has a root operator, a Trino plan maps fragment ids to plan nodes
34 1 : const isHyperPlan = typeof parsed.operator === 'string';
35 1 : const isTrinoPlan = Object.values(parsed).every(node =>
36 1 : node != null && typeof node === 'object' && typeof (node as { name?: unknown }).name === 'string');
37 1 : return isHyperPlan || isTrinoPlan ? value : null;
38 1 : } catch {
39 0 : return null;
40 0 : }
41 1 : }
42 :
43 : /// Open the last result again. `reopen` tells whether there is one.
44 1 : export function createShellLastCommand(reopen: () => boolean): DashQLShellCommand {
45 1 : return [
46 1 : 'last',
47 1 : 'Show the last query result again',
48 1 : args => {
49 1 : if (args.length > 0) throw new Error('usage: .last');
50 1 : return reopen() ? undefined : 'No result to show';
51 1 : },
52 1 : ];
53 1 : }
|