I have some problems in properly quoting a table name using the format function in the example below.
CREATE OR REPLACE FUNCTION copy_table(_source_tbl regclass, _target_tbl text)
RETURNS bool AS $func$
DECLARE query_str text;
BEGIN
query_str = format($fmt$ DROP TABLE IF EXISTS %1$I; CREATE TABLE %1$I AS (TABLE %s); $fmt$, _target_tbl, _source_tbl);
EXECUTE query_str;
RAISE NOTICE '%', query_str;
RETURN True;
END $func$ LANGUAGE plpgsql;
My dilemma is that I want to quote the input table name _target_tbl as an identifier (to avoid SQL injection). However, given a full table name ex.test1, this causes the schema part ex. to be treated as part of the table name and the table public."ex.test1" created in the default public. schema as shown below.
How should I quote/format the identifier properly here?
=> SELECT copy_table('ex.test', 'ex.test1');
NOTICE: table "ex.test1" does not exist, skipping
NOTICE: DROP TABLE IF EXISTS "ex.test1"; CREATE TABLE "ex.test1" AS (TABLE ex.test);
=> \dt ex.test1
Did not find any relation named "ex.test1".
=> \dt "ex.test1"
List of relations
Schema | Name | Type | Owner
--------+----------+-------+-------
public | ex.test1 | table |
(1 row)
This is with PostgreSQL 10.3.