From 8c03a625effd7163e006a101fa0fc2dcc9518569 Mon Sep 17 00:00:00 2001 From: Steve Chavez Date: Fri, 10 Nov 2023 13:01:03 -0500 Subject: [PATCH] docs: add postgrest-js explain() (#18833) --- spec/supabase_js_v2.yml | 83 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/spec/supabase_js_v2.yml b/spec/supabase_js_v2.yml index 9c7d222badc..ede65fc60e9 100644 --- a/spec/supabase_js_v2.yml +++ b/spec/supabase_js_v2.yml @@ -4378,6 +4378,89 @@ functions: hideCodeBlock: true isSpotlight: true + - id: using-explain + title: Using Explain + description: | + For debugging slow queries, you can get the [PostgreSQL EXPLAIN execution plan](https://www.postgresql.org/docs/current/sql-explain.html) of a query + using the `explain()` method. This works on any query, even for `rpc()` or writes. + + Explain is not enabled by default as it can reveal sensitive information about your database. + It's best to only enable this for testing environments but if you wish to enable it for production you can provide additional protection by using a `pre-request` function. + + To enable it: + + ```sql + alter role authenticator set pgrst.db_plan_enabled to 'true'; + notify pgrst, 'reload config'; + ``` + + To only allow `explain()` from a fixed IP address you can do the following. Use this if you plan on enabling `explain()` on a production environment. + + ```sql + create or replace function filter_plan_requests() + returns void as $$ + declare + headers json := current_setting('request.headers', true)::json; + client_ip text := coalesce(headers->>'cf-connecting-ip', ''); + accept text := coalesce(headers->>'accept', ''); + your_ip text := '123.123.123.123'; -- replace this by your ip + begin + if accept like 'application/vnd.pgrst.plan%' and client_ip != your_ip then + raise insufficient_privilege using + message = 'Not allowed to use application/vnd.pgrst.plan'; + end if; + end; $$ language plpgsql; + + alter role authenticator set pgrst.db_pre_request to 'filter_plan_requests'; + notify pgrst, 'reload config'; + ``` + + Once you're done using `explain()`, you can disable it with: + + ```sql + alter role authenticator set pgrst.db_plan_enabled to 'false'; + -- if you used the above pre-request + alter role authenticator set pgrst.db_pre_request to ''; + + notify pgrst, 'reload config'; + ``` + - id: explain + $ref: '@supabase/postgrest-js.PostgrestTransformBuilder.explain' + title: explain() + examples: + - id: get-execution-plan + name: Get the execution plan + code: | + ```ts + const { data, error } = await supabase + .from('countries') + .select() + .explain() + ``` + data: + sql: | + ```sql + create table + countries (id int8 primary key, name text); + + insert into + countries (id, name) + values + (1, 'Afghanistan'), + (2, 'Albania'), + (3, 'Algeria'); + ``` + response: | + ``` + Aggregate (cost=33.34..33.36 rows=1 width=112) + -> Limit (cost=0.00..18.33 rows=1000 width=40) + -> Seq Scan on countries (cost=0.00..22.00 rows=1200 width=40) + ``` + description: | + By default, the data is returned in TEXT format, but can also be returned as JSON by using the `format` parameter. + hideCodeBlock: true + isSpotlight: true + # NOTE: Not available on currently deployed PostgREST # db.geojson(): # $ref: '@supabase/postgrest-js.PostgrestTransformBuilder.geojson'