diff --git a/test/iceberg_data_files.sh b/test/iceberg_data_files.sh index f8fac4e37..fb53b1b79 100755 --- a/test/iceberg_data_files.sh +++ b/test/iceberg_data_files.sh @@ -288,23 +288,34 @@ check "a table with no current snapshot yields no data files" \ "$(q "SELECT count(*) FROM pgcolumnar.iceberg_data_files('$NOSNAP')")" "0" # ---- privilege: needs pg_read_server_files --------------------------------- -# The role gets USAGE on the schema and EXECUTE on the function, so the refusal is -# the function's own gate. Without them the 42501 is "permission denied for schema -# pgcolumnar", the function never runs, and the arm cannot fail on the gate it names. +# The role gets USAGE on the schema, so the refusal is the function's own gate (EXECUTE +# it already has, through PUBLIC). Without USAGE the 42501 is "permission denied for +# schema pgcolumnar" and the function never runs, so the arm requires the gate's own +# message, naming pg_read_server_files, and not only the SQLSTATE they share. DROP_UNPRIV="DO \$\$BEGIN IF EXISTS (SELECT FROM pg_roles WHERE rolname = 'icedf_unpriv') THEN EXECUTE 'DROP OWNED BY icedf_unpriv'; END IF; END\$\$; DROP ROLE IF EXISTS icedf_unpriv;" psql_run "$DROP_UNPRIV CREATE ROLE icedf_unpriv LOGIN; -GRANT USAGE ON SCHEMA pgcolumnar TO icedf_unpriv; -GRANT EXECUTE ON FUNCTION pgcolumnar.iceberg_data_files TO icedf_unpriv;" -check "an unprivileged role is refused (42501)" \ - "$(env PATH="$PGC_BINDIR:$PATH" psql -h 127.0.0.1 -p "$PGC_PORT" -U icedf_unpriv -d "$PGC_DB" \ - -qtA 2>&1 <&1 < None, or the failed reading.""" try: @@ -208,14 +222,14 @@ def _run(dsn, *stmts): return _failed(exc) -# The unprivileged role reaches the function: USAGE on the schema and EXECUTE on the -# function, or its 42501 is the schema's and the pg_read_server_files gate never runs. +# The unprivileged role reaches the function: USAGE on the schema (EXECUTE it has +# through PUBLIC), or its 42501 is the schema's and the pg_read_server_files gate never +# runs. The arm requires the gate's own message, not only the SQLSTATE they share. DROP_UNPRIV = ("DO $$BEGIN IF EXISTS (SELECT FROM pg_roles WHERE rolname = 'icedf_unpriv') " "THEN EXECUTE 'DROP OWNED BY icedf_unpriv'; END IF; END$$", "DROP ROLE IF EXISTS icedf_unpriv") MAKE_UNPRIV = DROP_UNPRIV + ("CREATE ROLE icedf_unpriv LOGIN", - "GRANT USAGE ON SCHEMA pgcolumnar TO icedf_unpriv", - "GRANT EXECUTE ON FUNCTION pgcolumnar.iceberg_data_files TO icedf_unpriv") + "GRANT USAGE ON SCHEMA pgcolumnar TO icedf_unpriv") def _alive(pgc_cluster): @@ -313,7 +327,7 @@ def ice(pgc_cluster, tmp_path_factory): got[f"entry {k}"] = _sqlstate(dsn, entries[k]) got["alive entries"] = _recovered(pgc_cluster, _alive(pgc_cluster)) got["no snapshot"] = _one(dsn, lst.format("count(*)"), str(nosnap)) - got["unprivileged"] = _run(dsn, *MAKE_UNPRIV) or _sqlstate(dsn, md, role="icedf_unpriv") + got["unprivileged"] = _run(dsn, *MAKE_UNPRIV) or _gate_refusal(dsn, md, "icedf_unpriv") try: yield got finally: