I have a plpgsql function to create child tables using table inheritance in PostgreSQL like this:
CREATE TABLE parent_table (
value integer,
end_time timestamp without time zone
);
CREATE OR REPLACE FUNCTION mk_child(_year INTEGER, _month INTEGER)
RETURNS text AS $$
DECLARE
tname varchar;
start_date date;
end_date date;
next_month varchar := (_month + 1)::text;
next_year varchar := (_year + 1)::text;
BEGIN
tname := 'child_y' || substring(_year::text from 3 for 2)
|| 'm' || lpad(_month::text, 2, '0');
start_date := DATE (_year::text || '-' || _month::text || '-01');
IF ( _month = 12 ) THEN
end_date := DATE (next_year || '-01-01');
ELSE
end_date := DATE (_year::text || '-' || next_month || '-01');
END IF;
RAISE NOTICE 'Creating child table %', tname;
EXECUTE format('CREATE TABLE %I ( CHECK ( end_time >= %L AND end_time < %L))
INHERITS (parent_table)', tname, start_date, end_date);
-- EXECUTE format('CREATE TABLE %I ( CHECK ( end_time >= $1 AND end_time < $2))
-- INHERITS (parent_table)', tname)
-- USING start_date, end_date;
RETURN tname;
END
$$ LANGUAGE plpgsql;
When I call it, it is successful:
# select mk_child(2015,1);
NOTICE: Creating child table child_y15m01
mk_child
--------------
child_y15m01
(1 row)
However, if I use the EXECUTE ... USING ...;
form (commented out in the snippet above), I get an error:
# select mk_child(2015,2);
NOTICE: Creating child table child_y15m02
ERROR: there is no parameter $1
CONTEXT: SQL statement "CREATE TABLE child_y15m02 ( CHECK ( end_time >= $1 AND end_time < $2 ) ) INHERITS (parent_table)"
PL/pgSQL function mk_child(integer,integer) line 21 at EXECUTE statement
The PostgreSQL docs say explicitly that this format works and is more efficient.
So why does it not work as expected?
CHECK
constraint, since that is DDL code, even if it looks like a DML statement that can work withUSING
. This is a good question with a sneaky problem that should not have been closed. I am addressing you since you are the only Postgres native in lynch mob - the rest seems to have followed your lead.