Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f69247cc2 | ||
|
|
e25a87bd84 | ||
|
|
0502488b70 | ||
|
|
a62b6de1d0 | ||
|
|
9baf17aed0 | ||
|
|
d9eabb2742 | ||
|
|
7711a86c0c | ||
|
|
d75a2bdce9 | ||
|
|
dd1956557d |
@@ -2,4 +2,5 @@
|
|||||||
# and made its way to us through nixpkgs.
|
# and made its way to us through nixpkgs.
|
||||||
self-hosted-runner:
|
self-hosted-runner:
|
||||||
labels:
|
labels:
|
||||||
|
- macos-15-intel
|
||||||
- ubuntu-24.04-arm
|
- ubuntu-24.04-arm
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ jobs:
|
|||||||
|
|
||||||
# Backport action that creates the PR with given settings
|
# Backport action that creates the PR with given settings
|
||||||
- name: Create backport PR
|
- name: Create backport PR
|
||||||
uses: korthout/backport-action@3c06f323a58619da1e8522229ebc8d5de2633e46 # v4.3.0
|
uses: korthout/backport-action@7c3f6cd5843cac11bc59a04a1b7699af93261670 # v4.5
|
||||||
with:
|
with:
|
||||||
github_token: ${{ steps.app-token.outputs.token }}
|
github_token: ${{ steps.app-token.outputs.token }}
|
||||||
pull_description: 'Backport for #${pull_number}.'
|
pull_description: 'Backport for #${pull_number}.'
|
||||||
|
|||||||
@@ -105,6 +105,15 @@ jobs:
|
|||||||
artifact: postgrest-macos-aarch64
|
artifact: postgrest-macos-aarch64
|
||||||
deps: brew link --force libpq
|
deps: brew link --force libpq
|
||||||
|
|
||||||
|
- name: MacOS x86-64
|
||||||
|
runs-on: macos-15-intel
|
||||||
|
cache: |
|
||||||
|
~/.stack/pantry
|
||||||
|
~/.stack/snapshots
|
||||||
|
~/.stack/stack.sqlite3
|
||||||
|
artifact: postgrest-macos-x86-64
|
||||||
|
deps: brew link --force libpq
|
||||||
|
|
||||||
- name: Windows
|
- name: Windows
|
||||||
runs-on: windows-2022
|
runs-on: windows-2022
|
||||||
cache: |
|
cache: |
|
||||||
|
|||||||
@@ -81,6 +81,9 @@ jobs:
|
|||||||
tar cJvf "release-bundle/postgrest-${GITHUB_REF_NAME}-macos-aarch64.tar.xz" \
|
tar cJvf "release-bundle/postgrest-${GITHUB_REF_NAME}-macos-aarch64.tar.xz" \
|
||||||
-C artifacts/postgrest-macos-aarch64 postgrest
|
-C artifacts/postgrest-macos-aarch64 postgrest
|
||||||
|
|
||||||
|
tar cJvf "release-bundle/postgrest-${GITHUB_REF_NAME}-macos-x86-64.tar.xz" \
|
||||||
|
-C artifacts/postgrest-macos-x86-64 postgrest
|
||||||
|
|
||||||
tar cJvf "release-bundle/postgrest-${GITHUB_REF_NAME}-freebsd-x86-64.tar.xz" \
|
tar cJvf "release-bundle/postgrest-${GITHUB_REF_NAME}-freebsd-x86-64.tar.xz" \
|
||||||
-C artifacts/postgrest-freebsd-x86-64 postgrest
|
-C artifacts/postgrest-freebsd-x86-64 postgrest
|
||||||
|
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
runs-on:
|
runs-on:
|
||||||
|
- macos-15-intel # x86_64-darwin
|
||||||
- macos-14 # aarch64-darwin
|
- macos-14 # aarch64-darwin
|
||||||
- ubuntu-24.04 # x86_64-linux
|
- ubuntu-24.04 # x86_64-linux
|
||||||
- ubuntu-24.04-arm # aarch64-linux
|
- ubuntu-24.04-arm # aarch64-linux
|
||||||
|
|||||||
@@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file. From versio
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
## [14.11] - 2026-05-04
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix login with uppercase and mixed case role names by @taimoorzaeem in #4678
|
||||||
|
- Restore Listener query shape so it can be found in `pg_stat_activity` by @mkleczek in #4857 #4859
|
||||||
|
- The LISTEN channel now automatically recovers when it stops working due to a PostgreSQL bug @laurenceisla in #3147
|
||||||
|
- Fix misleading "Functions" name on schema cache summary in startup logs by @taimoorzaeem in #4821
|
||||||
|
|
||||||
## [14.10] - 2026-04-16
|
## [14.10] - 2026-04-16
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
# The x86-64 is a single-static-binary image built via Nix, see:
|
# The x86-64 is a single-static-binary image built via Nix, see:
|
||||||
# nix/tools/docker/README.md
|
# nix/tools/docker/README.md
|
||||||
|
|
||||||
FROM ubuntu:noble@sha256:c4a8d5503dfb2a3eb8ab5f807da5bc69a85730fb49b5cfca2330194ebcc41c7b AS postgrest
|
FROM ubuntu:resolute@sha256:5e275723f82c67e387ba9e3c24baa0abdcb268917f276a0561c97bef9450d0b4 AS postgrest
|
||||||
|
|
||||||
RUN apt-get update -y \
|
RUN apt-get update -y \
|
||||||
&& apt install -y --no-install-recommends libpq-dev zlib1g-dev jq gcc libnuma-dev \
|
&& apt install -y --no-install-recommends libpq-dev zlib1g-dev jq gcc libnuma-dev \
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ For diagnostic information about the server itself, PostgREST logs to ``stderr``
|
|||||||
06/May/2024:08:16:11 -0500: Listening for database notifications on the "pgrst" channel
|
06/May/2024:08:16:11 -0500: Listening for database notifications on the "pgrst" channel
|
||||||
06/May/2024:08:16:11 -0500: Config reloaded
|
06/May/2024:08:16:11 -0500: Config reloaded
|
||||||
06/May/2024:08:16:11 -0500: Schema cache queried in 3.8 milliseconds
|
06/May/2024:08:16:11 -0500: Schema cache queried in 3.8 milliseconds
|
||||||
06/May/2024:08:16:11 -0500: Schema cache loaded 15 Relations, 8 Relationships, 8 Functions, 0 Domain Representations, 4 Media Type Handlers
|
06/May/2024:08:16:11 -0500: Schema cache loaded 15 Relations, 8 Relationships, 8 RPCs, 0 Domain Representations, 4 Media Type Handlers
|
||||||
06/May/2024:14:11:27 -0500: Received a config reload message on the "pgrst" channel
|
06/May/2024:14:11:27 -0500: Received a config reload message on the "pgrst" channel
|
||||||
06/May/2024:14:11:27 -0500: Config reloaded
|
06/May/2024:14:11:27 -0500: Config reloaded
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ let
|
|||||||
"ARG_OPTIONAL_SINGLE([fixtures], [f], [SQL file to load fixtures from])"
|
"ARG_OPTIONAL_SINGLE([fixtures], [f], [SQL file to load fixtures from])"
|
||||||
"ARG_POSITIONAL_SINGLE([command], [Command to run])"
|
"ARG_POSITIONAL_SINGLE([command], [Command to run])"
|
||||||
"ARG_LEFTOVERS([command arguments])"
|
"ARG_LEFTOVERS([command arguments])"
|
||||||
"ARG_USE_ENV([PGUSER], [postgrest_test_authenticator], [Authenticator PG role])"
|
"ARG_USE_ENV([PGUSER], [Postgrest_Test_Authenticator], [Authenticator PG role])" # user is written in mixed case to implicitly test that it is being properly quoted in schema cache queries
|
||||||
"ARG_USE_ENV([PGDATABASE], [postgres], [PG database name])"
|
"ARG_USE_ENV([PGDATABASE], [postgres], [PG database name])"
|
||||||
"ARG_USE_ENV([PGRST_DB_SCHEMAS], [test], [Schema to expose])"
|
"ARG_USE_ENV([PGRST_DB_SCHEMAS], [test], [Schema to expose])"
|
||||||
"ARG_USE_ENV([PGTZ], [utc], [Timezone to use])"
|
"ARG_USE_ENV([PGTZ], [utc], [Timezone to use])"
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
name: postgrest
|
name: postgrest
|
||||||
version: 14.10
|
version: 14.11
|
||||||
synopsis: REST API for any Postgres database
|
synopsis: REST API for any Postgres database
|
||||||
description: Reads the schema of a PostgreSQL database and creates RESTful routes
|
description: Reads the schema of a PostgreSQL database and creates RESTful routes
|
||||||
for tables, views, and functions, supporting all HTTP methods that security
|
for tables, views, and functions, supporting all HTTP methods that security
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ queryDbSettings preConfFunc prepared =
|
|||||||
SELECT setdatabase as database,
|
SELECT setdatabase as database,
|
||||||
unnest(setconfig) as setting
|
unnest(setconfig) as setting
|
||||||
FROM pg_catalog.pg_db_role_setting
|
FROM pg_catalog.pg_db_role_setting
|
||||||
WHERE setrole = CURRENT_USER::regrole::oid
|
WHERE setrole = quote_ident(CURRENT_USER)::regrole::oid
|
||||||
AND setdatabase IN (0, (SELECT oid FROM pg_catalog.pg_database WHERE datname = CURRENT_CATALOG))
|
AND setdatabase IN (0, (SELECT oid FROM pg_catalog.pg_database WHERE datname = CURRENT_CATALOG))
|
||||||
),
|
),
|
||||||
kv_settings AS (
|
kv_settings AS (
|
||||||
@@ -142,7 +142,7 @@ queryRoleSettings pgVer prepared =
|
|||||||
select r.rolname, unnest(r.rolconfig) as setting
|
select r.rolname, unnest(r.rolconfig) as setting
|
||||||
from pg_auth_members m
|
from pg_auth_members m
|
||||||
join pg_roles r on r.oid = m.roleid
|
join pg_roles r on r.oid = m.roleid
|
||||||
where member = current_user::regrole::oid
|
where member = quote_ident(current_user)::regrole::oid
|
||||||
),
|
),
|
||||||
kv_settings AS (
|
kv_settings AS (
|
||||||
SELECT
|
SELECT
|
||||||
@@ -167,7 +167,7 @@ queryRoleSettings pgVer prepared =
|
|||||||
|]
|
|]
|
||||||
|
|
||||||
hasParameterPrivilege
|
hasParameterPrivilege
|
||||||
| pgVer >= pgVersion150 = "or has_parameter_privilege(current_user::regrole::oid, ps.name, 'set')"
|
| pgVer >= pgVersion150 = "or has_parameter_privilege(quote_ident(current_user)::regrole::oid, ps.name, 'set')"
|
||||||
| otherwise = ""
|
| otherwise = ""
|
||||||
|
|
||||||
processRows :: [(Text, Maybe Text, [(Text, Text)])] -> (RoleSettings, RoleIsolationLvl)
|
processRows :: [(Text, Maybe Text, [(Text, Text)])] -> (RoleSettings, RoleIsolationLvl)
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ import qualified Hasql.Connection as SQL
|
|||||||
import qualified Hasql.Notifications as SQL
|
import qualified Hasql.Notifications as SQL
|
||||||
import PostgREST.AppState (AppState, getConfig)
|
import PostgREST.AppState (AppState, getConfig)
|
||||||
import PostgREST.Config (AppConfig (..))
|
import PostgREST.Config (AppConfig (..))
|
||||||
import PostgREST.Observation (Observation (..),
|
import PostgREST.Observation (Observation (..))
|
||||||
isDbListenerBug)
|
|
||||||
import PostgREST.Version (prettyVersion)
|
import PostgREST.Version (prettyVersion)
|
||||||
|
|
||||||
import qualified PostgREST.AppState as AppState
|
import qualified PostgREST.AppState as AppState
|
||||||
@@ -20,6 +19,7 @@ import qualified PostgREST.Config as Config
|
|||||||
import Control.Arrow ((&&&))
|
import Control.Arrow ((&&&))
|
||||||
import Data.Bitraversable (bisequence)
|
import Data.Bitraversable (bisequence)
|
||||||
import Data.Either.Combinators (whenRight)
|
import Data.Either.Combinators (whenRight)
|
||||||
|
import qualified Data.Text as T
|
||||||
import qualified Database.PostgreSQL.LibPQ as LibPQ
|
import qualified Database.PostgreSQL.LibPQ as LibPQ
|
||||||
import qualified Hasql.Session as SQL
|
import qualified Hasql.Session as SQL
|
||||||
import PostgREST.Config.Database (queryPgVersion)
|
import PostgREST.Config.Database (queryPgVersion)
|
||||||
@@ -31,12 +31,12 @@ runListener :: AppState -> IO ()
|
|||||||
runListener appState = do
|
runListener appState = do
|
||||||
AppConfig{..} <- getConfig appState
|
AppConfig{..} <- getConfig appState
|
||||||
when configDbChannelEnabled $
|
when configDbChannelEnabled $
|
||||||
void . forkIO . void $ retryingListen appState
|
void . forkIO . void $ retryingListen appState False
|
||||||
|
|
||||||
-- | Starts a LISTEN connection and handles notifications. It recovers with exponential backoff with a cap of 32 seconds, if the LISTEN connection is lost.
|
-- | Starts a LISTEN connection and handles notifications. It recovers with exponential backoff with a cap of 32 seconds, if the LISTEN connection is lost.
|
||||||
-- | This function never returns (but can throw) and return type enforces that.
|
-- | This function never returns (but can throw) and return type enforces that.
|
||||||
retryingListen :: AppState -> IO Void
|
retryingListen :: AppState -> Bool -> IO Void
|
||||||
retryingListen appState = do
|
retryingListen appState hasDbListenerBug = do
|
||||||
AppConfig{..} <- AppState.getConfig appState
|
AppConfig{..} <- AppState.getConfig appState
|
||||||
let
|
let
|
||||||
dbChannel = toS configDbChannel
|
dbChannel = toS configDbChannel
|
||||||
@@ -44,7 +44,7 @@ retryingListen appState = do
|
|||||||
AppState.putIsListenerOn appState False
|
AppState.putIsListenerOn appState False
|
||||||
observer $ DBListenFail dbChannel (Right err)
|
observer $ DBListenFail dbChannel (Right err)
|
||||||
when (isDbListenerBug err) $
|
when (isDbListenerBug err) $
|
||||||
observer DBListenBugHint
|
observer DBListenBugCallQueryFix
|
||||||
unless configDbPoolAutomaticRecovery $
|
unless configDbPoolAutomaticRecovery $
|
||||||
killThread mainThreadId
|
killThread mainThreadId
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ retryingListen appState = do
|
|||||||
unless (delay == maxDelay) $
|
unless (delay == maxDelay) $
|
||||||
AppState.putNextListenerDelay appState (delay * 2)
|
AppState.putNextListenerDelay appState (delay * 2)
|
||||||
-- loop running the listener
|
-- loop running the listener
|
||||||
retryingListen appState
|
retryingListen appState (isDbListenerBug err)
|
||||||
|
|
||||||
-- Execute the listener with with error handling
|
-- Execute the listener with with error handling
|
||||||
handle onError $ do
|
handle onError $ do
|
||||||
@@ -68,9 +68,10 @@ retryingListen appState = do
|
|||||||
-- use connection
|
-- use connection
|
||||||
\case
|
\case
|
||||||
Right db -> do
|
Right db -> do
|
||||||
SQL.listen db $ SQL.toPgIdentifier dbChannel
|
|
||||||
(pqHost, pqPort) <- SQL.withLibPQConnection db $ bisequence . (LibPQ.host &&& LibPQ.port)
|
(pqHost, pqPort) <- SQL.withLibPQConnection db $ bisequence . (LibPQ.host &&& LibPQ.port)
|
||||||
pgFullName <- SQL.run (queryPgVersion False) db >>= either throwIO (pure . pgvFullName)
|
pgFullName <- SQL.run (queryPgVersion False) db >>= either throwIO (pure . pgvFullName)
|
||||||
|
when hasDbListenerBug $ SQL.run callNotifQueryUsage db >>= either throwIO pure
|
||||||
|
SQL.listen db $ SQL.toPgIdentifier dbChannel
|
||||||
|
|
||||||
AppState.putIsListenerOn appState True
|
AppState.putIsListenerOn appState True
|
||||||
|
|
||||||
@@ -106,3 +107,10 @@ retryingListen appState = do
|
|||||||
AppState.schemaCacheLoader appState
|
AppState.schemaCacheLoader appState
|
||||||
|
|
||||||
releaseConnection = void . forkIO . handle (observer . DBListenerConnectionCleanupFail) . SQL.release
|
releaseConnection = void . forkIO . handle (observer . DBListenerConnectionCleanupFail) . SQL.release
|
||||||
|
|
||||||
|
isDbListenerBug e = "could not access status of transaction" `T.isInfixOf` show e
|
||||||
|
|
||||||
|
-- Used to fix a Postgres bug in the listener, see: https://github.com/PostgREST/postgrest/issues/3147#issuecomment-3494591361
|
||||||
|
-- This query advances the async notification query tail, which solves this issue.
|
||||||
|
callNotifQueryUsage :: SQL.Session ()
|
||||||
|
callNotifQueryUsage = SQL.sql "SELECT pg_notification_queue_usage();"
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ module PostgREST.Observation
|
|||||||
, observationMessage
|
, observationMessage
|
||||||
, ObservationHandler
|
, ObservationHandler
|
||||||
, showOnSingleLine
|
, showOnSingleLine
|
||||||
, isDbListenerBug
|
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import qualified Data.ByteString.Lazy as LBS
|
import qualified Data.ByteString.Lazy as LBS
|
||||||
@@ -48,7 +47,7 @@ data Observation
|
|||||||
| DBListenStart (Maybe ByteString) (Maybe ByteString) Text Text -- host, port, version string, channel
|
| DBListenStart (Maybe ByteString) (Maybe ByteString) Text Text -- host, port, version string, channel
|
||||||
| DBListenFail Text (Either SQL.ConnectionError SomeException)
|
| DBListenFail Text (Either SQL.ConnectionError SomeException)
|
||||||
| DBListenRetry Int
|
| DBListenRetry Int
|
||||||
| DBListenBugHint -- https://github.com/PostgREST/postgrest/issues/3147
|
| DBListenBugCallQueryFix
|
||||||
| DBListenerGotSCacheMsg ByteString
|
| DBListenerGotSCacheMsg ByteString
|
||||||
| DBListenerGotConfigMsg ByteString
|
| DBListenerGotConfigMsg ByteString
|
||||||
| DBListenerConnectionCleanupFail SomeException
|
| DBListenerConnectionCleanupFail SomeException
|
||||||
@@ -122,8 +121,8 @@ observationMessage = \case
|
|||||||
either showListenerConnError showListenerException listenErr
|
either showListenerConnError showListenerException listenErr
|
||||||
DBListenRetry delay ->
|
DBListenRetry delay ->
|
||||||
"Retrying listening for database notifications in " <> (show delay::Text) <> " seconds..."
|
"Retrying listening for database notifications in " <> (show delay::Text) <> " seconds..."
|
||||||
DBListenBugHint ->
|
DBListenBugCallQueryFix ->
|
||||||
"HINT: This is likely a bug in the notification queue, try executing the following to solve it: select pg_notification_queue_usage();"
|
"This is likely a PostgreSQL bug in the notification queue, executing the following to try to solve it: SELECT pg_notification_queue_usage();"
|
||||||
DBListenerGotSCacheMsg channel ->
|
DBListenerGotSCacheMsg channel ->
|
||||||
"Received a schema cache reload message on the " <> show channel <> " channel"
|
"Received a schema cache reload message on the " <> show channel <> " channel"
|
||||||
DBListenerGotConfigMsg channel ->
|
DBListenerGotConfigMsg channel ->
|
||||||
@@ -188,6 +187,3 @@ observationMessage = \case
|
|||||||
|
|
||||||
showOnSingleLine :: Char -> Text -> Text
|
showOnSingleLine :: Char -> Text -> Text
|
||||||
showOnSingleLine split txt = T.intercalate " " $ T.filter (/= split) <$> T.lines txt -- the errors from hasql-notifications come intercalated with "\t\n"
|
showOnSingleLine split txt = T.intercalate " " $ T.filter (/= split) <$> T.lines txt -- the errors from hasql-notifications come intercalated with "\t\n"
|
||||||
|
|
||||||
isDbListenerBug :: SomeException -> Bool
|
|
||||||
isDbListenerBug e = "could not access status of transaction" `T.isInfixOf` show e
|
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ showSummary (SchemaCache tbls rels routs reps mediaHdlrs tzs _) =
|
|||||||
T.intercalate ", "
|
T.intercalate ", "
|
||||||
[ show (HM.size tbls) <> " Relations"
|
[ show (HM.size tbls) <> " Relations"
|
||||||
, show (HM.size rels) <> " Relationships"
|
, show (HM.size rels) <> " Relationships"
|
||||||
, show (HM.size routs) <> " Functions"
|
, show (HM.size routs) <> " RPCs"
|
||||||
, show (HM.size reps) <> " Domain Representations"
|
, show (HM.size reps) <> " Domain Representations"
|
||||||
, show (HM.size mediaHdlrs) <> " Media Type Handlers"
|
, show (HM.size mediaHdlrs) <> " Media Type Handlers"
|
||||||
, show (S.size tzs) <> " Timezones"
|
, show (S.size tzs) <> " Timezones"
|
||||||
|
|||||||
@@ -11399,7 +11399,7 @@ $$;
|
|||||||
DROP ROLE IF EXISTS postgrest_test_anonymous;
|
DROP ROLE IF EXISTS postgrest_test_anonymous;
|
||||||
CREATE ROLE postgrest_test_anonymous;
|
CREATE ROLE postgrest_test_anonymous;
|
||||||
|
|
||||||
GRANT postgrest_test_anonymous TO :PGUSER;
|
GRANT postgrest_test_anonymous TO :"PGUSER";
|
||||||
|
|
||||||
GRANT USAGE ON SCHEMA apflora TO postgrest_test_anonymous;
|
GRANT USAGE ON SCHEMA apflora TO postgrest_test_anonymous;
|
||||||
GRANT USAGE ON SCHEMA fuzzysearch TO postgrest_test_anonymous;
|
GRANT USAGE ON SCHEMA fuzzysearch TO postgrest_test_anonymous;
|
||||||
|
|||||||
+11
-11
@@ -4,7 +4,7 @@ set check_function_bodies = false; -- to allow conditionals based on the pg vers
|
|||||||
set search_path to public;
|
set search_path to public;
|
||||||
|
|
||||||
CREATE ROLE postgrest_test_anonymous;
|
CREATE ROLE postgrest_test_anonymous;
|
||||||
ALTER ROLE :PGUSER SET pgrst.db_anon_role = 'postgrest_test_anonymous';
|
ALTER ROLE :"PGUSER" SET pgrst.db_anon_role = 'postgrest_test_anonymous';
|
||||||
|
|
||||||
CREATE ROLE postgrest_test_author;
|
CREATE ROLE postgrest_test_author;
|
||||||
|
|
||||||
@@ -21,14 +21,14 @@ alter role postgrest_test_w_superuser_settings set log_min_messages = 'fatal';
|
|||||||
DO $do$BEGIN
|
DO $do$BEGIN
|
||||||
IF (SELECT current_setting('server_version_num')::INT >= 150000) THEN
|
IF (SELECT current_setting('server_version_num')::INT >= 150000) THEN
|
||||||
ALTER ROLE postgrest_test_w_superuser_settings SET log_min_duration_sample = 12345;
|
ALTER ROLE postgrest_test_w_superuser_settings SET log_min_duration_sample = 12345;
|
||||||
GRANT SET ON PARAMETER log_min_duration_sample to postgrest_test_authenticator;
|
GRANT SET ON PARAMETER log_min_duration_sample to "Postgrest_Test_Authenticator";
|
||||||
END IF;
|
END IF;
|
||||||
END$do$;
|
END$do$;
|
||||||
|
|
||||||
GRANT
|
GRANT
|
||||||
postgrest_test_anonymous, postgrest_test_author,
|
postgrest_test_anonymous, postgrest_test_author,
|
||||||
postgrest_test_serializable, postgrest_test_repeatable_read,
|
postgrest_test_serializable, postgrest_test_repeatable_read,
|
||||||
postgrest_test_w_superuser_settings TO :PGUSER;
|
postgrest_test_w_superuser_settings TO :"PGUSER";
|
||||||
|
|
||||||
CREATE SCHEMA v1;
|
CREATE SCHEMA v1;
|
||||||
GRANT USAGE ON SCHEMA v1 TO postgrest_test_anonymous;
|
GRANT USAGE ON SCHEMA v1 TO postgrest_test_anonymous;
|
||||||
@@ -57,7 +57,7 @@ $$ language sql;
|
|||||||
create function change_max_rows_config(val int, notify bool default false) returns void as $_$
|
create function change_max_rows_config(val int, notify bool default false) returns void as $_$
|
||||||
begin
|
begin
|
||||||
execute format($$
|
execute format($$
|
||||||
alter role postgrest_test_authenticator set pgrst.db_max_rows = %L;
|
alter role "Postgrest_Test_Authenticator" set pgrst.db_max_rows = %L;
|
||||||
$$, val);
|
$$, val);
|
||||||
if notify then
|
if notify then
|
||||||
perform pg_notify('pgrst', 'reload config');
|
perform pg_notify('pgrst', 'reload config');
|
||||||
@@ -66,13 +66,13 @@ end $_$ volatile security definer language plpgsql ;
|
|||||||
|
|
||||||
create function reset_max_rows_config() returns void as $_$
|
create function reset_max_rows_config() returns void as $_$
|
||||||
begin
|
begin
|
||||||
alter role postgrest_test_authenticator reset pgrst.db_max_rows;
|
alter role "Postgrest_Test_Authenticator" reset pgrst.db_max_rows;
|
||||||
end $_$ volatile security definer language plpgsql ;
|
end $_$ volatile security definer language plpgsql ;
|
||||||
|
|
||||||
create function change_db_schema_and_full_reload(schemas text) returns void as $_$
|
create function change_db_schema_and_full_reload(schemas text) returns void as $_$
|
||||||
begin
|
begin
|
||||||
execute format($$
|
execute format($$
|
||||||
alter role postgrest_test_authenticator set pgrst.db_schemas = %L;
|
alter role "Postgrest_Test_Authenticator" set pgrst.db_schemas = %L;
|
||||||
$$, schemas);
|
$$, schemas);
|
||||||
perform pg_notify('pgrst', 'reload config');
|
perform pg_notify('pgrst', 'reload config');
|
||||||
perform pg_notify('pgrst', 'reload schema');
|
perform pg_notify('pgrst', 'reload schema');
|
||||||
@@ -80,14 +80,14 @@ end $_$ volatile security definer language plpgsql ;
|
|||||||
|
|
||||||
create function v1.reset_db_schema_config() returns void as $_$
|
create function v1.reset_db_schema_config() returns void as $_$
|
||||||
begin
|
begin
|
||||||
alter role postgrest_test_authenticator reset pgrst.db_schemas;
|
alter role "Postgrest_Test_Authenticator" reset pgrst.db_schemas;
|
||||||
perform pg_notify('pgrst', 'reload config');
|
perform pg_notify('pgrst', 'reload config');
|
||||||
perform pg_notify('pgrst', 'reload schema');
|
perform pg_notify('pgrst', 'reload schema');
|
||||||
end $_$ volatile security definer language plpgsql ;
|
end $_$ volatile security definer language plpgsql ;
|
||||||
|
|
||||||
create function invalid_role_claim_key_reload() returns void as $_$
|
create function invalid_role_claim_key_reload() returns void as $_$
|
||||||
begin
|
begin
|
||||||
alter role postgrest_test_authenticator set pgrst.jwt_role_claim_key = 'test';
|
alter role "Postgrest_Test_Authenticator" set pgrst.jwt_role_claim_key = 'test';
|
||||||
perform pg_notify('pgrst', 'reload config');
|
perform pg_notify('pgrst', 'reload config');
|
||||||
end $_$ volatile security definer language plpgsql ;
|
end $_$ volatile security definer language plpgsql ;
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ $_$ language sql;
|
|||||||
|
|
||||||
create function reset_invalid_role_claim_key() returns void as $_$
|
create function reset_invalid_role_claim_key() returns void as $_$
|
||||||
begin
|
begin
|
||||||
alter role postgrest_test_authenticator reset pgrst.jwt_role_claim_key;
|
alter role "Postgrest_Test_Authenticator" reset pgrst.jwt_role_claim_key;
|
||||||
perform pg_notify('pgrst', 'reload config');
|
perform pg_notify('pgrst', 'reload config');
|
||||||
end $_$ volatile security definer language plpgsql ;
|
end $_$ volatile security definer language plpgsql ;
|
||||||
|
|
||||||
@@ -235,12 +235,12 @@ $$ language sql;
|
|||||||
|
|
||||||
create function change_db_schemas_config() returns void as $_$
|
create function change_db_schemas_config() returns void as $_$
|
||||||
begin
|
begin
|
||||||
alter role postgrest_test_authenticator set pgrst.db_schemas = 'test';
|
alter role "Postgrest_Test_Authenticator" set pgrst.db_schemas = 'test';
|
||||||
end $_$ volatile security definer language plpgsql;
|
end $_$ volatile security definer language plpgsql;
|
||||||
|
|
||||||
create function reset_db_schemas_config() returns void as $_$
|
create function reset_db_schemas_config() returns void as $_$
|
||||||
begin
|
begin
|
||||||
alter role postgrest_test_authenticator reset pgrst.db_schemas;
|
alter role "Postgrest_Test_Authenticator" reset pgrst.db_schemas;
|
||||||
end $_$ volatile security definer language plpgsql ;
|
end $_$ volatile security definer language plpgsql ;
|
||||||
|
|
||||||
create function test.get_current_schema() returns text as $$
|
create function test.get_current_schema() returns text as $$
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ create table replica.items as select x as id from generate_series(1, 10) x;
|
|||||||
DROP ROLE IF EXISTS postgrest_test_anonymous;
|
DROP ROLE IF EXISTS postgrest_test_anonymous;
|
||||||
CREATE ROLE postgrest_test_anonymous;
|
CREATE ROLE postgrest_test_anonymous;
|
||||||
|
|
||||||
GRANT postgrest_test_anonymous TO :PGUSER;
|
GRANT postgrest_test_anonymous TO :"PGUSER";
|
||||||
|
|
||||||
GRANT USAGE ON SCHEMA replica TO postgrest_test_anonymous;
|
GRANT USAGE ON SCHEMA replica TO postgrest_test_anonymous;
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import signal
|
import signal
|
||||||
|
import subprocess
|
||||||
import time
|
import time
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -542,6 +543,39 @@ def test_admin_ready_w_channel(defaultenv):
|
|||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
def test_listener_query_is_visible_in_pg_stat_activity(defaultenv):
|
||||||
|
"The listener connection should show the LISTEN pgrst statement in pg_stat_activity"
|
||||||
|
|
||||||
|
env = {
|
||||||
|
**defaultenv,
|
||||||
|
"PGRST_DB_CHANNEL_ENABLED": "true",
|
||||||
|
"PGAPPNAME": "listener-query-test",
|
||||||
|
}
|
||||||
|
|
||||||
|
with run(env=env):
|
||||||
|
query = """
|
||||||
|
select query
|
||||||
|
from pg_stat_activity
|
||||||
|
where application_name = 'listener-query-test'
|
||||||
|
and query = 'LISTEN "pgrst"'
|
||||||
|
limit 1;
|
||||||
|
"""
|
||||||
|
output = subprocess.check_output(
|
||||||
|
[
|
||||||
|
"psql",
|
||||||
|
"--set",
|
||||||
|
"ON_ERROR_STOP=1",
|
||||||
|
"--tuples-only",
|
||||||
|
"--no-align",
|
||||||
|
"-c",
|
||||||
|
query,
|
||||||
|
],
|
||||||
|
text=True,
|
||||||
|
).strip()
|
||||||
|
|
||||||
|
assert output == 'LISTEN "pgrst"'
|
||||||
|
|
||||||
|
|
||||||
def test_admin_ready_wo_channel(defaultenv):
|
def test_admin_ready_wo_channel(defaultenv):
|
||||||
"Should get a success response from the admin server ready endpoint when the LISTEN channel is disabled"
|
"Should get a success response from the admin server ready endpoint when the LISTEN channel is disabled"
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
CREATE ROLE postgrest_test_anonymous;
|
CREATE ROLE postgrest_test_anonymous;
|
||||||
CREATE ROLE postgrest_test_author;
|
CREATE ROLE postgrest_test_author;
|
||||||
GRANT postgrest_test_anonymous TO :PGUSER;
|
GRANT postgrest_test_anonymous TO :"PGUSER";
|
||||||
GRANT postgrest_test_author TO :PGUSER;
|
GRANT postgrest_test_author TO :"PGUSER";
|
||||||
CREATE SCHEMA test;
|
CREATE SCHEMA test;
|
||||||
|
|
||||||
-- PUT+PATCH target needs one record and column to modify
|
-- PUT+PATCH target needs one record and column to modify
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ DROP ROLE IF EXISTS postgrest_test_anonymous, postgrest_test_author;
|
|||||||
CREATE ROLE postgrest_test_anonymous;
|
CREATE ROLE postgrest_test_anonymous;
|
||||||
CREATE ROLE postgrest_test_author;
|
CREATE ROLE postgrest_test_author;
|
||||||
|
|
||||||
GRANT postgrest_test_anonymous, postgrest_test_author TO :PGUSER;
|
GRANT postgrest_test_anonymous, postgrest_test_author TO :"PGUSER";
|
||||||
|
|||||||
Vendored
+1
-1
@@ -4,4 +4,4 @@ CREATE ROLE postgrest_test_default_role;
|
|||||||
CREATE ROLE postgrest_test_author;
|
CREATE ROLE postgrest_test_author;
|
||||||
CREATE ROLE postgrest_test_superuser WITH SUPERUSER;
|
CREATE ROLE postgrest_test_superuser WITH SUPERUSER;
|
||||||
|
|
||||||
GRANT postgrest_test_anonymous, postgrest_test_default_role, postgrest_test_author, postgrest_test_superuser TO :PGUSER;
|
GRANT postgrest_test_anonymous, postgrest_test_default_role, postgrest_test_author, postgrest_test_superuser TO :"PGUSER";
|
||||||
|
|||||||
Reference in New Issue
Block a user