eKol in #postgresql reported a problem with a plpgsql function crashing the server. I tested the attached against 8.2cvs as of this morning and got this stacktrace:

#0  plpgsql_xact_cb (event=XACT_EVENT_COMMIT, arg=0x0) at pl_exec.c:4521
#1  0x000000000046f43d in CallXactCallbacks (event=XACT_EVENT_COMMIT)
    at xact.c:2618
#2  0x000000000047138b in CommitTransaction () at xact.c:1534
#3  0x0000000000472be7 in CommitTransactionCommand () at xact.c:2184
#4  0x000000000058ecde in finish_xact_command () at postgres.c:2017
#5  0x0000000000590475 in exec_simple_query (
    query_string=0x8f8f28 "select admin.fn_revoke_all('public');")
    at postgres.c:1041
#6  0x00000000005917ab in PostgresMain (argc=4, argv=0x8bb360,
    username=0x8bb320 "jurka") at postgres.c:3231
#7  0x0000000000566a18 in ServerLoop () at postmaster.c:2917
#8  0x0000000000567861 in PostmasterMain (argc=3, argv=0x89b830)
    at postmaster.c:980
#9  0x00000000005250de in main (argc=3, argv=0x3e8) at main.c:254

Kris Jurka
DROP SCHEMA admin CASCADE;

CREATE SCHEMA admin;

create or replace function admin.fn_show_functions(text)
returns setof text as $$
declare
    v_schema alias for $1;
    v_schema_oid oid;
    v_function pg_catalog.pg_proc%rowtype;
    v_function_arg text;
    v_function_name_and_args text;
begin
    select into v_schema_oid oid
    from pg_catalog.pg_namespace
    where nspname = v_schema;

    if found then
        for v_function in select * from pg_catalog.pg_proc
        where pronamespace = v_schema_oid
        loop
            v_function_name_and_args := v_function.proname || '(';

            for i in 0..(v_function.pronargs - 1)
            loop
                select into v_function_arg typname
                from pg_catalog.pg_type
                where oid = v_function.proargtypes[i];

                if v_function_arg is not null then
                    v_function_name_and_args := v_function_name_and_args || 
v_function_arg || ', ';
                end if;
            end loop;

            v_function_name_and_args := trim(trailing ', ' from 
v_function_name_and_args);
            v_function_name_and_args := v_function_name_and_args || ')';

            return next v_function_name_and_args;
        end loop;
    end if;

    return;
end;
$$
language plpgsql;

create or replace function admin.fn_revoke_all(text)
returns void as $$
declare
    v_user alias for $1;
    v_schema record;
    v_obj record;
    v_current_db text;
begin
    -- Second, revoke on functions, tables, and views from
    -- user schemas.
    for v_schema in select nspname AS name FROM pg_namespace WHERE nspname NOT 
LIKE 'pg%' AND nspname NOT LIKE 'info%'
    loop
        perform admin.fn_revoke_all_functions_from(v_user, v_schema.name); 
    end loop;

end;
$$
language plpgsql;

create or replace function admin.fn_revoke_all_functions_from(text, text)
returns void as $$
declare
    v_user alias for $1;
    v_schema alias for $2;
    v_obj record;
begin
        for v_obj in select * from admin.fn_show_functions(v_schema) as name
        loop
            --raise notice 'revoking function %', v_obj.name;
            execute 'revoke all on function ' ||
            quote_ident(v_schema) || '."' ||
            replace(v_obj.name, '(', '"(') || ' from ' ||
            quote_ident(v_user);
        end loop;
end;
$$
language plpgsql;


SELECT admin.fn_revoke_all('public');
-- Sometimes doesn't crash on the first attempt
SELECT admin.fn_revoke_all('public');
SELECT admin.fn_revoke_all('public');
SELECT admin.fn_revoke_all('public');
---------------------------(end of broadcast)---------------------------
TIP 3: Have you checked our extensive FAQ?

               http://www.postgresql.org/docs/faq

Reply via email to