Skip to content

Commit 6d53518

Browse files
feat: add QUERY_TECHNICAL_MARK to all UI queries (#1992)
1 parent 5065ddf commit 6d53518

File tree

10 files changed

+69
-66
lines changed

10 files changed

+69
-66
lines changed

src/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/TenantStorage.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export function TenantStorage({tenantName, metrics}: TenantStorageProps) {
6868
<React.Fragment>
6969
<TenantDashboard database={tenantName} charts={storageDashboardConfig} />
7070
<InfoViewer className={b('storage-info')} title="Storage details" info={info} />
71-
<TopTables path={tenantName} />
71+
<TopTables database={tenantName} />
7272
<TopGroups tenant={tenantName} />
7373
</React.Fragment>
7474
);

src/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/TopTables.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,18 @@ import i18n from '../i18n';
1818
import '../TenantOverview.scss';
1919

2020
interface TopTablesProps {
21-
path: string;
21+
database: string;
2222
}
2323

2424
const TOP_TABLES_COLUMNS_WIDTH_LS_KEY = 'topTablesTableColumnsWidth';
2525

26-
export function TopTables({path}: TopTablesProps) {
26+
export function TopTables({database}: TopTablesProps) {
2727
const location = useLocation();
2828

2929
const [autoRefreshInterval] = useAutoRefreshInterval();
3030

3131
const {currentData, error, isFetching} = topTablesApi.useGetTopTablesQuery(
32-
{path},
32+
{database},
3333
{pollingInterval: autoRefreshInterval},
3434
);
3535
const loading = isFetching && currentData === undefined;

src/store/reducers/cluster/cluster.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export const clusterApi = api.injectEndpoints({
8787
}
8888

8989
try {
90-
const query = createSelectClusterGroupsQuery(clusterRoot);
90+
const query = createSelectClusterGroupsQuery();
9191

9292
// Normally query request should be fulfilled within 300-400ms even on very big clusters
9393
// Table with stats is supposed to be very small (less than 10 rows)

src/store/reducers/cluster/utils.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
import type {TClusterInfoV2, TStorageStats} from '../../../types/api/cluster';
22
import type {ExecuteQueryResponse, KeyValueRow} from '../../../types/api/query';
3+
import {QUERY_TECHNICAL_MARK} from '../../../utils/constants';
34
import {parseQueryAPIResponse} from '../../../utils/query';
45

56
import type {ClusterGroupsStats} from './types';
67

7-
export const createSelectClusterGroupsQuery = (clusterRoot: string) => {
8-
return `
8+
export const createSelectClusterGroupsQuery = () => {
9+
return `${QUERY_TECHNICAL_MARK}
910
SELECT
1011
PDiskFilter,
1112
ErasureSpecies,
1213
CurrentAvailableSize,
1314
CurrentAllocatedSize,
1415
CurrentGroupsCreated,
1516
AvailableGroupsToCreate
16-
FROM \`${clusterRoot}/.sys/ds_storage_stats\`
17-
ORDER BY CurrentGroupsCreated DESC;
17+
FROM \`.sys/ds_storage_stats\`
18+
ORDER BY CurrentGroupsCreated DESC;
1819
`;
1920
};
2021

src/store/reducers/executeTopQueries/executeTopQueries.ts

+27-24
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type {SortOrder} from '@gravity-ui/react-data-table';
33
import {createSlice} from '@reduxjs/toolkit';
44
import type {PayloadAction} from '@reduxjs/toolkit';
55

6+
import {QUERY_TECHNICAL_MARK} from '../../../utils/constants';
67
import {prepareOrderByFromTableSort} from '../../../utils/hooks/useTableSort';
78
import {isQueryErrorResponse, parseQueryAPIResponse} from '../../../utils/query';
89
import {api} from '../api';
@@ -12,8 +13,6 @@ import {getFiltersConditions} from './utils';
1213

1314
const initialState: TopQueriesFilters = {};
1415

15-
const QUERY_TECHNICAL_MARK = '/*UI-QUERY-EXCLUDE*/';
16-
1716
const slice = createSlice({
1817
name: 'executeTopQueries',
1918
initialState,
@@ -27,13 +26,13 @@ const slice = createSlice({
2726
export const {setTopQueriesFilters} = slice.actions;
2827
export default slice.reducer;
2928

30-
const getQueryText = (path: string, filters?: TopQueriesFilters, sortOrder?: SortOrder[]) => {
31-
const filterConditions = getFiltersConditions(path, filters);
29+
const getQueryText = (filters?: TopQueriesFilters, sortOrder?: SortOrder[]) => {
30+
const filterConditions = getFiltersConditions(filters);
3231

3332
const orderBy = prepareOrderByFromTableSort(sortOrder);
3433

35-
return `
36-
SELECT ${QUERY_TECHNICAL_MARK}
34+
return `${QUERY_TECHNICAL_MARK}
35+
SELECT
3736
CPUTime as CPUTimeUs,
3837
QueryText,
3938
IntervalEnd,
@@ -42,13 +41,32 @@ SELECT ${QUERY_TECHNICAL_MARK}
4241
ReadBytes,
4342
UserSID,
4443
Duration
45-
FROM \`${path}/.sys/top_queries_by_cpu_time_one_hour\`
44+
FROM \`.sys/top_queries_by_cpu_time_one_hour\`
4645
WHERE ${filterConditions || 'true'} AND QueryText NOT LIKE '%${QUERY_TECHNICAL_MARK}%'
4746
${orderBy}
4847
LIMIT 100
4948
`;
5049
};
5150

51+
function getRunningQueriesText(filters?: TopQueriesFilters, sortOrder?: SortOrder[]) {
52+
const filterConditions = filters?.text
53+
? `Query ILIKE '%${filters.text}%' OR UserSID ILIKE '%${filters.text}%'`
54+
: '';
55+
56+
const orderBy = prepareOrderByFromTableSort(sortOrder);
57+
58+
return `${QUERY_TECHNICAL_MARK}
59+
SELECT
60+
UserSID,
61+
QueryStartAt,
62+
Query as QueryText,
63+
ApplicationName
64+
FROM \`.sys/query_sessions\`
65+
WHERE ${filterConditions || 'true'} AND Query NOT LIKE '%${QUERY_TECHNICAL_MARK}%'
66+
${orderBy}
67+
LIMIT 100`;
68+
}
69+
5270
interface TopQueriesRequestParams {
5371
database: string;
5472
filters?: TopQueriesFilters;
@@ -68,7 +86,7 @@ export const topQueriesApi = api.injectEndpoints({
6886
try {
6987
const response = await window.api.viewer.sendQuery(
7088
{
71-
query: getQueryText(database, preparedFilters, sortOrder),
89+
query: getQueryText(preparedFilters, sortOrder),
7290
database,
7391
action: 'execute-scan',
7492
},
@@ -102,24 +120,9 @@ export const topQueriesApi = api.injectEndpoints({
102120
getRunningQueries: build.query({
103121
queryFn: async ({database, filters, sortOrder}: TopQueriesRequestParams, {signal}) => {
104122
try {
105-
const filterConditions = filters?.text
106-
? `Query ILIKE '%${filters.text}%' OR UserSID ILIKE '%${filters.text}%'`
107-
: '';
108-
109-
const orderBy = prepareOrderByFromTableSort(sortOrder);
110-
111-
const queryText = `SELECT ${QUERY_TECHNICAL_MARK}
112-
UserSID, QueryStartAt, Query as QueryText, ApplicationName
113-
FROM
114-
\`.sys/query_sessions\`
115-
WHERE
116-
${filterConditions || 'true'} AND Query NOT LIKE '%${QUERY_TECHNICAL_MARK}%'
117-
${orderBy}
118-
LIMIT 100`;
119-
120123
const response = await window.api.viewer.sendQuery(
121124
{
122-
query: queryText,
125+
query: getRunningQueriesText(filters, sortOrder),
123126
database,
124127
action: 'execute-scan',
125128
},

src/store/reducers/executeTopQueries/utils.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ import type {TopQueriesFilters} from './types';
55
const endTimeColumn = 'EndTime';
66
const intervalEndColumn = 'IntervalEnd';
77

8-
const getMaxIntervalSubquery = (path: string) => `(
8+
const getMaxIntervalSubquery = () => `(
99
SELECT
1010
MAX(${intervalEndColumn})
11-
FROM \`${path}/.sys/top_queries_by_cpu_time_one_hour\`
11+
FROM \`.sys/top_queries_by_cpu_time_one_hour\`
1212
)`;
1313

14-
export function getFiltersConditions(path: string, filters?: TopQueriesFilters) {
14+
export function getFiltersConditions(filters?: TopQueriesFilters) {
1515
const conditions: string[] = [];
1616
const to = dateTimeParse(Number(filters?.to) || filters?.to)?.valueOf();
1717
const from = dateTimeParse(Number(filters?.from) || filters?.from)?.valueOf();
@@ -33,7 +33,7 @@ export function getFiltersConditions(path: string, filters?: TopQueriesFilters)
3333

3434
// If there is no filters, return queries, that were executed in the last hour
3535
if (!from && !to) {
36-
conditions.push(`${intervalEndColumn} IN ${getMaxIntervalSubquery(path)}`);
36+
conditions.push(`${intervalEndColumn} IN ${getMaxIntervalSubquery()}`);
3737
}
3838

3939
if (filters?.text) {

src/store/reducers/shardsWorkload/shardsWorkload.ts

+12-13
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type {SortOrder} from '@gravity-ui/react-data-table';
33
import {createSlice} from '@reduxjs/toolkit';
44
import type {PayloadAction} from '@reduxjs/toolkit';
55

6+
import {QUERY_TECHNICAL_MARK} from '../../../utils/constants';
67
import {prepareOrderByFromTableSort} from '../../../utils/hooks/useTableSort';
78
import {isQueryErrorResponse, parseQueryAPIResponse} from '../../../utils/query';
89
import {api} from '../api';
@@ -37,13 +38,11 @@ function getFiltersConditions(filters?: ShardsWorkloadFilters) {
3738

3839
function createShardQueryHistorical(
3940
path: string,
41+
database: string,
4042
filters?: ShardsWorkloadFilters,
4143
sortOrder?: SortOrder[],
42-
tenantName?: string,
4344
) {
44-
const pathSelect = tenantName
45-
? `CAST(SUBSTRING(CAST(Path AS String), ${tenantName.length}) AS Utf8) AS Path`
46-
: 'Path';
45+
const pathSelect = `CAST(SUBSTRING(CAST(Path AS String), ${database.length}) AS Utf8) AS Path`;
4746

4847
let where = `Path='${path}' OR Path LIKE '${path}/%'`;
4948

@@ -54,7 +53,8 @@ function createShardQueryHistorical(
5453

5554
const orderBy = prepareOrderByFromTableSort(sortOrder);
5655

57-
return `SELECT
56+
return `${QUERY_TECHNICAL_MARK}
57+
SELECT
5858
${pathSelect},
5959
TabletId,
6060
CPUCores,
@@ -69,14 +69,13 @@ ${orderBy}
6969
LIMIT 20`;
7070
}
7171

72-
function createShardQueryImmediate(path: string, sortOrder?: SortOrder[], tenantName?: string) {
73-
const pathSelect = tenantName
74-
? `CAST(SUBSTRING(CAST(Path AS String), ${tenantName.length}) AS Utf8) AS Path`
75-
: 'Path';
72+
function createShardQueryImmediate(path: string, database: string, sortOrder?: SortOrder[]) {
73+
const pathSelect = `CAST(SUBSTRING(CAST(Path AS String), ${database.length}) AS Utf8) AS Path`;
7674

7775
const orderBy = prepareOrderByFromTableSort(sortOrder);
7876

79-
return `SELECT
77+
return `${QUERY_TECHNICAL_MARK}
78+
SELECT
8079
${pathSelect},
8180
TabletId,
8281
CPUCores,
@@ -110,7 +109,7 @@ export const {setShardsQueryFilters} = slice.actions;
110109
export default slice.reducer;
111110

112111
interface SendShardQueryParams {
113-
database?: string;
112+
database: string;
114113
path?: string;
115114
sortOrder?: SortOrder[];
116115
filters?: ShardsWorkloadFilters;
@@ -128,12 +127,12 @@ export const shardApi = api.injectEndpoints({
128127
{
129128
query:
130129
filters?.mode === EShardsWorkloadMode.Immediate
131-
? createShardQueryImmediate(path, sortOrder, database)
130+
? createShardQueryImmediate(path, database, sortOrder)
132131
: createShardQueryHistorical(
133132
path,
133+
database,
134134
filters,
135135
sortOrder,
136-
database,
137136
),
138137
database,
139138
action: queryAction,

src/store/reducers/tenantOverview/executeTopTables/executeTopTables.ts

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
1-
import {TENANT_OVERVIEW_TABLES_LIMIT} from '../../../../utils/constants';
1+
import {QUERY_TECHNICAL_MARK, TENANT_OVERVIEW_TABLES_LIMIT} from '../../../../utils/constants';
22
import {isQueryErrorResponse, parseQueryAPIResponse} from '../../../../utils/query';
33
import {api} from '../../api';
44

5-
const getQueryText = (path: string) => {
6-
return `
5+
const getQueryText = () => {
6+
return `${QUERY_TECHNICAL_MARK}
77
SELECT
88
Path, SUM(DataSize) as Size
9-
FROM \`${path}/.sys/partition_stats\`
9+
FROM \`.sys/partition_stats\`
1010
GROUP BY Path
11-
ORDER BY Size DESC
12-
LIMIT ${TENANT_OVERVIEW_TABLES_LIMIT}
11+
ORDER BY Size DESC
12+
LIMIT ${TENANT_OVERVIEW_TABLES_LIMIT}
1313
`;
1414
};
1515

1616
export const topTablesApi = api.injectEndpoints({
1717
endpoints: (builder) => ({
1818
getTopTables: builder.query({
19-
queryFn: async ({path}: {path: string}, {signal}) => {
19+
queryFn: async ({database}: {database: string}, {signal}) => {
2020
try {
2121
const response = await window.api.viewer.sendQuery(
2222
{
23-
query: getQueryText(path),
24-
database: path,
23+
query: getQueryText(),
24+
database,
2525
action: 'execute-scan',
2626
},
2727
{signal, withRetries: true},

src/store/reducers/tenantOverview/topShards/tenantOverviewTopShards.ts

+5-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
1-
import {TENANT_OVERVIEW_TABLES_LIMIT} from '../../../../utils/constants';
1+
import {QUERY_TECHNICAL_MARK, TENANT_OVERVIEW_TABLES_LIMIT} from '../../../../utils/constants';
22
import {isQueryErrorResponse, parseQueryAPIResponse} from '../../../../utils/query';
33
import {api} from '../../api';
44

5-
function createShardQuery(path: string, tenantName?: string) {
6-
const pathSelect = tenantName
7-
? `CAST(SUBSTRING(CAST(Path AS String), ${tenantName.length}) AS Utf8) AS Path`
8-
: 'Path';
9-
10-
return `SELECT
5+
function createShardQuery(path: string, database: string) {
6+
const pathSelect = `CAST(SUBSTRING(CAST(Path AS String), ${database.length}) AS Utf8) AS Path`;
7+
return `${QUERY_TECHNICAL_MARK}
8+
SELECT
119
${pathSelect},
1210
TabletId,
1311
CPUCores,

src/utils/constants.ts

+2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ export const TENANT_OVERVIEW_TABLES_LIMIT = 5;
5252

5353
export const EMPTY_DATA_PLACEHOLDER = '—';
5454

55+
export const QUERY_TECHNICAL_MARK = '/*UI-QUERY-EXCLUDE*/';
56+
5557
// ==== Titles ====
5658
export const DEVELOPER_UI_TITLE = 'Developer UI';
5759
export const CLUSTER_DEFAULT_TITLE = 'Cluster';

0 commit comments

Comments
 (0)