From 5dfe245f2d1fbae482b74e1605e09fcbd720e42e Mon Sep 17 00:00:00 2001
From: Vikrant Gupta <vikrant.thomso@gmail.com>
Date: Tue, 24 Dec 2024 19:07:20 +0530
Subject: [PATCH 1/3] chore: fix cross spawn vulnerability (#6709)

---
 frontend/package.json |  3 ++-
 frontend/yarn.lock    | 50 +++++--------------------------------------
 2 files changed, 7 insertions(+), 46 deletions(-)

diff --git a/frontend/package.json b/frontend/package.json
index bbfd1c8564..0379ac9bff 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -242,6 +242,7 @@
 		"xml2js": "0.5.0",
 		"phin": "^3.7.1",
 		"body-parser": "1.20.3",
-		"http-proxy-middleware": "3.0.3"
+		"http-proxy-middleware": "3.0.3",
+		"cross-spawn": "7.0.5"
 	}
 }
diff --git a/frontend/yarn.lock b/frontend/yarn.lock
index 8f1214a21a..15e4b72c0f 100644
--- a/frontend/yarn.lock
+++ b/frontend/yarn.lock
@@ -6740,21 +6740,10 @@ cross-fetch@3.1.5:
   dependencies:
     node-fetch "2.6.7"
 
-cross-spawn@^6.0.5:
-  version "6.0.5"
-  resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
-  integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
-  dependencies:
-    nice-try "^1.0.4"
-    path-key "^2.0.1"
-    semver "^5.5.0"
-    shebang-command "^1.2.0"
-    which "^1.2.9"
-
-cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
-  version "7.0.3"
-  resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz"
-  integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
+cross-spawn@7.0.5, cross-spawn@^6.0.5, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
+  version "7.0.5"
+  resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.5.tgz#910aac880ff5243da96b728bc6521a5f6c2f2f82"
+  integrity sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==
   dependencies:
     path-key "^3.1.0"
     shebang-command "^2.0.0"
@@ -12120,11 +12109,6 @@ nice-color-palettes@^1.0.1:
     new-array "^1.0.0"
     xhr-request "^1.0.1"
 
-nice-try@^1.0.4:
-  version "1.0.5"
-  resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
-  integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
-
 no-case@^3.0.4:
   version "3.0.4"
   resolved "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz"
@@ -12682,11 +12666,6 @@ path-is-absolute@^1.0.0:
   resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz"
   integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
 
-path-key@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
-  integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==
-
 path-key@^3.0.0, path-key@^3.1.0:
   version "3.1.1"
   resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz"
@@ -14758,7 +14737,7 @@ selfsigned@^2.1.1:
   dependencies:
     node-forge "^1"
 
-"semver@2 || 3 || 4 || 5", semver@7.3.7, semver@7.5.4, semver@7.x, semver@^5.5.0, semver@^5.6.0, semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0, semver@^6.3.1, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7:
+"semver@2 || 3 || 4 || 5", semver@7.3.7, semver@7.5.4, semver@7.x, semver@^5.6.0, semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0, semver@^6.3.1, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7:
   version "7.5.4"
   resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
   integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
@@ -14870,13 +14849,6 @@ shallowequal@^1.1.0:
   resolved "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz"
   integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==
 
-shebang-command@^1.2.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
-  integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==
-  dependencies:
-    shebang-regex "^1.0.0"
-
 shebang-command@^2.0.0:
   version "2.0.0"
   resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz"
@@ -14884,11 +14856,6 @@ shebang-command@^2.0.0:
   dependencies:
     shebang-regex "^3.0.0"
 
-shebang-regex@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
-  integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==
-
 shebang-regex@^3.0.0:
   version "3.0.0"
   resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz"
@@ -16765,13 +16732,6 @@ which-typed-array@^1.1.9:
     has-tostringtag "^1.0.0"
     is-typed-array "^1.1.10"
 
-which@^1.2.9:
-  version "1.3.1"
-  resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
-  integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
-  dependencies:
-    isexe "^2.0.0"
-
 which@^2.0.1, which@^2.0.2:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"

From 838192cf5c621715769917132f57e265a5b343fe Mon Sep 17 00:00:00 2001
From: Shaheer Kochai <ashaheerki@gmail.com>
Date: Tue, 24 Dec 2024 19:55:07 +0430
Subject: [PATCH 2/3] fix(Traces Explorer): prevent duplicate API calls to
 query_range in traces explorer (#6677)

* fix(Traces Explorer): prevent duplicate API calls to query_range in traces explorer

* fix(QueryBuilder): fix the race condition causing duplicate triggering of initQueryBuilderData

* chore: address review comments

* fix: fix the failing tests

---------

Co-authored-by: Vikrant Gupta <vikrant.thomso@gmail.com>
---
 .../TracesExplorer/ListView/index.tsx         | 64 +++++++++++++------
 .../pages/TracesExplorer/Filter/Filter.tsx    |  4 ++
 .../__test__/TracesExplorer.test.tsx          |  7 ++
 frontend/src/providers/QueryBuilder.tsx       |  7 +-
 4 files changed, 60 insertions(+), 22 deletions(-)

diff --git a/frontend/src/container/TracesExplorer/ListView/index.tsx b/frontend/src/container/TracesExplorer/ListView/index.tsx
index e59906c075..1c8209f709 100644
--- a/frontend/src/container/TracesExplorer/ListView/index.tsx
+++ b/frontend/src/container/TracesExplorer/ListView/index.tsx
@@ -7,10 +7,12 @@ import { REACT_QUERY_KEY } from 'constants/reactQueryKeys';
 import EmptyLogsSearch from 'container/EmptyLogsSearch/EmptyLogsSearch';
 import NoLogs from 'container/NoLogs/NoLogs';
 import { useOptionsMenu } from 'container/OptionsMenu';
+import { CustomTimeType } from 'container/TopNav/DateTimeSelectionV2/config';
 import TraceExplorerControls from 'container/TracesExplorer/Controls';
 import { useGetQueryRange } from 'hooks/queryBuilder/useGetQueryRange';
 import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
 import { Pagination } from 'hooks/queryPagination';
+import { getDefaultPaginationConfig } from 'hooks/queryPagination/utils';
 import useDragColumns from 'hooks/useDragColumns';
 import { getDraggedColumns } from 'hooks/useDragColumns/utils';
 import useUrlQueryData from 'hooks/useUrlQueryData';
@@ -32,12 +34,19 @@ interface ListViewProps {
 }
 
 function ListView({ isFilterApplied }: ListViewProps): JSX.Element {
-	const { stagedQuery, panelType } = useQueryBuilder();
+	const {
+		stagedQuery,
+		panelType: panelTypeFromQueryBuilder,
+	} = useQueryBuilder();
 
-	const { selectedTime: globalSelectedTime, maxTime, minTime } = useSelector<
-		AppState,
-		GlobalReducer
-	>((state) => state.globalTime);
+	const panelType = panelTypeFromQueryBuilder || PANEL_TYPES.LIST;
+
+	const {
+		selectedTime: globalSelectedTime,
+		maxTime,
+		minTime,
+		loading: timeRangeUpdateLoading,
+	} = useSelector<AppState, GlobalReducer>((state) => state.globalTime);
 
 	const { options, config } = useOptionsMenu({
 		storageKey: LOCALSTORAGE.TRACES_LIST_OPTIONS,
@@ -55,34 +64,51 @@ function ListView({ isFilterApplied }: ListViewProps): JSX.Element {
 	const { queryData: paginationQueryData } = useUrlQueryData<Pagination>(
 		QueryParams.pagination,
 	);
+	const paginationConfig =
+		paginationQueryData ?? getDefaultPaginationConfig(PER_PAGE_OPTIONS);
+
+	const queryKey = useMemo(
+		() => [
+			REACT_QUERY_KEY.GET_QUERY_RANGE,
+			globalSelectedTime,
+			maxTime,
+			minTime,
+			stagedQuery,
+			panelType,
+			paginationConfig,
+			options?.selectColumns,
+		],
+		[
+			stagedQuery,
+			panelType,
+			globalSelectedTime,
+			paginationConfig,
+			options?.selectColumns,
+			maxTime,
+			minTime,
+		],
+	);
 
 	const { data, isFetching, isLoading, isError } = useGetQueryRange(
 		{
 			query: stagedQuery || initialQueriesMap.traces,
-			graphType: panelType || PANEL_TYPES.LIST,
-			selectedTime: 'GLOBAL_TIME',
-			globalSelectedInterval: globalSelectedTime,
+			graphType: panelType,
+			selectedTime: 'GLOBAL_TIME' as const,
+			globalSelectedInterval: globalSelectedTime as CustomTimeType,
 			params: {
 				dataSource: 'traces',
 			},
 			tableParams: {
-				pagination: paginationQueryData,
+				pagination: paginationConfig,
 				selectColumns: options?.selectColumns,
 			},
 		},
 		DEFAULT_ENTITY_VERSION,
 		{
-			queryKey: [
-				REACT_QUERY_KEY.GET_QUERY_RANGE,
-				globalSelectedTime,
-				maxTime,
-				minTime,
-				stagedQuery,
-				panelType,
-				paginationQueryData,
-				options?.selectColumns,
-			],
+			queryKey,
 			enabled:
+				// don't make api call while the time range state in redux is loading
+				!timeRangeUpdateLoading &&
 				!!stagedQuery &&
 				panelType === PANEL_TYPES.LIST &&
 				!!options?.selectColumns?.length,
diff --git a/frontend/src/pages/TracesExplorer/Filter/Filter.tsx b/frontend/src/pages/TracesExplorer/Filter/Filter.tsx
index 27c3b65950..c4ee2dba5a 100644
--- a/frontend/src/pages/TracesExplorer/Filter/Filter.tsx
+++ b/frontend/src/pages/TracesExplorer/Filter/Filter.tsx
@@ -203,6 +203,10 @@ export function Filter(props: FilterProps): JSX.Element {
 					selectedFilters,
 				});
 			}
+
+			if (isEqual(currentQuery, preparedQuery) && !props?.resetAll) {
+				return;
+			}
 			redirectWithQueryBuilderData(preparedQuery);
 		},
 		[currentQuery, redirectWithQueryBuilderData, selectedFilters],
diff --git a/frontend/src/pages/TracesExplorer/__test__/TracesExplorer.test.tsx b/frontend/src/pages/TracesExplorer/__test__/TracesExplorer.test.tsx
index c4fdf588de..d5e89feb20 100644
--- a/frontend/src/pages/TracesExplorer/__test__/TracesExplorer.test.tsx
+++ b/frontend/src/pages/TracesExplorer/__test__/TracesExplorer.test.tsx
@@ -109,6 +109,13 @@ jest.mock('container/OptionsMenu/useOptionsMenu', () => ({
 	default: (): any => optionMenuReturn,
 }));
 
+jest.mock('react-redux', () => ({
+	...jest.requireActual('react-redux'),
+	useSelector: (): any => ({
+		loading: false,
+	}),
+}));
+
 describe('TracesExplorer - Filters', () => {
 	// Initial filter panel rendering
 	// Test the initial state like which filters section are opened, default state of duration slider, etc.
diff --git a/frontend/src/providers/QueryBuilder.tsx b/frontend/src/providers/QueryBuilder.tsx
index b79538cb45..9db10d2767 100644
--- a/frontend/src/providers/QueryBuilder.tsx
+++ b/frontend/src/providers/QueryBuilder.tsx
@@ -95,7 +95,8 @@ export function QueryBuilderProvider({
 	const urlQuery = useUrlQuery();
 	const history = useHistory();
 	const location = useLocation();
-	const currentPathnameRef = useRef<string | null>(null);
+
+	const currentPathnameRef = useRef<string | null>(location.pathname);
 
 	const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
 		(state) => state.globalTime,
@@ -814,14 +815,14 @@ export function QueryBuilderProvider({
 	};
 
 	useEffect(() => {
-		if (stagedQuery && location.pathname !== currentPathnameRef.current) {
+		if (location.pathname !== currentPathnameRef.current) {
 			currentPathnameRef.current = location.pathname;
 
 			setStagedQuery(null);
 			// reset the last used query to 0 when navigating away from the page
 			setLastUsedQuery(0);
 		}
-	}, [location, stagedQuery, currentQuery]);
+	}, [location.pathname]);
 
 	const handleOnUnitsChange = useCallback(
 		(unit: string) => {

From d2aa1cf06e4b0a83bc70f6e0f5416ab6c68af3ed Mon Sep 17 00:00:00 2001
From: Shaheer Kochai <ashaheerki@gmail.com>
Date: Tue, 24 Dec 2024 20:09:48 +0430
Subject: [PATCH 3/3] fix: fix the issue of saved view overriding query for
 logs and traces (#6678)

* fix: fix the issue of saved view overriding query for logs and traces for builder type query

* chore: refactored isDefaultQuery to use a function to extract relevant keys and use lodash's isEqual

* fix: add check for multiple queries in isDefaultQuery logic

* chore: moved extractRelevantKeys outside isDefaultQuery

* fix: fix the failing tests
---
 .../ExplorerOptions/ExplorerOptions.tsx       | 14 ++-
 .../__tests__/LogsExplorer.test.tsx           |  1 +
 .../TracesExplorer/__test__/testUtils.ts      |  1 +
 frontend/src/providers/QueryBuilder.tsx       | 88 ++++++++++++++++++-
 frontend/src/types/common/queryBuilder.ts     |  6 ++
 5 files changed, 108 insertions(+), 2 deletions(-)

diff --git a/frontend/src/container/ExplorerOptions/ExplorerOptions.tsx b/frontend/src/container/ExplorerOptions/ExplorerOptions.tsx
index 8bccc41c67..85ce464db4 100644
--- a/frontend/src/container/ExplorerOptions/ExplorerOptions.tsx
+++ b/frontend/src/container/ExplorerOptions/ExplorerOptions.tsx
@@ -112,6 +112,7 @@ function ExplorerOptions({
 		panelType,
 		isStagedQueryUpdated,
 		redirectWithQueryBuilderData,
+		isDefaultQuery,
 	} = useQueryBuilder();
 
 	const handleSaveViewModalToggle = (): void => {
@@ -478,6 +479,11 @@ function ExplorerOptions({
 	] = useState(false);
 
 	useEffect(() => {
+		// If the query is not the default query, don't set the recently used saved view
+		if (!isDefaultQuery({ currentQuery, sourcePage: sourcepage })) {
+			return;
+		}
+
 		const parsedPreservedView = JSON.parse(
 			localStorage.getItem(PRESERVED_VIEW_LOCAL_STORAGE_KEY) || '{}',
 		);
@@ -499,12 +505,18 @@ function ExplorerOptions({
 			setIsRecentlyUsedSavedViewSelected(false);
 		}
 
-		return (): void => clearTimeout(timeoutId);
+		// eslint-disable-next-line consistent-return
+		return (): void => {
+			clearTimeout(timeoutId);
+		};
 	}, [
 		PRESERVED_VIEW_LOCAL_STORAGE_KEY,
 		PRESERVED_VIEW_TYPE,
+		currentQuery,
+		isDefaultQuery,
 		isRecentlyUsedSavedViewSelected,
 		onMenuItemSelectHandler,
+		sourcepage,
 		viewKey,
 		viewName,
 		viewsData?.data?.data,
diff --git a/frontend/src/pages/LogsExplorer/__tests__/LogsExplorer.test.tsx b/frontend/src/pages/LogsExplorer/__tests__/LogsExplorer.test.tsx
index f76bdce610..f22bfbac80 100644
--- a/frontend/src/pages/LogsExplorer/__tests__/LogsExplorer.test.tsx
+++ b/frontend/src/pages/LogsExplorer/__tests__/LogsExplorer.test.tsx
@@ -155,6 +155,7 @@ describe('Logs Explorer Tests', () => {
 		const { queryAllByText } = render(
 			<QueryBuilderContext.Provider
 				value={{
+					isDefaultQuery: (): boolean => false,
 					currentQuery: {
 						...initialQueriesMap.metrics,
 						builder: {
diff --git a/frontend/src/pages/TracesExplorer/__test__/testUtils.ts b/frontend/src/pages/TracesExplorer/__test__/testUtils.ts
index 8a46740e6a..22817103e5 100644
--- a/frontend/src/pages/TracesExplorer/__test__/testUtils.ts
+++ b/frontend/src/pages/TracesExplorer/__test__/testUtils.ts
@@ -195,6 +195,7 @@ export const compositeQuery: Query = {
 export const redirectWithQueryBuilderData = jest.fn();
 
 export const qbProviderValue = {
+	isDefaultQuery: jest.fn(() => false),
 	currentQuery: {
 		...initialQueriesMap.traces,
 		builder: {
diff --git a/frontend/src/providers/QueryBuilder.tsx b/frontend/src/providers/QueryBuilder.tsx
index 9db10d2767..031ca9841f 100644
--- a/frontend/src/providers/QueryBuilder.tsx
+++ b/frontend/src/providers/QueryBuilder.tsx
@@ -27,7 +27,7 @@ import { createIdFromObjectFields } from 'lib/createIdFromObjectFields';
 import { createNewBuilderItemName } from 'lib/newQueryBuilder/createNewBuilderItemName';
 import { getOperatorsBySourceAndPanelType } from 'lib/newQueryBuilder/getOperatorsBySourceAndPanelType';
 import { replaceIncorrectObjectFields } from 'lib/replaceIncorrectObjectFields';
-import { cloneDeep, get, merge, set } from 'lodash-es';
+import { cloneDeep, get, isEqual, merge, set } from 'lodash-es';
 import {
 	createContext,
 	PropsWithChildren,
@@ -53,6 +53,7 @@ import { ViewProps } from 'types/api/saveViews/types';
 import { EQueryType } from 'types/common/dashboard';
 import {
 	DataSource,
+	IsDefaultQueryProps,
 	QueryBuilderContextType,
 	QueryBuilderData,
 } from 'types/common/queryBuilder';
@@ -87,6 +88,7 @@ export const QueryBuilderContext = createContext<QueryBuilderContextType>({
 	initQueryBuilderData: () => {},
 	handleOnUnitsChange: () => {},
 	isStagedQueryUpdated: () => false,
+	isDefaultQuery: () => false,
 });
 
 export function QueryBuilderProvider({
@@ -250,6 +252,88 @@ export function QueryBuilderProvider({
 		[getElementWithActualOperator],
 	);
 
+	const extractRelevantKeys = useCallback(
+		(queryData: IBuilderQuery): IBuilderQuery => {
+			const {
+				dataSource,
+				queryName,
+				aggregateOperator,
+				aggregateAttribute,
+				timeAggregation,
+				spaceAggregation,
+				functions,
+				filters,
+				expression,
+				disabled,
+				stepInterval,
+				having,
+				groupBy,
+				legend,
+			} = queryData;
+
+			return {
+				dataSource,
+				queryName,
+				aggregateOperator,
+				// remove id from aggregateAttribute
+				aggregateAttribute: {
+					...aggregateAttribute,
+					id: '',
+				},
+				timeAggregation,
+				spaceAggregation,
+				functions,
+				filters,
+				expression,
+				disabled,
+				stepInterval,
+				having,
+				groupBy,
+				legend,
+				// set to default values
+				orderBy: [],
+				limit: null,
+				reduceTo: 'avg',
+			};
+		},
+		[],
+	);
+
+	const isDefaultQuery = useCallback(
+		({ currentQuery, sourcePage }: IsDefaultQueryProps): boolean => {
+			// Get default query with updated operators
+			const defaultQuery = updateAllQueriesOperators(
+				initialQueriesMap[sourcePage],
+				PANEL_TYPES.LIST,
+				sourcePage,
+			);
+
+			// Early return if query types don't match
+			if (currentQuery.queryType !== defaultQuery.queryType) {
+				return false;
+			}
+
+			// Only compare builder queries
+			if (currentQuery.queryType !== EQueryType.QUERY_BUILDER) {
+				return false;
+			}
+
+			// If there is more than one query, then it is not a default query
+			if (currentQuery.builder.queryData.length > 1) {
+				return false;
+			}
+
+			const currentBuilderData = extractRelevantKeys(
+				currentQuery.builder.queryData[0],
+			);
+			const defaultBuilderData = extractRelevantKeys(
+				defaultQuery.builder.queryData[0],
+			);
+
+			return isEqual(currentBuilderData, defaultBuilderData);
+		},
+		[updateAllQueriesOperators, extractRelevantKeys],
+	);
 	const updateQueriesData = useCallback(
 		<T extends keyof QueryBuilderData>(
 			query: Query,
@@ -884,6 +968,7 @@ export function QueryBuilderProvider({
 			handleRunQuery,
 			resetQuery,
 			updateAllQueriesOperators,
+			isDefaultQuery,
 			updateQueriesData,
 			initQueryBuilderData,
 			handleOnUnitsChange,
@@ -910,6 +995,7 @@ export function QueryBuilderProvider({
 			redirectWithQueryBuilderData,
 			handleRunQuery,
 			updateAllQueriesOperators,
+			isDefaultQuery,
 			updateQueriesData,
 			initQueryBuilderData,
 			handleOnUnitsChange,
diff --git a/frontend/src/types/common/queryBuilder.ts b/frontend/src/types/common/queryBuilder.ts
index 0987347fd5..fe77e1ad68 100644
--- a/frontend/src/types/common/queryBuilder.ts
+++ b/frontend/src/types/common/queryBuilder.ts
@@ -247,9 +247,15 @@ export type QueryBuilderContextType = {
 		viewData: ViewProps[] | undefined,
 		viewKey: string,
 	) => boolean;
+	isDefaultQuery: (props: IsDefaultQueryProps) => boolean;
 };
 
 export type QueryAdditionalFilter = {
 	field: keyof IBuilderQuery;
 	text: string;
 };
+
+export type IsDefaultQueryProps = {
+	currentQuery: Query;
+	sourcePage: DataSource;
+};