fix: prevent sending order by id with traces query (#8250)

* fix: prevent sending order by id with traces query

* test: write tests for preventing sending order by id with traces query
This commit is contained in:
Shaheer Kochai 2025-06-23 17:04:59 +04:30 committed by GitHub
parent 35e8165463
commit 133c0deaa8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 54 additions and 10 deletions

View File

@ -10,6 +10,7 @@ import { useMemo } from 'react';
import { useQuery, UseQueryOptions, UseQueryResult } from 'react-query'; import { useQuery, UseQueryOptions, UseQueryResult } from 'react-query';
import { SuccessResponse } from 'types/api'; import { SuccessResponse } from 'types/api';
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange'; import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
import { DataSource } from 'types/common/queryBuilder';
type UseGetQueryRange = ( type UseGetQueryRange = (
requestData: GetQueryResultsProps, requestData: GetQueryResultsProps,
@ -25,15 +26,13 @@ export const useGetQueryRange: UseGetQueryRange = (
headers, headers,
) => { ) => {
const newRequestData: GetQueryResultsProps = useMemo(() => { const newRequestData: GetQueryResultsProps = useMemo(() => {
const firstQueryData = requestData.query.builder?.queryData[0];
const isListWithSingleTimestampOrder = const isListWithSingleTimestampOrder =
requestData.graphType === PANEL_TYPES.LIST && requestData.graphType === PANEL_TYPES.LIST &&
requestData.query.builder?.queryData[0]?.orderBy?.length === 1 && firstQueryData?.orderBy?.length === 1 &&
// exclude list with id filter (i.e. context logs) // exclude list with id filter (i.e. context logs)
!requestData.query.builder?.queryData[0].filters.items.some( !firstQueryData?.filters.items.some((filter) => filter.key?.key === 'id') &&
(filter) => filter.key?.key === 'id', firstQueryData?.orderBy[0].columnName === 'timestamp';
) &&
requestData.query.builder?.queryData[0].orderBy[0].columnName ===
'timestamp';
const modifiedRequestData = { const modifiedRequestData = {
...requestData, ...requestData,
@ -44,17 +43,20 @@ export const useGetQueryRange: UseGetQueryRange = (
}; };
// If the query is a list with a single timestamp order, we need to add the id column to the order by clause // If the query is a list with a single timestamp order, we need to add the id column to the order by clause
if (isListWithSingleTimestampOrder) { if (
isListWithSingleTimestampOrder &&
firstQueryData?.dataSource === DataSource.LOGS
) {
modifiedRequestData.query.builder = { modifiedRequestData.query.builder = {
...requestData.query.builder, ...requestData.query.builder,
queryData: [ queryData: [
{ {
...requestData?.query?.builder?.queryData[0], ...firstQueryData,
orderBy: [ orderBy: [
...(requestData?.query?.builder?.queryData[0]?.orderBy || []), ...(firstQueryData?.orderBy || []),
{ {
columnName: 'id', columnName: 'id',
order: requestData?.query?.builder?.queryData[0]?.orderBy[0]?.order, order: firstQueryData?.orderBy[0]?.order,
}, },
], ],
}, },

View File

@ -26,6 +26,7 @@ import {
waitFor, waitFor,
within, within,
} from 'tests/test-utils'; } from 'tests/test-utils';
import { QueryRangePayload } from 'types/api/metrics/getQueryRange';
import TracesExplorer from '..'; import TracesExplorer from '..';
import { Filter } from '../Filter/Filter'; import { Filter } from '../Filter/Filter';
@ -449,6 +450,8 @@ jest.mock('hooks/useHandleExplorerTabChange', () => ({
})), })),
})); }));
let capturedPayload: QueryRangePayload;
describe('TracesExplorer - ', () => { describe('TracesExplorer - ', () => {
const quickFiltersListURL = `${BASE_URL}/api/v1/orgs/me/filters/traces`; const quickFiltersListURL = `${BASE_URL}/api/v1/orgs/me/filters/traces`;
@ -496,6 +499,45 @@ describe('TracesExplorer - ', () => {
// column interaction is covered in E2E tests as its a complex interaction // column interaction is covered in E2E tests as its a complex interaction
}); });
it('should not add id to orderBy when dataSource is traces', async () => {
server.use(
rest.post(`${BASE_URL}/api/v4/query_range`, async (req, res, ctx) => {
const payload = await req.json();
capturedPayload = payload;
return res(ctx.status(200), ctx.json(queryRangeForTableView));
}),
);
render(
<QueryBuilderContext.Provider
value={{
...qbProviderValue,
stagedQuery: {
...qbProviderValue.stagedQuery,
builder: {
...qbProviderValue.stagedQuery.builder,
queryData: [
{
...qbProviderValue.stagedQuery.builder.queryData[0],
orderBy: [{ columnName: 'timestamp', order: 'desc' }],
},
],
},
},
}}
>
<TracesExplorer />
</QueryBuilderContext.Provider>,
);
await waitFor(() => {
expect(capturedPayload).toBeDefined();
});
expect(capturedPayload.compositeQuery.builderQueries?.A.orderBy).toEqual([
{ columnName: 'timestamp', order: 'desc' },
]);
});
it('trace explorer - table view', async () => { it('trace explorer - table view', async () => {
server.use( server.use(