Thread: partitioned table insert triggers

partitioned table insert triggers

From
Reece Hart
Date:
I'm trying to create a date-partitioned version of the postgres_log
table that is described here:
http://www.postgresql.org/docs/current/static/runtime-config-logging.html


In lieu of hardcoding the partition table names in the trigger, as shown
in the table partitioning docs, I wanted to dynamically compute the
table name. I tried:

        CREATE OR REPLACE FUNCTION postgres_log_insert_trigger()
        RETURNS TRIGGER AS $$
        DECLARE
            c text;
            ptable text := 'postgres_log';
            ctable text := ptable || '_' ||
        to_char(NEW.session_start_time, 'YYYY_MM');
        BEGIN
            c := 'INSERT INTO ' || ctable || ' VALUES (NEW.*)';
            EXECUTE c;
            RETURN NULL;
        END;
        $$
        LANGUAGE plpgsql;

I get:
        ERROR:  NEW used in query that is not in a rule
        CONTEXT:  SQL statement "INSERT INTO
        measurement_postgres_log_2008_05 VALUES (NEW.*)"
        PL/pgSQL function "postgres_log_insert_trigger" line 7 at
        EXECUTE statement

I didn't really think that would work exactly for the reason given, but
I didn't know what else to try.

Now that my only idea is gone, the question for y'all is: how?

(Okay, I actually do have one more idea: construct the insert values
list with quote_literal. I'm hoping there's a better way.)

Thanks,
Reece

--
Reece Hart, http://harts.net/reece/, GPG:0x25EC91A0


Re: partitioned table insert triggers

From
ITAGAKI Takahiro
Date:
Reece Hart <reece@harts.net> wrote:

>             c := 'INSERT INTO ' || ctable || ' VALUES (NEW.*)';

> Now that my only idea is gone, the question for y'all is: how?
>
> ?(Okay, I actually do have one more idea: construct the insert values
> list with quote_literal. I'm hoping there's a better way.)

You need to do so in 8.3:
    EXECUTE 'INSERT INTO ' || ctable ||
            ' VALUES( (' || quote_literal(new) || '::' || ptable || ').*)';

In 8.4, the next release, you will be able to use a better way:
    EXECUTE 'INSERT INTO ' || ctable || ' VALUES( ($1).* )' USING new;

Regards,
---
ITAGAKI Takahiro
NTT Open Source Software Center



Re: partitioned table insert triggers

From
Reece Hart
Date:
On Mon, 2008-06-23 at 10:18 +0900, ITAGAKI Takahiro wrote:
You need to do so in 8.3:
    EXECUTE 'INSERT INTO ' || ctable ||
            ' VALUES( (' || quote_literal(new) || '::' || ptable || ').*)';

In 8.4, the next release, you will be able to use a better way:
    EXECUTE 'INSERT INTO ' || ctable || ' VALUES( ($1).* )' USING new;

Domo arigato, Itagaki-san. (I think I got that right.)

The 8.3 method works like a charm.

-Reece

-- 
Reece Hart, http://harts.net/reece/, GPG:0x25EC91A0