mirror of
https://github.com/supabase/supabase.git
synced 2026-09-22 13:37:53 +08:00
8bbd1d3048
## Summary
- `useIndexInvalidation()` resolves the `preset` URL param through
`QUERY_PERFORMANCE_PRESET_MAP` with no fallback.
- A value that isn't one of the four known
`QUERY_PERFORMANCE_REPORT_TYPES` (stale bookmark, hand-edited URL, a
renamed/removed preset) resolves to `undefined`.
- That `undefined` preset flows into `generateQueryPerformanceSql()`,
which indexes `queryPerfQueries.queries[preset]` with it, producing
`undefined` for `baseSQL` — and the very next line reads
`baseSQL.queryType`, crashing the whole page via `globalErrorBoundary`.
- Fix: fall back to the `unified` preset when the URL value doesn't map
to a known preset, mirroring the `parseAsString.withDefault('unified')`
intent already expressed a few lines above for the case where the param
is entirely absent.
## Evidence (Sentry, past week)
- [SUPABASE-APP-K9Z](https://supabase.sentry.io/issues/7721026586/) —
`TypeError: Cannot read properties of undefined (reading 'queryType')`
on `/dashboard/project/[ref]/observability/query-performance`.
## Test plan
- [ ] Existing `useQueryPerformanceQuery.test.ts` suite still passes
- [ ] Manually confirmed
`QUERY_PERFORMANCE_PRESET_MAP[QUERY_PERFORMANCE_REPORT_TYPES.UNIFIED]`
resolves to `'unified'`, a valid key in
`PRESET_CONFIG[Presets.QUERY_PERFORMANCE].queries`
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01RUrmUfMBpPqkgerh9onNTM
---
_Generated by [Claude
Code](https://claude.ai/code/session_01RUrmUfMBpPqkgerh9onNTM)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Ali Waseem <waseema393@gmail.com>
59 lines
2.3 KiB
TypeScript
59 lines
2.3 KiB
TypeScript
import { useQueryClient } from '@tanstack/react-query'
|
|
import { useRouter } from 'next/router'
|
|
import { parseAsString, useQueryStates } from 'nuqs'
|
|
import { useCallback } from 'react'
|
|
|
|
import {
|
|
QUERY_PERFORMANCE_PRESET_MAP,
|
|
QUERY_PERFORMANCE_REPORT_TYPES,
|
|
} from '../QueryPerformance.constants'
|
|
import { type QueryPerformanceSort } from '../QueryPerformance.types'
|
|
import { useQueryPerformanceQuery } from '../useQueryPerformanceQuery'
|
|
import { useIndexAdvisorStatus } from './useIsIndexAdvisorStatus'
|
|
import { useTableIndexAdvisor } from '@/components/grid/context/TableIndexAdvisorContext'
|
|
import { databaseIndexesKeys } from '@/data/database-indexes/keys'
|
|
import { databaseKeys } from '@/data/database/keys'
|
|
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
|
|
|
export function useIndexInvalidation() {
|
|
const router = useRouter()
|
|
const queryClient = useQueryClient()
|
|
const { data: project } = useSelectedProjectQuery()
|
|
const { isIndexAdvisorEnabled } = useIndexAdvisorStatus()
|
|
|
|
const [{ preset: urlPreset, search: searchQuery, order, sort }] = useQueryStates({
|
|
sort: parseAsString,
|
|
search: parseAsString.withDefault(''),
|
|
order: parseAsString,
|
|
preset: parseAsString.withDefault('unified'),
|
|
})
|
|
|
|
const { invalidate: invalidateTableIndexAdvisor } = useTableIndexAdvisor()
|
|
|
|
// Falls back to UNIFIED so an unrecognized preset param doesn't resolve to
|
|
// undefined and crash generateQueryPerformanceSql.
|
|
const preset =
|
|
QUERY_PERFORMANCE_PRESET_MAP[urlPreset as QUERY_PERFORMANCE_REPORT_TYPES] ??
|
|
QUERY_PERFORMANCE_PRESET_MAP[QUERY_PERFORMANCE_REPORT_TYPES.UNIFIED]
|
|
const orderBy = !!sort ? ({ column: sort, order } as QueryPerformanceSort) : undefined
|
|
const roles = router?.query?.roles ?? []
|
|
|
|
const queryPerformanceQuery = useQueryPerformanceQuery({
|
|
searchQuery,
|
|
orderBy,
|
|
preset,
|
|
roles: typeof roles === 'string' ? [roles] : roles,
|
|
runIndexAdvisor: isIndexAdvisorEnabled,
|
|
})
|
|
|
|
return useCallback(() => {
|
|
queryPerformanceQuery.runQuery()
|
|
queryClient.invalidateQueries({
|
|
queryKey: databaseKeys.indexAdvisorFromQuery(project?.ref, ''),
|
|
})
|
|
queryClient.invalidateQueries({ queryKey: databaseIndexesKeys.list(project?.ref) })
|
|
|
|
invalidateTableIndexAdvisor()
|
|
}, [queryPerformanceQuery, queryClient, project?.ref, invalidateTableIndexAdvisor])
|
|
}
|