ydb-embedded-ui 3.5.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/dist/containers/Tenant/QueryEditor/QueriesHistory/QueriesHistory.tsx +3 -3
- package/dist/containers/Tenant/QueryEditor/QueryDuration/QueryDuration.scss +8 -0
- package/dist/containers/Tenant/QueryEditor/QueryDuration/QueryDuration.tsx +21 -0
- package/dist/containers/Tenant/QueryEditor/QueryEditor.js +58 -83
- package/dist/containers/Tenant/QueryEditor/QueryEditor.scss +0 -33
- package/dist/containers/Tenant/QueryEditor/QueryEditorControls/OldQueryEditorControls.tsx +83 -0
- package/dist/containers/Tenant/QueryEditor/QueryEditorControls/QueryEditorControls.scss +57 -0
- package/dist/containers/Tenant/QueryEditor/QueryEditorControls/QueryEditorControls.tsx +84 -0
- package/dist/containers/Tenant/QueryEditor/QueryEditorControls/shared.ts +23 -0
- package/dist/containers/Tenant/QueryEditor/QueryExplain/QueryExplain.js +12 -23
- package/dist/containers/Tenant/QueryEditor/QueryResult/QueryResult.js +4 -6
- package/dist/containers/Tenant/QueryEditor/i18n/en.json +3 -0
- package/dist/containers/Tenant/QueryEditor/i18n/index.ts +11 -0
- package/dist/containers/Tenant/QueryEditor/i18n/ru.json +3 -0
- package/dist/containers/UserSettings/UserSettings.tsx +30 -1
- package/dist/services/api.d.ts +4 -3
- package/dist/services/api.js +2 -2
- package/dist/store/reducers/executeQuery.ts +12 -37
- package/dist/store/reducers/{explainQuery.js → explainQuery.ts} +44 -59
- package/dist/store/reducers/settings.js +18 -3
- package/dist/types/api/error.ts +14 -0
- package/dist/types/api/query.ts +226 -117
- package/dist/types/store/executeQuery.ts +4 -8
- package/dist/types/store/explainQuery.ts +38 -0
- package/dist/types/store/query.ts +23 -3
- package/dist/utils/constants.ts +2 -1
- package/dist/utils/error.ts +25 -0
- package/dist/utils/index.js +0 -49
- package/dist/utils/prepareQueryExplain.ts +7 -24
- package/dist/utils/query.test.ts +153 -231
- package/dist/utils/query.ts +44 -78
- package/dist/utils/timeParsers/i18n/en.json +9 -9
- package/dist/utils/timeParsers/i18n/ru.json +9 -9
- package/dist/utils/timeParsers/parsers.ts +9 -0
- package/dist/utils/utils.js +1 -2
- package/package.json +1 -1
package/dist/types/api/query.ts
CHANGED
@@ -1,34 +1,165 @@
|
|
1
|
-
//
|
1
|
+
// ==== types from backend protos ====
|
2
|
+
interface Position {
|
3
|
+
row?: number;
|
4
|
+
column?: number;
|
5
|
+
file?: string;
|
6
|
+
}
|
2
7
|
|
3
|
-
|
4
|
-
|
5
|
-
|
8
|
+
/** source: https://github.com/ydb-platform/ydb/blob/main/ydb/public/api/protos/ydb_issue_message.proto */
|
9
|
+
export interface IssueMessage {
|
10
|
+
position?: Position;
|
11
|
+
end_position?: Position;
|
12
|
+
message?: string;
|
13
|
+
issue_code?: number;
|
14
|
+
severity?: number;
|
15
|
+
issues?: IssueMessage[];
|
16
|
+
}
|
6
17
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
18
|
+
/** incomplete */
|
19
|
+
interface TDqStageStats {}
|
20
|
+
|
21
|
+
/** incomplete */
|
22
|
+
interface TKqpStatsCompile {}
|
23
|
+
|
24
|
+
interface TDqTableStats {
|
25
|
+
TablePath?: string;
|
26
|
+
/** uint64 */
|
27
|
+
ReadRows?: string;
|
28
|
+
/** uint64 */
|
29
|
+
ReadBytes?: string;
|
30
|
+
/** uint64 */
|
31
|
+
WriteRows?: string;
|
32
|
+
/** uint64 */
|
33
|
+
WriteBytes?: string;
|
34
|
+
/** uint64 */
|
35
|
+
EraseRows?: string;
|
36
|
+
/** uint64 */
|
37
|
+
EraseBytes?: string;
|
38
|
+
AffectedPartitions?: number;
|
39
|
+
Extra?: unknown;
|
11
40
|
}
|
12
41
|
|
13
|
-
|
14
|
-
|
42
|
+
/** source: https://github.com/ydb-platform/ydb/blob/main/ydb/library/yql/dq/actors/protos/dq_stats.proto */
|
43
|
+
interface TDqExecutionStats {
|
44
|
+
/** uint64 */
|
45
|
+
CpuTimeUs?: string;
|
46
|
+
/** uint64 */
|
47
|
+
DurationUs?: string;
|
48
|
+
/** uint64 */
|
49
|
+
ResultRows?: string;
|
50
|
+
/** uint64 */
|
51
|
+
ResultBytes?: string;
|
52
|
+
|
53
|
+
Tables?: TDqTableStats[];
|
54
|
+
|
55
|
+
/** uint64 */
|
56
|
+
ExecuterCpuTimeUs?: string;
|
57
|
+
/** uint64 */
|
58
|
+
StartTimeMs?: string;
|
59
|
+
/** uint64 */
|
60
|
+
FinishTimeMs?: string;
|
61
|
+
/** uint64 */
|
62
|
+
FirstRowTimeMs?: string;
|
63
|
+
|
64
|
+
Stages?: TDqStageStats[];
|
65
|
+
TxPlansWithStats?: string[];
|
66
|
+
|
67
|
+
Extra: unknown;
|
15
68
|
}
|
16
69
|
|
17
|
-
|
18
|
-
|
19
|
-
|
70
|
+
/** source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/protos/kqp_stats.proto */
|
71
|
+
export interface TKqpStatsQuery {
|
72
|
+
/** uint64 */
|
73
|
+
DurationUs?: string;
|
74
|
+
Compilation?: TKqpStatsCompile;
|
75
|
+
|
76
|
+
/** uint64 */
|
77
|
+
WorkerCpuTimeUs?: string;
|
78
|
+
/** uint64 */
|
79
|
+
ReadSetsCount?: string;
|
80
|
+
/** uint64 */
|
81
|
+
MaxShardProgramSize?: string;
|
82
|
+
/** uint64 */
|
83
|
+
MaxShardReplySize?: string;
|
84
|
+
|
85
|
+
Executions?: TDqExecutionStats[];
|
20
86
|
}
|
21
87
|
|
22
|
-
|
23
|
-
|
24
|
-
|
88
|
+
// ==== Self-written types ====
|
89
|
+
// ==== Meta version 0.2 ====
|
90
|
+
// Backend code: https://github.com/ydb-platform/ydb/blob/main/ydb/core/kqp/opt/kqp_query_plan.cpp
|
25
91
|
|
26
|
-
//
|
27
|
-
export
|
92
|
+
// ==== Plan ====
|
93
|
+
export interface PlanMeta {
|
94
|
+
version: string;
|
95
|
+
type: 'script' | 'query';
|
96
|
+
}
|
28
97
|
|
29
|
-
|
98
|
+
export interface PlanTable {
|
99
|
+
name: string;
|
100
|
+
reads?: {
|
101
|
+
type: string;
|
102
|
+
lookup_by?: string[];
|
103
|
+
scan_by?: string[];
|
104
|
+
limit?: string;
|
105
|
+
reverse?: boolean;
|
106
|
+
columns?: string[];
|
107
|
+
}[];
|
108
|
+
writes?: {
|
109
|
+
type: string;
|
110
|
+
key?: string[];
|
111
|
+
columns?: string[];
|
112
|
+
}[];
|
113
|
+
}
|
30
114
|
|
31
|
-
|
115
|
+
interface PlanNodeStats {
|
116
|
+
TotalCpuTimeUs?: number;
|
117
|
+
TotalTasks?: number;
|
118
|
+
TotalInputBytes?: number;
|
119
|
+
TotalInputRows?: number;
|
120
|
+
TotalOutputBytes?: number;
|
121
|
+
TotalDurationMs?: number;
|
122
|
+
TotalOutputRows?: number;
|
123
|
+
}
|
124
|
+
|
125
|
+
interface PlanNodeOperator {
|
126
|
+
Name: string;
|
127
|
+
Limit?: string;
|
128
|
+
ReadLimit?: string;
|
129
|
+
ReadColumns?: string[];
|
130
|
+
ReadRanges?: string[];
|
131
|
+
Table?: string;
|
132
|
+
Iterator?: string;
|
133
|
+
}
|
134
|
+
|
135
|
+
export interface PlanNode {
|
136
|
+
PlanNodeId?: number;
|
137
|
+
'Node Type'?: string;
|
138
|
+
Plans?: PlanNode[];
|
139
|
+
Operators?: PlanNodeOperator[];
|
140
|
+
Tables?: string[];
|
141
|
+
PlanNodeType?: string;
|
142
|
+
Stats?: PlanNodeStats;
|
143
|
+
'CTE Name'?: string;
|
144
|
+
'Subplan Name'?: string;
|
145
|
+
'Parent Relationship'?: string;
|
146
|
+
}
|
147
|
+
|
148
|
+
export interface ScriptPlan {
|
149
|
+
queries?: {
|
150
|
+
Plan?: PlanNode;
|
151
|
+
tables?: PlanTable[];
|
152
|
+
}[];
|
153
|
+
meta: PlanMeta;
|
154
|
+
}
|
155
|
+
|
156
|
+
export interface ScanPlan {
|
157
|
+
Plan?: PlanNode;
|
158
|
+
tables?: PlanTable[];
|
159
|
+
meta: PlanMeta;
|
160
|
+
}
|
161
|
+
|
162
|
+
// ==== Common types ====
|
32
163
|
|
33
164
|
export type CellValue = string | number | null | undefined;
|
34
165
|
|
@@ -43,113 +174,91 @@ export interface ColumnType {
|
|
43
174
|
type: string;
|
44
175
|
}
|
45
176
|
|
46
|
-
|
47
|
-
|
48
|
-
export type ExecuteModernResponse = {
|
49
|
-
result: ArrayRow[];
|
50
|
-
columns: ColumnType[];
|
51
|
-
} & CommonFields;
|
52
|
-
|
53
|
-
export type ExecuteClassicResponseDeep = {
|
54
|
-
result: KeyValueRow[];
|
55
|
-
} & CommonFields;
|
56
|
-
|
57
|
-
// can be undefined for queries like `insert into`
|
58
|
-
export type ExecuteClassicResponsePlain = KeyValueRow[] | undefined;
|
59
|
-
|
60
|
-
export type ExecuteClassicResponse = ExecuteClassicResponseDeep | ExecuteClassicResponsePlain;
|
61
|
-
|
62
|
-
export type ExecuteYdbResponse = {
|
63
|
-
result: KeyValueRow[];
|
64
|
-
} & CommonFields;
|
65
|
-
|
66
|
-
// prettier-ignore
|
67
|
-
type ExecuteResponse<Schema extends Schemas> =
|
68
|
-
| CommonFields // result can be undefined for queries like `insert into`
|
69
|
-
| (Schema extends 'modern'
|
70
|
-
? ExecuteModernResponse
|
71
|
-
: Schema extends 'ydb'
|
72
|
-
? ExecuteYdbResponse
|
73
|
-
: Schema extends 'classic' | undefined
|
74
|
-
? ExecuteClassicResponse
|
75
|
-
: unknown);
|
76
|
-
|
77
|
-
// deprecated response from older versions, backward compatibility
|
78
|
-
|
79
|
-
type DeprecatedExecuteResponseValue =
|
80
|
-
| KeyValueRow[]
|
81
|
-
| string
|
82
|
-
// can be here because of a bug in the previous backend version
|
83
|
-
// should be ignored in parsing
|
84
|
-
| Plan;
|
85
|
-
|
86
|
-
export type DeprecatedExecuteResponseDeep = {
|
87
|
-
// can be undefined for queries like `insert into`
|
88
|
-
result?: DeprecatedExecuteResponseValue;
|
89
|
-
} & DeprecatedCommonFields;
|
90
|
-
|
91
|
-
// can be undefined for queries like `insert into`
|
92
|
-
export type DeprecatedExecuteResponsePlain = DeprecatedExecuteResponseValue | undefined;
|
93
|
-
|
94
|
-
export type DeprecatedExecuteResponse =
|
95
|
-
| DeprecatedExecuteResponseDeep
|
96
|
-
| DeprecatedExecuteResponsePlain;
|
177
|
+
/** undefined = 'classic' */
|
178
|
+
export type Schemas = 'classic' | 'modern' | 'ydb' | undefined;
|
97
179
|
|
98
|
-
|
180
|
+
/**
|
181
|
+
* undefined = 'execute'
|
182
|
+
*
|
183
|
+
* execute and execute-script have similar responses
|
184
|
+
*/
|
185
|
+
export type ExecuteActions = 'execute' | 'execute-scan' | 'execute-script' | undefined;
|
99
186
|
|
100
|
-
|
187
|
+
/** explain, explain-scan and explain-ast have similar responses */
|
188
|
+
export type ExplainActions = 'explain' | 'explain-scan' | 'explain-script' | 'explain-ast';
|
101
189
|
|
102
|
-
type
|
190
|
+
export type Actions = ExecuteActions | ExplainActions;
|
103
191
|
|
104
|
-
//
|
192
|
+
// ==== Error response ====
|
105
193
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
: Action extends 'explain'
|
111
|
-
? ({result: Plan} & Required<DeprecatedCommonFields>) | Plan
|
112
|
-
: unknown;
|
194
|
+
export interface ErrorResponse {
|
195
|
+
error?: IssueMessage;
|
196
|
+
issues?: IssueMessage[];
|
197
|
+
}
|
113
198
|
|
114
|
-
// ====
|
199
|
+
// ==== Explain Responses ====
|
115
200
|
|
116
|
-
export
|
117
|
-
|
118
|
-
|
119
|
-
| null;
|
201
|
+
export interface ExplainScriptResponse {
|
202
|
+
plan?: ScriptPlan;
|
203
|
+
}
|
120
204
|
|
121
|
-
export
|
122
|
-
|
123
|
-
|
124
|
-
|
205
|
+
export interface ExplainScanResponse {
|
206
|
+
ast?: string;
|
207
|
+
plan?: ScanPlan;
|
208
|
+
}
|
125
209
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
210
|
+
export type ExplainResponse<Action extends ExplainActions> = Action extends 'explain-script'
|
211
|
+
? ExplainScriptResponse
|
212
|
+
: ExplainScanResponse;
|
213
|
+
|
214
|
+
// ==== Execute Responses ====
|
215
|
+
|
216
|
+
type ResultFields<Schema extends Schemas> = Schema extends 'modern'
|
217
|
+
? {
|
218
|
+
result?: ArrayRow[];
|
219
|
+
columns?: ColumnType[];
|
220
|
+
}
|
221
|
+
: {
|
222
|
+
result?: KeyValueRow[];
|
223
|
+
};
|
224
|
+
|
225
|
+
export type ExecuteScanResponse<Schema extends Schemas> = {
|
226
|
+
plan?: ScanPlan;
|
227
|
+
ast?: string;
|
228
|
+
stats?: TKqpStatsQuery;
|
229
|
+
} & ResultFields<Schema>;
|
230
|
+
|
231
|
+
export type ExecuteScriptResponse<Schema extends Schemas> = {
|
232
|
+
plan?: ScriptPlan;
|
233
|
+
ast?: string;
|
234
|
+
stats?: TKqpStatsQuery;
|
235
|
+
} & ResultFields<Schema>;
|
236
|
+
|
237
|
+
export type ExecuteResponse<
|
238
|
+
Action extends ExecuteActions,
|
239
|
+
Schema extends Schemas,
|
240
|
+
> = Action extends 'execute-scan' ? ExecuteScanResponse<Schema> : ExecuteScriptResponse<Schema>;
|
241
|
+
|
242
|
+
// ==== Combined API response ====
|
243
|
+
export type QueryAPIResponse<
|
244
|
+
Action extends Actions,
|
245
|
+
Schema extends Schemas,
|
246
|
+
> = Action extends ExplainActions
|
247
|
+
? ExplainResponse<Action>
|
248
|
+
: Action extends ExecuteActions
|
249
|
+
? ExecuteResponse<Action, Schema>
|
250
|
+
: unknown;
|
251
|
+
|
252
|
+
// ==== types to use in query result preparation ====
|
253
|
+
export type AnyExplainResponse = ExplainScanResponse | ExplainScriptResponse;
|
254
|
+
|
255
|
+
export type ExecuteModernResponse = ExecuteScanResponse<'modern'> | ExecuteScriptResponse<'modern'>;
|
256
|
+
export type ExecuteClassicResponse =
|
257
|
+
| ExecuteScanResponse<'classic'>
|
258
|
+
| ExecuteScriptResponse<'classic'>;
|
259
|
+
export type ExecuteYdbResponse = ExecuteScanResponse<'ydb'> | ExecuteScriptResponse<'ydb'>;
|
133
260
|
|
134
261
|
export type AnyExecuteResponse =
|
135
262
|
| ExecuteModernResponse
|
136
263
|
| ExecuteClassicResponse
|
137
|
-
| ExecuteYdbResponse
|
138
|
-
| CommonFields
|
139
|
-
| DeprecatedExecuteResponse
|
140
|
-
| null;
|
141
|
-
|
142
|
-
export type DeepExecuteResponse =
|
143
|
-
| ExecuteModernResponse
|
144
|
-
| ExecuteClassicResponseDeep
|
145
|
-
| ExecuteYdbResponse
|
146
|
-
| DeprecatedExecuteResponseDeep;
|
147
|
-
|
148
|
-
export type AnyExplainResponse =
|
149
|
-
| ExplainResponse
|
150
|
-
| CommonFields
|
151
|
-
| DeprecatedExplainResponse<'explain'>
|
152
|
-
| DeprecatedExplainResponse<'explain-ast'>
|
153
|
-
| null;
|
154
|
-
|
155
|
-
export type AnyResponse = AnyExecuteResponse | AnyExplainResponse;
|
264
|
+
| ExecuteYdbResponse;
|
@@ -2,19 +2,17 @@ import {
|
|
2
2
|
SEND_QUERY,
|
3
3
|
changeUserInput,
|
4
4
|
saveQueryToHistory,
|
5
|
-
selectRunAction,
|
6
5
|
goToPreviousQuery,
|
7
6
|
setMonacoHotKey,
|
8
7
|
goToNextQuery,
|
9
8
|
MONACO_HOT_KEY_ACTIONS,
|
10
|
-
RUN_ACTIONS_VALUES,
|
11
9
|
} from '../../store/reducers/executeQuery';
|
12
10
|
import type {ApiRequestAction} from '../../store/utils';
|
11
|
+
import type {ErrorResponse} from '../api/query';
|
13
12
|
import type {ValueOf} from '../common';
|
14
|
-
import type {IQueryResult} from './query';
|
13
|
+
import type {IQueryResult, QueryError} from './query';
|
15
14
|
|
16
15
|
export type MonacoHotKeyAction = ValueOf<typeof MONACO_HOT_KEY_ACTIONS>;
|
17
|
-
export type RunAction = ValueOf<typeof RUN_ACTIONS_VALUES>;
|
18
16
|
|
19
17
|
export interface ExecuteQueryState {
|
20
18
|
loading: boolean;
|
@@ -23,14 +21,13 @@ export interface ExecuteQueryState {
|
|
23
21
|
queries: string[];
|
24
22
|
currentIndex: number;
|
25
23
|
};
|
26
|
-
runAction: RunAction;
|
27
24
|
monacoHotKey: null | MonacoHotKeyAction;
|
28
25
|
data?: IQueryResult;
|
29
26
|
stats?: IQueryResult['stats'];
|
30
|
-
error?:
|
27
|
+
error?: string | ErrorResponse;
|
31
28
|
}
|
32
29
|
|
33
|
-
type SendQueryAction = ApiRequestAction<typeof SEND_QUERY, IQueryResult,
|
30
|
+
type SendQueryAction = ApiRequestAction<typeof SEND_QUERY, IQueryResult, QueryError>;
|
34
31
|
|
35
32
|
export type ExecuteQueryAction =
|
36
33
|
| SendQueryAction
|
@@ -38,5 +35,4 @@ export type ExecuteQueryAction =
|
|
38
35
|
| ReturnType<typeof goToPreviousQuery>
|
39
36
|
| ReturnType<typeof changeUserInput>
|
40
37
|
| ReturnType<typeof saveQueryToHistory>
|
41
|
-
| ReturnType<typeof selectRunAction>
|
42
38
|
| ReturnType<typeof setMonacoHotKey>;
|
@@ -0,0 +1,38 @@
|
|
1
|
+
import type {ExplainPlanNodeData, GraphNode, Link} from '@gravity-ui/paranoid';
|
2
|
+
|
3
|
+
import {GET_EXPLAIN_QUERY, GET_EXPLAIN_QUERY_AST} from '../../store/reducers/explainQuery';
|
4
|
+
import type {ApiRequestAction} from '../../store/utils';
|
5
|
+
import type {PlanTable, ErrorResponse, ScanPlan, ScriptPlan} from '../api/query';
|
6
|
+
import type {IQueryResult, QueryError} from './query';
|
7
|
+
|
8
|
+
export interface PreparedExplainResponse {
|
9
|
+
plan?: {
|
10
|
+
links?: Link[];
|
11
|
+
nodes?: GraphNode<ExplainPlanNodeData>[];
|
12
|
+
tables?: PlanTable[];
|
13
|
+
version?: string;
|
14
|
+
pristine?: ScanPlan | ScriptPlan;
|
15
|
+
};
|
16
|
+
ast?: string;
|
17
|
+
}
|
18
|
+
|
19
|
+
export interface ExplainQueryState {
|
20
|
+
loading: boolean;
|
21
|
+
data?: PreparedExplainResponse['plan'];
|
22
|
+
dataAst?: PreparedExplainResponse['ast'];
|
23
|
+
error?: string | ErrorResponse;
|
24
|
+
errorAst?: string | ErrorResponse;
|
25
|
+
}
|
26
|
+
|
27
|
+
type GetExplainQueryAstAction = ApiRequestAction<
|
28
|
+
typeof GET_EXPLAIN_QUERY_AST,
|
29
|
+
IQueryResult,
|
30
|
+
QueryError
|
31
|
+
>;
|
32
|
+
type GetExplainQueryAction = ApiRequestAction<
|
33
|
+
typeof GET_EXPLAIN_QUERY,
|
34
|
+
PreparedExplainResponse,
|
35
|
+
QueryError
|
36
|
+
>;
|
37
|
+
|
38
|
+
export type ExplainQueryAction = GetExplainQueryAstAction | GetExplainQueryAction;
|
@@ -1,9 +1,29 @@
|
|
1
|
-
import type {
|
1
|
+
import type {NetworkError} from '../api/error';
|
2
|
+
import type {
|
3
|
+
KeyValueRow,
|
4
|
+
ColumnType,
|
5
|
+
ErrorResponse,
|
6
|
+
ScriptPlan,
|
7
|
+
ScanPlan,
|
8
|
+
TKqpStatsQuery,
|
9
|
+
} from '../api/query';
|
2
10
|
|
3
11
|
export interface IQueryResult {
|
4
12
|
result?: KeyValueRow[];
|
5
13
|
columns?: ColumnType[];
|
6
|
-
stats?:
|
7
|
-
plan?:
|
14
|
+
stats?: TKqpStatsQuery;
|
15
|
+
plan?: ScriptPlan | ScanPlan;
|
8
16
|
ast?: string;
|
9
17
|
}
|
18
|
+
|
19
|
+
export interface QueryRequestParams {
|
20
|
+
database: string;
|
21
|
+
query: string;
|
22
|
+
}
|
23
|
+
|
24
|
+
export type QueryError = NetworkError | ErrorResponse;
|
25
|
+
|
26
|
+
export enum QueryModes {
|
27
|
+
scan = 'scan',
|
28
|
+
script = 'script',
|
29
|
+
}
|
package/dist/utils/constants.ts
CHANGED
@@ -94,6 +94,7 @@ export type IProblemFilterValues = typeof ALL | typeof PROBLEMS;
|
|
94
94
|
export const THEME_KEY = 'theme';
|
95
95
|
export const INVERTED_DISKS_KEY = 'invertedDisks';
|
96
96
|
export const USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY = 'useNodesEndpointInDiagnostics';
|
97
|
+
export const ENABLE_QUERY_MODES_FOR_EXPLAIN = 'enableQueryModesForExplain';
|
97
98
|
export const SAVED_QUERIES_KEY = 'saved_queries';
|
98
99
|
export const ASIDE_HEADER_COMPACT_KEY = 'asideHeaderCompact';
|
99
100
|
export const QUERIES_HISTORY_KEY = 'queries_history';
|
@@ -118,6 +119,6 @@ export const DEFAULT_TABLE_SETTINGS = {
|
|
118
119
|
} as const;
|
119
120
|
|
120
121
|
export const TENANT_INITIAL_TAB_KEY = 'saved_tenant_initial_tab';
|
121
|
-
export const
|
122
|
+
export const QUERY_INITIAL_MODE_KEY = 'query_initial_mode';
|
122
123
|
|
123
124
|
export const PARTITIONS_SELECTED_COLUMNS_KEY = 'partitionsSelectedColumns';
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import type {AxiosError} from 'axios';
|
2
|
+
|
3
|
+
import type {IResponseError, NetworkError} from '../types/api/error';
|
4
|
+
import type {ErrorResponse as QueryErrorResponse} from '../types/api/query';
|
5
|
+
import type {QueryError} from '../types/store/query';
|
6
|
+
|
7
|
+
type RequestError = NetworkError | IResponseError | AxiosError | QueryErrorResponse | unknown;
|
8
|
+
|
9
|
+
const isNetworkError = (error: RequestError): error is NetworkError => {
|
10
|
+
return Boolean(
|
11
|
+
error &&
|
12
|
+
typeof error === 'object' &&
|
13
|
+
'message' in error &&
|
14
|
+
(error as {message: unknown}).message === 'Network Error',
|
15
|
+
);
|
16
|
+
};
|
17
|
+
|
18
|
+
export const parseQueryError = (error: QueryError): QueryErrorResponse | string | undefined => {
|
19
|
+
if (isNetworkError(error)) {
|
20
|
+
return error.message;
|
21
|
+
}
|
22
|
+
|
23
|
+
// 401 Unauthorized error is handled by GenericAPI
|
24
|
+
return error ?? 'Unauthorized';
|
25
|
+
};
|
package/dist/utils/index.js
CHANGED
@@ -113,52 +113,3 @@ export const renderExplainNode = (node) => {
|
|
113
113
|
const parts = node.name.split('|');
|
114
114
|
return parts.length > 1 ? parts[1] : node.name;
|
115
115
|
};
|
116
|
-
|
117
|
-
export const getExplainNodeId = (...values) => {
|
118
|
-
return values.join('|');
|
119
|
-
};
|
120
|
-
|
121
|
-
const getStringFromProps = (props) => {
|
122
|
-
return props
|
123
|
-
.map(([name, value]) => {
|
124
|
-
return value && `${name}: ${Array.isArray(value) ? value.join(', ') : value}`;
|
125
|
-
})
|
126
|
-
.filter(Boolean)
|
127
|
-
.join('\n');
|
128
|
-
};
|
129
|
-
|
130
|
-
export const getMetaForExplainNode = (node) => {
|
131
|
-
switch (node.type) {
|
132
|
-
case 'MultiLookup':
|
133
|
-
case 'Lookup': {
|
134
|
-
return getStringFromProps([
|
135
|
-
['lookup by', node.lookup_by],
|
136
|
-
['columns', node.columns],
|
137
|
-
]);
|
138
|
-
}
|
139
|
-
case 'FullScan':
|
140
|
-
case 'Scan': {
|
141
|
-
return getStringFromProps([
|
142
|
-
['scan by', node.scan_by],
|
143
|
-
['limit', node.limit],
|
144
|
-
['columns', node.columns],
|
145
|
-
]);
|
146
|
-
}
|
147
|
-
case 'Upsert':
|
148
|
-
case 'MultiUpsert': {
|
149
|
-
return getStringFromProps([
|
150
|
-
['key', node.key],
|
151
|
-
['columns', node.columns],
|
152
|
-
]);
|
153
|
-
}
|
154
|
-
case 'Erase':
|
155
|
-
case 'MultiErase': {
|
156
|
-
return getStringFromProps([
|
157
|
-
['key', node.key],
|
158
|
-
['columns', node.columns],
|
159
|
-
]);
|
160
|
-
}
|
161
|
-
default:
|
162
|
-
return '';
|
163
|
-
}
|
164
|
-
};
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import type {
|
2
2
|
Link,
|
3
3
|
GraphNode,
|
4
4
|
TopologyNodeDataStats,
|
@@ -7,28 +7,11 @@ import {
|
|
7
7
|
TopologyNodeDataStatsItem,
|
8
8
|
} from '@gravity-ui/paranoid';
|
9
9
|
|
10
|
-
|
11
|
-
Name: string;
|
12
|
-
[key: string]: any;
|
13
|
-
}
|
14
|
-
|
15
|
-
export interface Plan {
|
16
|
-
PlanNodeId: number;
|
17
|
-
'Node Type': string;
|
18
|
-
Plans?: Plan[];
|
19
|
-
Operators?: PlanOperator[];
|
20
|
-
Tables?: string[];
|
21
|
-
PlanNodeType?: string;
|
22
|
-
[key: string]: any;
|
23
|
-
}
|
24
|
-
|
25
|
-
export interface RootPlan {
|
26
|
-
Plan: Plan;
|
27
|
-
}
|
10
|
+
import type {PlanNode} from '../types/api/query';
|
28
11
|
|
29
12
|
const CONNECTION_NODE_META_FIELDS = new Set(['PlanNodeId', 'PlanNodeType', 'Node Type', 'Plans']);
|
30
13
|
|
31
|
-
function prepareStats(plan:
|
14
|
+
function prepareStats(plan: PlanNode) {
|
32
15
|
const stats: TopologyNodeDataStats[] = [];
|
33
16
|
|
34
17
|
if (plan.Operators) {
|
@@ -77,7 +60,7 @@ function prepareStats(plan: Plan) {
|
|
77
60
|
return stats;
|
78
61
|
}
|
79
62
|
|
80
|
-
function getNodeType(plan:
|
63
|
+
function getNodeType(plan: PlanNode) {
|
81
64
|
switch (plan.PlanNodeType) {
|
82
65
|
case 'Connection':
|
83
66
|
return 'connection';
|
@@ -90,11 +73,11 @@ function getNodeType(plan: Plan) {
|
|
90
73
|
}
|
91
74
|
}
|
92
75
|
|
93
|
-
export function preparePlan(plan:
|
94
|
-
const nodes: GraphNode[] = [];
|
76
|
+
export function preparePlan(plan: PlanNode) {
|
77
|
+
const nodes: GraphNode<ExplainPlanNodeData>[] = [];
|
95
78
|
const links: Link[] = [];
|
96
79
|
|
97
|
-
function parsePlans(plans:
|
80
|
+
function parsePlans(plans: PlanNode[] = [], from: string) {
|
98
81
|
plans.forEach((p) => {
|
99
82
|
const node: GraphNode<ExplainPlanNodeData> = {
|
100
83
|
name: String(p.PlanNodeId),
|