add: config to emit warning for legacy target names

Adds the `url_use_legacy_target_names` config.

Enabled (default):
* It allows using the resource name in filters,
  orders or limits when it has an alias, e.g.
  `table?select=alias:target(*)&target.id=eq.1`
* Logs a WARNING with a hint to use the alias
* Returns a Warning header in the response

Disabled:
* It returns an error, only the alias is allowed
* No warnings returned

This feature is deprecated
This commit is contained in:
steve-chavez
2026-07-11 02:15:07 +00:00
committed by Laurence Isla
parent 2fa8de4e52
commit 490d1dc5d3
33 changed files with 385 additions and 69 deletions
@@ -1,7 +1,59 @@
- - - qiName: awards
qiSchema: public
- public
- - relCardinality:
relColumns:
- - director_id
- id
relCons: awards_director_id_fkey
tag: M2O
relFTableIsView: false
relForeignTable:
qiName: directors
qiSchema: public
relIsSelf: false
relTable:
qiName: awards
qiSchema: public
relTableIsView: false
tag: Relationship
- relCardinality:
relColumns:
- - film_id
- id
relCons: awards_film_id_fkey
tag: M2O
relFTableIsView: false
relForeignTable:
qiName: films
qiSchema: public
relIsSelf: false
relTable:
qiName: awards
qiSchema: public
relTableIsView: false
tag: Relationship
- - - qiName: directors
qiSchema: public
- public
- - relCardinality:
relColumns:
- - id
- director_id
relCons: awards_director_id_fkey
tag: O2M
relFTableIsView: false
relForeignTable:
qiName: awards
qiSchema: public
relIsSelf: false
relTable:
qiName: directors
qiSchema: public
relTableIsView: false
tag: Relationship
- relCardinality:
relColumns:
- - id
- director_id
@@ -22,6 +74,22 @@
qiSchema: public
- public
- - relCardinality:
relColumns:
- - id
- film_id
relCons: awards_film_id_fkey
tag: O2M
relFTableIsView: false
relForeignTable:
qiName: awards
qiSchema: public
relIsSelf: false
relTable:
qiName: films
qiSchema: public
relTableIsView: false
tag: Relationship
- relCardinality:
relColumns:
- - director_id
- id
@@ -126,6 +126,64 @@
tableSchema: public
tableUpdatable: false
- - qiName: awards
qiSchema: public
- tableColumns:
director_id:
colDefault: null
colDescription: null
colEnum: []
colMaxLen: null
colName: director_id
colNominalType: integer
colNullable: true
colType: integer
film_id:
colDefault: null
colDescription: null
colEnum: []
colMaxLen: null
colName: film_id
colNominalType: integer
colNullable: true
colType: integer
id:
colDefault: null
colDescription: null
colEnum: []
colMaxLen: null
colName: id
colNominalType: integer
colNullable: false
colType: integer
name:
colDefault: null
colDescription: null
colEnum: []
colMaxLen: null
colName: name
colNominalType: text
colNullable: true
colType: text
year:
colDefault: null
colDescription: null
colEnum: []
colMaxLen: null
colName: year
colNominalType: integer
colNullable: true
colType: integer
tableDeletable: true
tableDescription: null
tableInsertable: true
tableIsView: false
tableName: awards
tablePKCols:
- id
tableSchema: public
tableUpdatable: true
- - qiName: films
qiSchema: public
- tableColumns:
+1
View File
@@ -42,3 +42,4 @@ server-timing-enabled = false
server-trace-header = ""
server-unix-socket = ""
server-unix-socket-mode = "660"
url-use-legacy-target-names = true
@@ -42,3 +42,4 @@ server-timing-enabled = false
server-trace-header = ""
server-unix-socket = ""
server-unix-socket-mode = "660"
url-use-legacy-target-names = true
@@ -42,3 +42,4 @@ server-timing-enabled = false
server-trace-header = ""
server-unix-socket = ""
server-unix-socket-mode = "660"
url-use-legacy-target-names = true
+1
View File
@@ -42,3 +42,4 @@ server-timing-enabled = false
server-trace-header = ""
server-unix-socket = ""
server-unix-socket-mode = "660"
url-use-legacy-target-names = true
@@ -44,3 +44,4 @@ server-timing-enabled = true
server-trace-header = "traceparent"
server-unix-socket = "/tmp/pgrst_io_test.sock"
server-unix-socket-mode = "777"
url-use-legacy-target-names = true
@@ -44,3 +44,4 @@ server-timing-enabled = false
server-trace-header = "CF-Ray"
server-unix-socket = "/tmp/pgrst_io_test.sock"
server-unix-socket-mode = "777"
url-use-legacy-target-names = true
@@ -44,3 +44,4 @@ server-timing-enabled = true
server-trace-header = "X-Request-Id"
server-unix-socket = "/tmp/pgrst_io_test.sock"
server-unix-socket-mode = "777"
url-use-legacy-target-names = false
+1
View File
@@ -43,3 +43,4 @@ server-timing-enabled = false
server-trace-header = ""
server-unix-socket = ""
server-unix-socket-mode = "660"
url-use-legacy-target-names = true
+1
View File
@@ -42,3 +42,4 @@ server-timing-enabled = false
server-trace-header = ""
server-unix-socket = ""
server-unix-socket-mode = "660"
url-use-legacy-target-names = true
+1
View File
@@ -41,6 +41,7 @@ PGRST_SERVER_TRACE_HEADER: X-Request-Id
PGRST_SERVER_TIMING_ENABLED: true
PGRST_SERVER_UNIX_SOCKET: /tmp/pgrst_io_test.sock
PGRST_SERVER_UNIX_SOCKET_MODE: 777
PGRST_URL_USE_LEGACY_TARGET_NAMES: false
PGRST_ADMIN_SERVER_HOST: 127.0.0.1
PGRST_ADMIN_SERVER_PORT: 3001
PGRST_ADMIN_SERVER_UNIX_SOCKET: /tmp/admin_io_test.sock
+1
View File
@@ -38,6 +38,7 @@ server-trace-header = "X-Request-Id"
server-timing-enabled = true
server-unix-socket = "/tmp/pgrst_io_test.sock"
server-unix-socket-mode = "777"
url-use-legacy-target-names = false
admin-server-port = 3001
admin-server-host = "127.0.0.1"
admin-server-unix-socket = "/tmp/admin_io_test.sock"
+2
View File
@@ -25,6 +25,7 @@ ALTER ROLE db_config_authenticator SET pgrst.openapi_server_proxy_uri = 'https:/
ALTER ROLE db_config_authenticator SET pgrst.server_cors_allowed_origins = 'http://origin.com';
ALTER ROLE db_config_authenticator SET pgrst.server_timing_enabled = 'false';
ALTER ROLE db_config_authenticator SET pgrst.server_trace_header = 'CF-Ray';
ALTER ROLE db_config_authenticator SET pgrst.url_use_legacy_target_names = 'true';
ALTER ROLE db_config_authenticator SET pgrst.db_hoisted_tx_settings = 'autovacuum_work_mem';
-- override with database specific setting
@@ -81,6 +82,7 @@ ALTER ROLE other_authenticator SET pgrst.openapi_server_proxy_uri = 'https://oth
ALTER ROLE other_authenticator SET pgrst.server_cors_allowed_origins = 'http://otherorigin.com';
ALTER ROLE other_authenticator SET pgrst.server_timing_enabled = 'true';
ALTER ROLE other_authenticator SET pgrst.server_trace_header = 'traceparent';
ALTER ROLE other_authenticator SET pgrst.url_use_legacy_target_names = 'true';
ALTER ROLE other_authenticator SET pgrst.db_hoisted_tx_settings = 'maintenance_work_mem';
create schema postgrest;
+1 -1
View File
@@ -3,7 +3,7 @@ GRANT USAGE ON SCHEMA test TO postgrest_test_anonymous;
GRANT SELECT ON authors_only TO postgrest_test_author;
GRANT SELECT ON projects TO postgrest_test_anonymous, postgrest_test_w_superuser_settings;
GRANT SELECT ON directors, films TO postgrest_test_anonymous, postgrest_test_w_superuser_settings;
GRANT SELECT ON directors, films, awards TO postgrest_test_anonymous, postgrest_test_w_superuser_settings;
GRANT ALL ON cats TO postgrest_test_anonymous;
GRANT ALL ON items_w_isolation_level TO postgrest_test_anonymous, postgrest_test_repeatable_read, postgrest_test_serializable;
+8
View File
@@ -25,6 +25,14 @@ CREATE TABLE films (
on delete cascade
);
CREATE TABLE awards (
id int primary key,
name text,
year int,
film_id int references films(id),
director_id int references directors(id)
);
-- data to test resource embedding
TRUNCATE TABLE directors CASCADE;
INSERT INTO directors
+30
View File
@@ -2089,3 +2089,33 @@ def test_work_mem_in_role_settings(defaultenv):
response = postgrest.session.post("/rpc/get_work_mem", headers=headers)
assert response.status_code == 200
assert response.text == '"3MB"'
@pytest.mark.parametrize("enabled", ["true", "false"])
def test_use_legacy_target_names(enabled, defaultenv):
"Show a warning when a target name is used instead of an alias, only when config is enabled"
env = {
**defaultenv,
"PGRST_URL_USE_LEGACY_TARGET_NAMES": enabled,
}
with run(env=env) as postgrest:
response = postgrest.session.get(
"/directors?select=name,all_films:films(title),awards_2026:awards(name)&films.order=title&awards.year=eq.2026"
)
output = postgrest.read_stdout(nlines=10)
log_err_warning = "WARNING: Embedded resource was referenced by relation name even though it has an alias. This is deprecated and will stop working in a future release."
log_err_hint = "Update filters, orders or limits that use `films` to `all_films`, `awards` to `awards_2026` in `GET /directors?select=name,all_films:films(title),awards_2026:awards(name)&films.order=title&awards.year=eq.2026`"
has_warning_log = any(log_err_warning in line for line in output)
has_hint_log = any(log_err_hint in line for line in output)
if enabled == "true":
assert response.status_code == 200
assert has_warning_log and has_hint_log
else:
assert response.status_code == 400
assert not has_warning_log and not has_hint_log