Skip to content

Commit 6a1ff44

Browse files
feat: add QUERY_TECHNICAL_MARK to all UI queries
1 parent 9ac8cfc commit 6a1ff44

File tree

9 files changed

+76
-62
lines changed

9 files changed

+76
-62
lines changed

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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,18 @@ import i18n from '../i18n';
1616
import '../TenantOverview.scss';
1717

1818
interface TopTablesProps {
19-
path: string;
19+
database: string;
2020
}
2121

2222
const TOP_TABLES_COLUMNS_WIDTH_LS_KEY = 'topTablesTableColumnsWidth';
2323

24-
export function TopTables({path}: TopTablesProps) {
24+
export function TopTables({database}: TopTablesProps) {
2525
const location = useLocation();
2626

2727
const [autoRefreshInterval] = useAutoRefreshInterval();
2828

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

src/store/reducers/cluster/utils.ts

Lines changed: 4 additions & 3 deletions
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

78
export const createSelectClusterGroupsQuery = (clusterRoot: string) => {
8-
return `
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 \`${clusterRoot}/.sys/ds_storage_stats\`
18+
ORDER BY CurrentGroupsCreated DESC;
1819
`;
1920
};
2021

src/store/reducers/executeTopQueries/executeTopQueries.ts

Lines changed: 30 additions & 23 deletions
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 = (database: string, filters?: TopQueriesFilters, sortOrder?: SortOrder[]) => {
30+
const filterConditions = getFiltersConditions(database, 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,36 @@ SELECT ${QUERY_TECHNICAL_MARK}
4241
ReadBytes,
4342
UserSID,
4443
Duration
45-
FROM \`${path}/.sys/top_queries_by_cpu_time_one_hour\`
44+
FROM \`${database}/.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(
52+
database: string,
53+
filters?: TopQueriesFilters,
54+
sortOrder?: SortOrder[],
55+
) {
56+
const filterConditions = filters?.text
57+
? `Query ILIKE '%${filters.text}%' OR UserSID ILIKE '%${filters.text}%'`
58+
: '';
59+
60+
const orderBy = prepareOrderByFromTableSort(sortOrder);
61+
62+
return `${QUERY_TECHNICAL_MARK}
63+
SELECT
64+
UserSID,
65+
QueryStartAt,
66+
Query as QueryText,
67+
ApplicationName
68+
FROM \`${database}/.sys/query_sessions\`
69+
WHERE ${filterConditions || 'true'} AND Query NOT LIKE '%${QUERY_TECHNICAL_MARK}%'
70+
${orderBy}
71+
LIMIT 100`;
72+
}
73+
5274
interface TopQueriesRequestParams {
5375
database: string;
5476
filters?: TopQueriesFilters;
@@ -102,24 +124,9 @@ export const topQueriesApi = api.injectEndpoints({
102124
getRunningQueries: build.query({
103125
queryFn: async ({database, filters, sortOrder}: TopQueriesRequestParams, {signal}) => {
104126
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-
120127
const response = await window.api.viewer.sendQuery(
121128
{
122-
query: queryText,
129+
query: getRunningQueriesText(database, filters, sortOrder),
123130
database,
124131
action: 'execute-scan',
125132
},

src/store/reducers/executeTopQueries/utils.ts

Lines changed: 4 additions & 4 deletions
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 = (database: string) => `(
99
SELECT
1010
MAX(${intervalEndColumn})
11-
FROM \`${path}/.sys/top_queries_by_cpu_time_one_hour\`
11+
FROM \`${database}/.sys/top_queries_by_cpu_time_one_hour\`
1212
)`;
1313

14-
export function getFiltersConditions(path: string, filters?: TopQueriesFilters) {
14+
export function getFiltersConditions(database: string, 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(database)}`);
3737
}
3838

3939
if (filters?.text) {

src/store/reducers/shardsWorkload/shardsWorkload.ts

Lines changed: 16 additions & 13 deletions
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,12 +38,12 @@ 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`
45+
const pathSelect = database
46+
? `CAST(SUBSTRING(CAST(Path AS String), ${database.length}) AS Utf8) AS Path`
4647
: 'Path';
4748

4849
let where = `Path='${path}' OR Path LIKE '${path}/%'`;
@@ -54,7 +55,8 @@ function createShardQueryHistorical(
5455

5556
const orderBy = prepareOrderByFromTableSort(sortOrder);
5657

57-
return `SELECT
58+
return `${QUERY_TECHNICAL_MARK}
59+
SELECT
5860
${pathSelect},
5961
TabletId,
6062
CPUCores,
@@ -63,27 +65,28 @@ function createShardQueryHistorical(
6365
PeakTime,
6466
InFlightTxCount,
6567
IntervalEnd
66-
FROM \`.sys/top_partitions_one_hour\`
68+
FROM \`${database}/.sys/top_partitions_one_hour\`
6769
WHERE ${where}
6870
${orderBy}
6971
LIMIT 20`;
7072
}
7173

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`
74+
function createShardQueryImmediate(path: string, database: string, sortOrder?: SortOrder[]) {
75+
const pathSelect = database
76+
? `CAST(SUBSTRING(CAST(Path AS String), ${database.length}) AS Utf8) AS Path`
7577
: 'Path';
7678

7779
const orderBy = prepareOrderByFromTableSort(sortOrder);
7880

79-
return `SELECT
81+
return `${QUERY_TECHNICAL_MARK}
82+
SELECT
8083
${pathSelect},
8184
TabletId,
8285
CPUCores,
8386
DataSize,
8487
NodeId,
8588
InFlightTxCount
86-
FROM \`.sys/partition_stats\`
89+
FROM \`${database}/.sys/partition_stats\`
8790
WHERE
8891
Path='${path}'
8992
OR Path LIKE '${path}/%'
@@ -110,7 +113,7 @@ export const {setShardsQueryFilters} = slice.actions;
110113
export default slice.reducer;
111114

112115
interface SendShardQueryParams {
113-
database?: string;
116+
database: string;
114117
path?: string;
115118
sortOrder?: SortOrder[];
116119
filters?: ShardsWorkloadFilters;
@@ -128,12 +131,12 @@ export const shardApi = api.injectEndpoints({
128131
{
129132
query:
130133
filters?.mode === EShardsWorkloadMode.Immediate
131-
? createShardQueryImmediate(path, sortOrder, database)
134+
? createShardQueryImmediate(path, database, sortOrder)
132135
: createShardQueryHistorical(
133136
path,
137+
database,
134138
filters,
135139
sortOrder,
136-
database,
137140
),
138141
database,
139142
action: queryAction,

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

Lines changed: 9 additions & 9 deletions
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 = (database: string) => {
6+
return `${QUERY_TECHNICAL_MARK}
77
SELECT
88
Path, SUM(DataSize) as Size
9-
FROM \`${path}/.sys/partition_stats\`
9+
FROM \`${database}/.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(database),
24+
database,
2525
action: 'execute-scan',
2626
},
2727
{signal, withRetries: true},

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
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`
5+
function createShardQuery(path: string, database: string) {
6+
const pathSelect = database
7+
? `CAST(SUBSTRING(CAST(Path AS String), ${database.length}) AS Utf8) AS Path`
88
: 'Path';
99

10-
return `SELECT
10+
return `${QUERY_TECHNICAL_MARK}
11+
SELECT
1112
${pathSelect},
1213
TabletId,
1314
CPUCores,
14-
FROM \`.sys/partition_stats\`
15+
FROM \`${database}/.sys/partition_stats\`
1516
WHERE
1617
Path='${path}'
1718
OR Path LIKE '${path}/%'

src/utils/constants.ts

Lines changed: 2 additions & 0 deletions
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)