mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 17:35:10 +03:00
## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Performance improvement ## What is the current behavior? The column privileges page in Studio only ever renders one table, but the underlying query still `aclexplode`s every column in the whole schema and filters the result client-side. ## What is the new behavior? Adds a scoped SQL path that prunes `pg_class`/`pg_namespace` to the requested schema+table before exploding ACLs, gated behind the `pgMetaScopedIntrospection` flag, with a plan-guard test asserting `pg_class`/`pg_attribute` stay index-driven. Studio's query hook and cache keys now thread the selected table through so column-privilege invalidation and cold-load races are scoped correctly, and the page fetches per-table instead of per-schema. ## Additional context <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Improvements** * Column privileges are now scoped to the selected schema and table for more accurate results. * Changing schemas automatically updates the table selection and refreshes the displayed privileges. * Privilege updates now refresh only the relevant schema, table, and column data. * Loading states are handled more accurately when no table is selected. * **Bug Fixes** * Improved consistency between scoped and unscoped column privilege results, including table-, column-, and grant-option privileges. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
58 lines
2.0 KiB
TypeScript
58 lines
2.0 KiB
TypeScript
export const privilegeKeys = {
|
|
tablePrivilegesList: (projectRef: string | undefined, includedSchemas?: string[]) =>
|
|
['projects', projectRef, 'database', 'table-privileges', includedSchemas].filter(Boolean),
|
|
columnPrivilegesList: (
|
|
projectRef: string | undefined,
|
|
schema?: string | undefined,
|
|
table?: string | undefined
|
|
) => {
|
|
const base = ['projects', projectRef, 'database', 'column-privileges'].filter(Boolean)
|
|
if (table === undefined) return schema === undefined ? base : [...base, schema]
|
|
return [...base, schema ?? null, table]
|
|
},
|
|
exposedTablesInfinite: (projectRef: string | undefined, search?: string) =>
|
|
[
|
|
'projects',
|
|
projectRef,
|
|
'privileges',
|
|
'exposed-tables-infinite',
|
|
...(search ? ([{ search }] as const) : []),
|
|
] as const,
|
|
exposedTablesAll: (projectRef: string | undefined) =>
|
|
['projects', projectRef, 'privileges', 'exposed-tables-all'] as const,
|
|
exposedFunctionsAll: (projectRef: string | undefined) =>
|
|
['projects', projectRef, 'privileges', 'exposed-functions-all'] as const,
|
|
exposedTableCounts: (projectRef: string | undefined, selectedSchemas?: string[]) =>
|
|
[
|
|
'projects',
|
|
projectRef,
|
|
'privileges',
|
|
'exposed-table-counts',
|
|
...(selectedSchemas ? ([selectedSchemas] as const) : []),
|
|
] as const,
|
|
exposedFunctionsInfinite: (projectRef: string | undefined, search?: string) =>
|
|
[
|
|
'projects',
|
|
projectRef,
|
|
'privileges',
|
|
'exposed-functions-infinite',
|
|
...(search ? ([{ search }] as const) : []),
|
|
] as const,
|
|
exposedFunctionCounts: (projectRef: string | undefined, selectedSchemas?: string[]) =>
|
|
[
|
|
'projects',
|
|
projectRef,
|
|
'privileges',
|
|
'exposed-function-counts',
|
|
...(selectedSchemas ? ([selectedSchemas] as const) : []),
|
|
] as const,
|
|
defaultPrivileges: (projectRef: string | undefined, schema?: string) =>
|
|
[
|
|
'projects',
|
|
projectRef,
|
|
'privileges',
|
|
'default-privileges',
|
|
...(schema ? [schema] : []),
|
|
] as const,
|
|
}
|