diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d75f8b1bb..b17dfb4806 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ All notable changes to this project will be documented in this file. From versio - Fix unexpected results when embedding and filtering the same table more than once by @laurenceisla in #4075 - Fix connection retrying message in `PGRST000` error by @netqo in #4980 + Remove redundant "Retrying the connection." from message because it is logged separately +- Fix request failures when `work_mem` is set on a role by @laurenceisla in #4955 ### Changed diff --git a/src/PostgREST/Config/Database.hs b/src/PostgREST/Config/Database.hs index 54386016ab..9c97554908 100644 --- a/src/PostgREST/Config/Database.hs +++ b/src/PostgREST/Config/Database.hs @@ -16,6 +16,7 @@ import Control.Arrow ((***)) import PostgREST.Config.PgVersion (PgVersion (..), pgVersion150) import qualified Data.HashMap.Strict as HM +import qualified Data.Text as T import qualified Hasql.Decoders as HD import qualified Hasql.Encoders as HE @@ -32,8 +33,8 @@ type RoleSettings = (HM.HashMap ByteString (HM.HashMap ByteString ByteString type RoleIsolationLvl = HM.HashMap ByteString SQL.IsolationLevel type TimezoneNames = Set Text -- cache timezone names for prefer timezone= -toIsolationLevel :: (Eq a, IsString a) => a -> SQL.IsolationLevel -toIsolationLevel a = case a of +toIsolationLevel :: Text -> SQL.IsolationLevel +toIsolationLevel a = case T.toLower a of "repeatable read" -> SQL.RepeatableRead "serializable" -> SQL.Serializable _ -> SQL.ReadCommitted @@ -148,7 +149,7 @@ queryRoleSettings pgVer = SELECT rolname, substr(setting, 1, strpos(setting, '=') - 1) as key, - lower(substr(setting, strpos(setting, '=') + 1)) as value + substr(setting, strpos(setting, '=') + 1) as value FROM role_setting ), iso_setting AS ( diff --git a/src/PostgREST/SchemaCache.hs b/src/PostgREST/SchemaCache.hs index e026dc1456..a487b70089 100644 --- a/src/PostgREST/SchemaCache.hs +++ b/src/PostgREST/SchemaCache.hs @@ -461,7 +461,7 @@ funcsSqlQuery = encodeUtf8 [trimming| bt.oid <> bt.base_type as rettype_is_composite_alias, p.provolatile, p.provariadic > 0 as hasvariadic, - lower((regexp_split_to_array((regexp_split_to_array(iso_config, '='))[2], ','))[1]) AS transaction_isolation_level, + (regexp_split_to_array((regexp_split_to_array(iso_config, '='))[2], ','))[1] AS transaction_isolation_level, coalesce(func_settings.kvs, '{}') as kvs FROM pg_proc p LEFT JOIN arguments a ON a.oid = p.oid diff --git a/test/io/__snapshots__/test_cli/test_schema_cache_snapshot[dbRoutines].yaml b/test/io/__snapshots__/test_cli/test_schema_cache_snapshot[dbRoutines].yaml index 7063ea43bb..f6b66bba60 100644 --- a/test/io/__snapshots__/test_cli/test_schema_cache_snapshot[dbRoutines].yaml +++ b/test/io/__snapshots__/test_cli/test_schema_cache_snapshot[dbRoutines].yaml @@ -582,6 +582,23 @@ pdSchema: public pdVolatility: Volatile +- - qiName: get_work_mem + qiSchema: public + - - pdDescription: null + pdFuncSettings: [] + pdHasVariadic: false + pdName: get_work_mem + pdParams: [] + pdReturnType: + contents: + contents: + qiName: text + qiSchema: pg_catalog + tag: Scalar + tag: Single + pdSchema: public + pdVolatility: Volatile + - - qiName: notify_do_nothing qiSchema: public - - pdDescription: null diff --git a/test/io/fixtures/roles.sql b/test/io/fixtures/roles.sql index 61070d7a1e..fbe8d8ac9a 100644 --- a/test/io/fixtures/roles.sql +++ b/test/io/fixtures/roles.sql @@ -8,11 +8,12 @@ CREATE ROLE postgrest_test_author; CREATE ROLE postgrest_test_serializable; CREATE ROLE postgrest_test_repeatable_read; CREATE ROLE postgrest_test_w_superuser_settings; +CREATE ROLE postgrest_test_work_mem; GRANT postgrest_test_anonymous, postgrest_test_author, postgrest_test_serializable, postgrest_test_repeatable_read, - postgrest_test_w_superuser_settings TO :"PGUSER"; + postgrest_test_w_superuser_settings, postgrest_test_work_mem TO :"PGUSER"; ALTER ROLE :"PGUSER" SET pgrst.db_anon_role = 'postgrest_test_anonymous'; ALTER ROLE postgrest_test_serializable SET default_transaction_isolation = 'serializable'; @@ -23,3 +24,5 @@ ALTER ROLE postgrest_test_w_superuser_settings SET log_min_messages = 'fatal'; ALTER ROLE postgrest_test_anonymous SET statement_timeout TO '5s'; ALTER ROLE postgrest_test_author SET statement_timeout TO '10s'; + +ALTER ROLE postgrest_test_work_mem SET work_mem TO '3MB'; diff --git a/test/io/fixtures/schema.sql b/test/io/fixtures/schema.sql index 0ca35079e2..85c1d274a2 100644 --- a/test/io/fixtures/schema.sql +++ b/test/io/fixtures/schema.sql @@ -265,3 +265,7 @@ create or replace function custom_vary_hdr() returns void as $$ perform set_config('response.headers', '[{"Vary": "X-Test-Accept"}]', false); end $$ language plpgsql; + +create or replace function get_work_mem() returns text as $$ + select current_setting('work_mem', true); +$$ language sql; diff --git a/test/io/test_io.py b/test/io/test_io.py index 6c20c0d0f6..a9a7da03ec 100644 --- a/test/io/test_io.py +++ b/test/io/test_io.py @@ -2187,3 +2187,19 @@ def test_positive_pool_metric(defaultenv): ).group(1) ) assert metrics >= 0 + + +def test_work_mem_in_role_settings(defaultenv): + "Should work when setting work_mem on a role. See https://github.com/PostgREST/postgrest/issues/4955" + + env = { + **defaultenv, + "PGRST_JWT_SECRET": SECRET, + } + + headers = jwtauthheader({"role": "postgrest_test_work_mem"}, SECRET) + + with run(env=env) as postgrest: + response = postgrest.session.post("/rpc/get_work_mem", headers=headers) + assert response.status_code == 200 + assert response.text == '"3MB"'