allow segment table to sort on start and end when grouped (#15720)

This commit is contained in:
Vadim Ogievetsky 2024-01-26 02:59:23 -08:00 committed by GitHub
parent 4e50a14d50
commit 45ad47cc66
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 49 additions and 40 deletions

View File

@ -26,6 +26,10 @@
.rt-td.padded, .rt-td.padded,
.rt-expandable { .rt-expandable {
padding: $table-cell-v-padding $table-cell-h-padding; padding: $table-cell-v-padding $table-cell-h-padding;
.default-aggregated {
padding: 0;
}
} }
} }

View File

@ -218,6 +218,7 @@ exports[`SegmentsView matches snapshot 1`] = `
"width": 100, "width": 100,
}, },
Object { Object {
"Aggregated": [Function],
"Cell": [Function], "Cell": [Function],
"Header": "Shard spec", "Header": "Shard spec",
"accessor": "shard_spec", "accessor": "shard_spec",

View File

@ -56,6 +56,7 @@ import { Api } from '../../singletons';
import type { NumberLike } from '../../utils'; import type { NumberLike } from '../../utils';
import { import {
compact, compact,
countBy,
deepGet, deepGet,
filterMap, filterMap,
formatBytes, formatBytes,
@ -64,6 +65,7 @@ import {
isNumberLikeNaN, isNumberLikeNaN,
LocalStorageBackedVisibility, LocalStorageBackedVisibility,
LocalStorageKeys, LocalStorageKeys,
oneOf,
queryDruidSql, queryDruidSql,
QueryManager, QueryManager,
QueryState, QueryState,
@ -137,6 +139,11 @@ interface Sorted {
desc: boolean; desc: boolean;
} }
function sortedToOrderByClause(sorted: Sorted[]): string | undefined {
if (!sorted.length) return;
return 'ORDER BY ' + sorted.map(sort => `${C(sort.id)} ${sort.desc ? 'DESC' : 'ASC'}`).join(', ');
}
interface TableState { interface TableState {
page: number; page: number;
pageSize: number; pageSize: number;
@ -315,9 +322,9 @@ END AS "time_span"`,
let queryParts: string[]; let queryParts: string[];
let whereClause = ''; let filterClause = '';
if (whereParts.length) { if (whereParts.length) {
whereClause = SqlExpression.and(...whereParts).toString(); filterClause = SqlExpression.and(...whereParts).toString();
} }
let effectiveSorted = sorted; let effectiveSorted = sorted;
@ -331,61 +338,45 @@ END AS "time_span"`,
]); ]);
} }
const base = SegmentsView.baseQuery(visibleColumns);
const orderByClause = sortedToOrderByClause(effectiveSorted);
if (groupByInterval) { if (groupByInterval) {
const innerQuery = compact([ const innerQuery = compact([
`SELECT "start" || '/' || "end" AS "interval"`, `SELECT "start", "end"`,
`FROM sys.segments`, `FROM sys.segments`,
whereClause ? `WHERE ${whereClause}` : undefined, filterClause ? `WHERE ${filterClause}` : undefined,
`GROUP BY 1`, `GROUP BY 1, 2`,
sortedToOrderByClause(sorted.filter(sort => oneOf(sort.id, 'start', 'end'))) ||
`ORDER BY 1 DESC`, `ORDER BY 1 DESC`,
`LIMIT ${pageSize}`, `LIMIT ${pageSize}`,
page ? `OFFSET ${page * pageSize}` : undefined, page ? `OFFSET ${page * pageSize}` : undefined,
]).join('\n'); ]).join('\n');
const intervals: string = (await queryDruidSql({ query: innerQuery })) const intervals: string = (await queryDruidSql({ query: innerQuery }))
.map(row => `'${row.interval}'`) .map(({ start, end }) => `'${start}/${end}'`)
.join(', '); .join(', ');
queryParts = compact([ queryParts = compact([
SegmentsView.baseQuery(visibleColumns), base,
`SELECT "start" || '/' || "end" AS "interval", *`, `SELECT "start" || '/' || "end" AS "interval", *`,
`FROM s`, `FROM s`,
`WHERE`, `WHERE`,
intervals ? ` ("start" || '/' || "end") IN (${intervals})` : 'FALSE', intervals ? ` ("start" || '/' || "end") IN (${intervals})` : 'FALSE',
whereClause ? ` AND ${whereClause}` : '', filterClause ? ` AND ${filterClause}` : '',
orderByClause,
`LIMIT ${pageSize * 1000}`,
]); ]);
if (effectiveSorted.length) {
queryParts.push(
'ORDER BY ' +
effectiveSorted
.map(sort => `${C(sort.id)} ${sort.desc ? 'DESC' : 'ASC'}`)
.join(', '),
);
}
queryParts.push(`LIMIT ${pageSize * 1000}`);
} else { } else {
queryParts = [SegmentsView.baseQuery(visibleColumns), `SELECT *`, `FROM s`]; queryParts = compact([
base,
if (whereClause) { `SELECT *`,
queryParts.push(`WHERE ${whereClause}`); `FROM s`,
} filterClause ? `WHERE ${filterClause}` : undefined,
orderByClause,
if (effectiveSorted.length) { `LIMIT ${pageSize}`,
queryParts.push( page ? `OFFSET ${page * pageSize}` : undefined,
'ORDER BY ' + ]);
effectiveSorted
.map(sort => `${C(sort.id)} ${sort.desc ? 'DESC' : 'ASC'}`)
.join(', '),
);
}
queryParts.push(`LIMIT ${pageSize}`);
if (page) {
queryParts.push(`OFFSET ${page * pageSize}`);
}
} }
const sqlQuery = queryParts.join('\n'); const sqlQuery = queryParts.join('\n');
setIntermediateQuery(sqlQuery); setIntermediateQuery(sqlQuery);
@ -762,6 +753,19 @@ END AS "time_span"`,
); );
} }
}, },
Aggregated: opt => {
const { subRows } = opt;
const previewValues = filterMap(subRows, row => row['shard_spec'].type);
const previewCount = countBy(previewValues);
return (
<div className="default-aggregated">
{Object.keys(previewCount)
.sort()
.map(v => `${v} (${previewCount[v]})`)
.join(', ')}
</div>
);
},
}, },
{ {
Header: 'Partition', Header: 'Partition',