I have to call procedure to analyze table by name.
example: call schema_name.analyze('table_name')
.
I've created procedure, but I'm gettin an error
ERROR: relation "x" does not exist.
How to deal with it?
CREATE OR REPLACE PROCEDURE schema_name.analyze(IN x VARCHAR)
LANGUAGE plpgsql
AS $$
begin
analyze x;
END;
$$;
What worked for me:
CREATE OR REPLACE PROCEDURE public.analyze_test(x character varying)
LANGUAGE plpgsql
AS $procedure$
begin
EXECUTE 'analyze ' || quote_ident(x);
END;
$procedure$
Since you are doing dynamic naming use EXECUTE
. Then quote_ident()
to get the passed in name correctly quoted.
UPDATE
Example of why quote_ident()
is important:
create table "MixedCase" (id int);
CREATE OR REPLACE PROCEDURE public.analyze_test(x character varying)
LANGUAGE plpgsql
AS $procedure$
begin
EXECUTE 'analyze ' || x;
END;
$procedure$
call analyze_test('MixedCase');
ERROR: relation "mixedcase" does not exist
CONTEXT: SQL statement "analyze MixedCase"
PL/pgSQL function analyze_test(character varying) line 3 at EXECUTE
CREATE OR REPLACE PROCEDURE public.analyze_test(x character varying)
LANGUAGE plpgsql
AS $procedure$
begin
EXECUTE 'analyze ' || quote_ident(x);
END;
$procedure$
call analyze_test('MixedCase');
CALL
UPDATE 2
To have a procedure or function run with the privileges of the user that created it use SECURITY DEFINER
. See section at bottom of this page:
https://www.postgresql.org/docs/current/sql-createfunction.html
Writing SECURITY DEFINER Functions Safely
for the do's and don'ts.
Here is original function with SECURITY DEFINER
:
CREATE OR REPLACE PROCEDURE public.analyze_test(x character varying)
LANGUAGE plpgsql SECURITY DEFINER
AS $procedure$
begin
EXECUTE 'analyze ' || quote_ident(x);
END;
$procedure$