|
31 | 31 | ) |
32 | 32 |
|
33 | 33 |
|
| 34 | +def psql_as_superuser(query): |
| 35 | + subprocess.check_call( |
| 36 | + [ |
| 37 | + "psql", |
| 38 | + "--username", |
| 39 | + "postgres", |
| 40 | + "--set", |
| 41 | + "ON_ERROR_STOP=1", |
| 42 | + "-c", |
| 43 | + query, |
| 44 | + ] |
| 45 | + ) |
| 46 | + |
| 47 | + |
34 | 48 | def test_connect_with_dburi(dburi, defaultenv): |
35 | 49 | "Connecting with db-uri instead of LIPQ* environment variables should work." |
36 | 50 | defaultenv_without_libpq = { |
@@ -1204,6 +1218,61 @@ def test_notify_reloading_catalog_cache(defaultenv): |
1204 | 1218 | assert response.status_code == 200 |
1205 | 1219 |
|
1206 | 1220 |
|
| 1221 | +def test_stale_schema_cache_dropped_table_returns_database_error(defaultenv): |
| 1222 | + "dropped table should return a database error while schema cache is stale" |
| 1223 | + |
| 1224 | + table = f"stale_schema_cache_items_{os.getpid()}" |
| 1225 | + internal_sleep = 2 |
| 1226 | + env = { |
| 1227 | + **defaultenv, |
| 1228 | + "PGRST_DB_POOL": "2", |
| 1229 | + "PGRST_DB_CHANNEL_ENABLED": "true", |
| 1230 | + "PGRST_INTERNAL_SCHEMA_CACHE_QUERY_SLEEP": str(internal_sleep * 1000), |
| 1231 | + } |
| 1232 | + path = f"/{table}" |
| 1233 | + |
| 1234 | + try: |
| 1235 | + psql_as_superuser( |
| 1236 | + f""" |
| 1237 | + drop table if exists {table}; |
| 1238 | + create table {table}(id int primary key); |
| 1239 | + insert into {table} values (1); |
| 1240 | + grant select on {table} to postgrest_test_anonymous; |
| 1241 | + """ |
| 1242 | + ) |
| 1243 | + |
| 1244 | + with run(env=env, wait_max_seconds=10) as postgrest: |
| 1245 | + response = postgrest.session.get(path) |
| 1246 | + assert response.status_code == 200 |
| 1247 | + assert response.json() == [{"id": 1}] |
| 1248 | + |
| 1249 | + psql_as_superuser( |
| 1250 | + f""" |
| 1251 | + drop table {table}; |
| 1252 | + notify pgrst, 'reload schema'; |
| 1253 | + """ |
| 1254 | + ) |
| 1255 | + |
| 1256 | + response = postgrest.session.get(path) |
| 1257 | + payload = response.json() |
| 1258 | + assert response.status_code == 404 |
| 1259 | + assert payload["code"] == "42P01" |
| 1260 | + assert payload["message"] == f'relation "public.{table}" does not exist' |
| 1261 | + |
| 1262 | + time.sleep(internal_sleep + 0.3) |
| 1263 | + |
| 1264 | + response = postgrest.session.get(path) |
| 1265 | + assert response.status_code == 404 |
| 1266 | + assert response.json() == { |
| 1267 | + "code": "PGRST205", |
| 1268 | + "details": None, |
| 1269 | + "hint": None, |
| 1270 | + "message": f"Could not find the table 'public.{table}' in the schema cache", |
| 1271 | + } |
| 1272 | + finally: |
| 1273 | + psql_as_superuser(f"drop table if exists {table};") |
| 1274 | + |
| 1275 | + |
1207 | 1276 | def test_role_settings(defaultenv): |
1208 | 1277 | "statement_timeout should be set per role" |
1209 | 1278 |
|
|
0 commit comments