diff --git a/apps/docs/content/guides/database/custom-postgres-config.mdx b/apps/docs/content/guides/database/custom-postgres-config.mdx index d650c5db26352..26e1fc9b6ff39 100644 --- a/apps/docs/content/guides/database/custom-postgres-config.mdx +++ b/apps/docs/content/guides/database/custom-postgres-config.mdx @@ -165,7 +165,32 @@ supabase --experimental \ postgres-config delete --config shared_buffers,work_mem ``` -By default, changing the configuration, whether by updating or deleting, causes the database and all associated read replicas to restart. You can use the `--no-restart` flag to prevent this behavior, and attempt to reload the updated configuration without a restart. Refer to the Postgres documentation to determine if a given parameter can be reloaded without a restart. +By default, CLI v2 (≥ 2.0.0) checks the parameter’s context and requests the correct action (reload or restart): + +- If the setting can be reloaded (`pg_settings.context = 'sighup'`), then the Management API will detect this and apply the change with a configuration reload. +- If the setting requires a restart (`pg_settings.context = 'postmaster'`), then both the primary and any read replicas will restart to apply the change. + +To check whether a parameter can be reloaded without a restart, see the [Postgres docs](https://www.postgresql.org/docs/current/runtime-config.html). + +You can verify whether changes have been applied with the following checks: + +```bash +supabase --version; +``` + +```sql +-- Check whether the parameters were updated (and if a restart is pending): +select name, setting, context, pending_restart +from pg_settings +where name in ('max_slot_wal_keep_size', 'shared_buffers', 'max_connections'); +``` + +```sql +-- If the timestamp hasn’t changed, no restart occurred +select pg_postmaster_start_time(); +``` + +You can also pass the `--no-restart` flag to attempt a reload-only apply. If the parameter cannot be reloaded, the change stays pending until the next restart. diff --git a/apps/docs/content/guides/realtime/authorization.mdx b/apps/docs/content/guides/realtime/authorization.mdx index 3dd1d59b33635..9fb4f3aa8aac9 100644 --- a/apps/docs/content/guides/realtime/authorization.mdx +++ b/apps/docs/content/guides/realtime/authorization.mdx @@ -28,7 +28,7 @@ To enforce private channels you need to disable the 'Allow public access' settin Realtime uses the `messages` table in your database's `realtime` schema to generate access policies for your clients when they connect to a Channel topic. -By creating RLS polices on the `realtime.messages` table you can control the access users have to a Channel topic, and features within a Channel topic. +By creating RLS policies on the `realtime.messages` table you can control the access users have to a Channel topic, and features within a Channel topic. The validation is done when the user connects. When their WebSocket connection is established and a Channel topic is joined, their permissions are calculated based on: @@ -373,9 +373,9 @@ When using Postgres Changes with RLS, database records are sent only to clients ## Updating RLS policies -Client access polices are cached for the duration of the connection. Your database is not queried for every Channel message. +Client access policies are cached for the duration of the connection. Your database is not queried for every Channel message. -Realtime updates the access policy cache for a client based on your RLS polices when: +Realtime updates the access policy cache for a client based on your RLS policies when: - A client connects to Realtime and subscribes to a Channel - A new JWT is sent to Realtime from a client via the [`access_token` message](/docs/guides/realtime/protocol#access-token) diff --git a/apps/studio/components/grid/SupabaseGrid.utils.ts b/apps/studio/components/grid/SupabaseGrid.utils.ts index 92aa3043d0b87..5f6ae0cf5fafc 100644 --- a/apps/studio/components/grid/SupabaseGrid.utils.ts +++ b/apps/studio/components/grid/SupabaseGrid.utils.ts @@ -214,10 +214,14 @@ export function useLoadTableEditorStateFromLocalStorageIntoUrl({ } export const handleCopyCell = ( - { column, row }: { column: CalculatedColumn; row: any }, + { + mode, + column, + row, + }: { mode: 'SELECT' | 'EDIT'; column: CalculatedColumn; row: any }, event: CellKeyboardEvent ) => { - if (event.code === 'KeyC' && (event.metaKey || event.ctrlKey)) { + if (mode === 'SELECT' && event.code === 'KeyC' && (event.metaKey || event.ctrlKey)) { const colKey = column.key const cellValue = row[colKey] ?? '' const value = formatClipboardValue(cellValue) diff --git a/apps/studio/components/grid/components/grid/Grid.tsx b/apps/studio/components/grid/components/grid/Grid.tsx index ffc35913baeea..1818e82ebba15 100644 --- a/apps/studio/components/grid/components/grid/Grid.tsx +++ b/apps/studio/components/grid/components/grid/Grid.tsx @@ -128,9 +128,7 @@ export const Grid = memo( } } - const removeAllFilters = () => { - onApplyFilters([]) - } + const removeAllFilters = () => onApplyFilters([]) return (
{ + const customAttributes = cloudProvider ? { cloud_provider: cloudProvider } : undefined + + return getFlags(userEmail, customAttributes) + }, + [cloudProvider] + ) + return ( diff --git a/packages/common/configcat.ts b/packages/common/configcat.ts index 89046050d734d..410f40addcc97 100644 --- a/packages/common/configcat.ts +++ b/packages/common/configcat.ts @@ -54,11 +54,13 @@ async function getClient() { return client } -export async function getFlags(userEmail: string = '') { +export async function getFlags(userEmail: string = '', customAttributes?: Record) { const client = await getClient() if (userEmail) { - return client.getAllValuesAsync(new configcat.User(userEmail)) + return client.getAllValuesAsync( + new configcat.User(userEmail, undefined, undefined, customAttributes) + ) } else { return client.getAllValuesAsync() }