fix: db-pre-config function failing with pg reserved words

When db-pre-config is accidentally set to a pg reserved word
like "true", it fails with a confusing error. The function
names should be properly quoted to avoid such errors. This commit
resolves this by quoting the pre-config function name.

Signed-off-by: Taimoor Zaeem <taimoorzaeem@gmail.com>
This commit is contained in:
Taimoor Zaeem
2025-10-29 16:54:24 -05:00
committed by Steve Chavez
parent 75d4131aa6
commit a688878236
6 changed files with 58 additions and 2 deletions
+4
View File
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. From versio
## Unreleased ## Unreleased
## Fixed
- Fix `db-pre-config` function failing when function names are pg reserved words by @taimoorzaeem #4380
## [14.0] - 2025-10-24 ## [14.0] - 2025-10-24
### Added ### Added
+2 -2
View File
@@ -69,7 +69,7 @@ import PostgREST.Config.PgVersion (PgVersion (..),
import PostgREST.SchemaCache (SchemaCache (..), import PostgREST.SchemaCache (SchemaCache (..),
querySchemaCache, querySchemaCache,
showSummary) showSummary)
import PostgREST.SchemaCache.Identifiers (dumpQi) import PostgREST.SchemaCache.Identifiers (quoteQi)
import PostgREST.Unix (createAndBindDomainSocket) import PostgREST.Unix (createAndBindDomainSocket)
import Data.Streaming.Network (bindPortTCP, bindRandomPortTCP) import Data.Streaming.Network (bindPortTCP, bindRandomPortTCP)
@@ -441,7 +441,7 @@ readInDbConfig startingUp appState@AppState{stateObserver=observer} = do
pgVer <- getPgVersion appState pgVer <- getPgVersion appState
dbSettings <- dbSettings <-
if configDbConfig conf then do if configDbConfig conf then do
qDbSettings <- usePool appState (queryDbSettings (dumpQi <$> configDbPreConfig conf) (configDbPreparedStatements conf)) qDbSettings <- usePool appState (queryDbSettings (quoteQi <$> configDbPreConfig conf) (configDbPreparedStatements conf))
case qDbSettings of case qDbSettings of
Left e -> do Left e -> do
observer $ ConfigReadErrorObs e observer $ ConfigReadErrorObs e
+5
View File
@@ -10,6 +10,7 @@ module PostgREST.SchemaCache.Identifiers
, dumpQi , dumpQi
, escapeIdent , escapeIdent
, isAnyElement , isAnyElement
, quoteQi
, toQi , toQi
, trimNullChars , trimNullChars
) where ) where
@@ -41,6 +42,10 @@ dumpQi :: QualifiedIdentifier -> Text
dumpQi (QualifiedIdentifier s i) = dumpQi (QualifiedIdentifier s i) =
(if T.null s then mempty else s <> ".") <> i (if T.null s then mempty else s <> ".") <> i
quoteQi :: QualifiedIdentifier -> Text
quoteQi (QualifiedIdentifier s i) =
(if T.null s then mempty else escapeIdent s <> ".") <> escapeIdent i
-- TODO: Handle a case where the QI comes like this: "my.fav.schema"."my.identifier" -- TODO: Handle a case where the QI comes like this: "my.fav.schema"."my.identifier"
-- Right now it only handles the schema.identifier case -- Right now it only handles the schema.identifier case
toQi :: Text -> QualifiedIdentifier toQi :: Text -> QualifiedIdentifier
@@ -461,6 +461,23 @@
pdSchema: public pdSchema: public
pdVolatility: Volatile pdVolatility: Volatile
- - qiName: 'true'
qiSchema: public
- - pdDescription: null
pdFuncSettings: []
pdHasVariadic: false
pdName: 'true'
pdParams: []
pdReturnType:
contents:
contents:
qiName: bool
qiSchema: pg_catalog
tag: Scalar
tag: Single
pdSchema: public
pdVolatility: Volatile
- - qiName: create_function - - qiName: create_function
qiSchema: public qiSchema: public
- - pdDescription: null - - pdDescription: null
+4
View File
@@ -256,3 +256,7 @@ select * from projects;
create or replace view infinite_recursion as create or replace view infinite_recursion as
select * from infinite_recursion; select * from infinite_recursion;
create or replace function "true"() returns boolean as $_$
select true;
$_$ language sql;
+26
View File
@@ -2046,3 +2046,29 @@ def test_log_listener_connection_errors(defaultenv):
in line in line
for line in output for line in output
) )
def test_db_pre_config_with_pg_reserved_words(defaultenv):
"The db-pre-config should not fail unexpectedly when function name is a postgres reserved word"
env = {
**defaultenv,
"PGRST_DB_PRE_CONFIG": "true", # call true function
}
with run(env=env) as postgrest:
response = postgrest.session.post("/rpc/true")
assert response.status_code == 200
env = {
**defaultenv,
"PGRST_DB_PRE_CONFIG": "select", # no "select" function in our fixtures, fail gracefully at startup
}
with run(env=env, no_startup_stdout=False, wait_for_readiness=False) as postgrest:
output = postgrest.read_stdout(nlines=8)
assert any(
'Failed to query database settings for the config parameters.{"code":"42883","details":null,"hint":"No function matches the given name and argument types. You might need to add explicit type casts.","message":"function select() does not exist"}'
in line
for line in output
)