Home Explore Blog CI



postgresql

60th chunk of `doc/src/sgml/ddl.sgml`
6d5aaebc9c891091859d94c0b122f170d88a06c3e2598b9f0000000100000fad
 constraints like:
<programlisting>
CHECK ( outletID BETWEEN 100 AND 200 )
CHECK ( outletID BETWEEN 200 AND 300 )
</programlisting>
         This is wrong since it is not clear which child table the key
         value 200 belongs in.
         Instead, ranges should be defined in this style:

<programlisting>
CREATE TABLE measurement_y2006m02 (
    CHECK ( logdate &gt;= DATE '2006-02-01' AND logdate &lt; DATE '2006-03-01' )
) INHERITS (measurement);

CREATE TABLE measurement_y2006m03 (
    CHECK ( logdate &gt;= DATE '2006-03-01' AND logdate &lt; DATE '2006-04-01' )
) INHERITS (measurement);

...
CREATE TABLE measurement_y2007m11 (
    CHECK ( logdate &gt;= DATE '2007-11-01' AND logdate &lt; DATE '2007-12-01' )
) INHERITS (measurement);

CREATE TABLE measurement_y2007m12 (
    CHECK ( logdate &gt;= DATE '2007-12-01' AND logdate &lt; DATE '2008-01-01' )
) INHERITS (measurement);

CREATE TABLE measurement_y2008m01 (
    CHECK ( logdate &gt;= DATE '2008-01-01' AND logdate &lt; DATE '2008-02-01' )
) INHERITS (measurement);
</programlisting>
        </para>
       </listitem>

       <listitem>
        <para>
         For each child table, create an index on the key column(s),
         as well as any other indexes you might want.
<programlisting>
CREATE INDEX measurement_y2006m02_logdate ON measurement_y2006m02 (logdate);
CREATE INDEX measurement_y2006m03_logdate ON measurement_y2006m03 (logdate);
CREATE INDEX measurement_y2007m11_logdate ON measurement_y2007m11 (logdate);
CREATE INDEX measurement_y2007m12_logdate ON measurement_y2007m12 (logdate);
CREATE INDEX measurement_y2008m01_logdate ON measurement_y2008m01 (logdate);
</programlisting>
        </para>
       </listitem>

       <listitem>
        <para>
         We want our application to be able to say <literal>INSERT INTO
         measurement ...</literal> and have the data be redirected into the
         appropriate child table.  We can arrange that by attaching
         a suitable trigger function to the root table.
         If data will be added only to the latest child, we can
         use a very simple trigger function:

<programlisting>
CREATE OR REPLACE FUNCTION measurement_insert_trigger()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO measurement_y2008m01 VALUES (NEW.*);
    RETURN NULL;
END;
$$
LANGUAGE plpgsql;
</programlisting>
        </para>

        <para>
         After creating the function, we create a trigger which
         calls the trigger function:

<programlisting>
CREATE TRIGGER insert_measurement_trigger
    BEFORE INSERT ON measurement
    FOR EACH ROW EXECUTE FUNCTION measurement_insert_trigger();
</programlisting>

         We must redefine the trigger function each month so that it always
         inserts into the current child table.  The trigger definition does
         not need to be updated, however.
        </para>

        <para>
         We might want to insert data and have the server automatically
         locate the child table into which the row should be added. We
         could do this with a more complex trigger function, for example:

<programlisting>
CREATE OR REPLACE FUNCTION measurement_insert_trigger()
RETURNS TRIGGER AS $$
BEGIN
    IF ( NEW.logdate &gt;= DATE '2006-02-01' AND
         NEW.logdate &lt; DATE '2006-03-01' ) THEN
        INSERT INTO measurement_y2006m02 VALUES (NEW.*);
    ELSIF ( NEW.logdate &gt;= DATE '2006-03-01' AND
            NEW.logdate &lt; DATE '2006-04-01' ) THEN
        INSERT INTO measurement_y2006m03 VALUES (NEW.*);
    ...
    ELSIF ( NEW.logdate &gt;= DATE '2008-01-01' AND
            NEW.logdate &lt; DATE '2008-02-01' ) THEN
        INSERT INTO measurement_y2008m01 VALUES (NEW.*);
    ELSE
        RAISE EXCEPTION 'Date out of range.  Fix the measurement_insert_trigger() function!';
    END IF;
    RETURN NULL;
END;
$$
LANGUAGE plpgsql;
</programlisting>

         The trigger definition is the same as before.
         Note that each <literal>IF</literal> test must exactly match the
         <literal>CHECK</literal>

Title: Partitioning Using Inheritance: Completing the Implementation
Summary
This section continues the step-by-step example of implementing partitioning using inheritance. It covers creating indexes on key columns for each child table, and attaching a trigger function to the root table to redirect data to the appropriate child table upon insertion. Two trigger function examples are provided: a simple one for inserting data only into the latest child, and a more complex one to automatically locate the correct child table based on data values. The importance of matching the IF tests in the trigger function to the CHECK constraints on the child tables is emphasized.