dbTalk Databases Forums  

Review question

comp.databases.postgresql comp.databases.postgresql


Discuss Review question in the comp.databases.postgresql forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
Mladen Gogala
 
Posts: n/a

Default Review question - 05-16-2011 , 12:19 PM






I have a partitioned table and the insert statements find the right
partition through the following trigger function:

CREATE OR REPLACE FUNCTION moreover.moreover_insert_trgfn()
RETURNS trigger AS
$BODY$
BEGIN
IF ( NEW.created_at >= TIMESTAMP '2011-04-01 00:00:00' AND
NEW.created_at < TIMESTAMP '2011-05-01 00:00:00' ) THEN
INSERT INTO moreover.moreover_documents_y2011m04 VALUES (NEW.*);
ELSIF ( NEW.created_at >= TIMESTAMP '2011-05-01 00:00:00' AND
NEW.created_at < TIMESTAMP '2011-06-01 00:00:00' ) THEN
INSERT INTO moreover.moreover_documents_y2011m05 VALUES (NEW.*);
ELSIF ( NEW.created_at >= TIMESTAMP '2011-06-01 00:00:00' AND
NEW.created_at < TIMESTAMP '2011-07-01 00:00:00' ) THEN
INSERT INTO moreover.moreover_documents_y2011m06 VALUES (NEW.*);
ELSE
RAISE EXCEPTION 'Date out of range.
Fix the moreover_insert_trigger() function!';
END IF;
RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

The only problem with that function is that I have to change it from time
to time. Being lazy bum that I am, I came up with the following trigger
function on my test DB:

CREATE OR REPLACE FUNCTION moreover.moreover_insert_trgfn()
RETURNS trigger AS
$BODY$
DECLARE
V_MONTH SMALLINT;
V_YEAR VARCHAR(4);
V_INS VARCHAR(512):='insert into moreover.moreover_documents_y';
V_VALS VARCHAR(128):=' VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,
$13,$14,$15,$16,$17,$18)';
BEGIN
SELECT EXTRACT(MONTH FROM NEW.created_at) INTO V_MONTH;
SELECT EXTRACT(YEAR FROM NEW.created_at) INTO V_YEAR;
IF (V_MONTH>=10) THEN
V_INS:=V_INS||V_YEAR||'m'||V_MONTH||V_VALS;
ELSE
V_INS:=V_INS||V_YEAR||'m0'||V_MONTH||V_VALS;
END IF;
execute V_INS USING NEW.document_id,
NEW.dre_reference,
NEW.headline,
NEW.author,
NEW.url,
NEW.rank,
NEW.content,
NEW.stories_like_this,
NEW.internet_web_site_id,
NEW.harvest_time,
NEW.valid_time,
NEW.keyword,
NEW.article_id,
NEW.media_type,
NEW.source_type,
NEW.created_at,
NEW.autonomy_fed_at,
NEW.language;
RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

The function tests perfectly but it is a bit more complex. It should
route approximately 1 million records every day to the right partition.
Any thoughts or words of caution?

--
http://mgogala.byethost5.com

Reply With Quote
  #2  
Old   
Laurenz Albe
 
Posts: n/a

Default Re: Review question - 05-17-2011 , 03:34 AM






Mladen Gogala wrote:
Quote:
I have a partitioned table and the insert statements find the right
partition through the following trigger function:

[static SQL]

The only problem with that function is that I have to change it from time
to time. Being lazy bum that I am, I came up with the following trigger
function on my test DB:

CREATE OR REPLACE FUNCTION moreover.moreover_insert_trgfn()
RETURNS trigger AS
$BODY$
DECLARE
V_MONTH SMALLINT;
V_YEAR VARCHAR(4);
V_INS VARCHAR(512):='insert into moreover.moreover_documents_y';
V_VALS VARCHAR(128):=' VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,
$13,$14,$15,$16,$17,$18)';
BEGIN
SELECT EXTRACT(MONTH FROM NEW.created_at) INTO V_MONTH;
SELECT EXTRACT(YEAR FROM NEW.created_at) INTO V_YEAR;
IF (V_MONTH>=10) THEN
V_INS:=V_INS||V_YEAR||'m'||V_MONTH||V_VALS;
ELSE
V_INS:=V_INS||V_YEAR||'m0'||V_MONTH||V_VALS;
END IF;
execute V_INS USING NEW.document_id,
NEW.dre_reference,
NEW.headline,
NEW.author,
NEW.url,
NEW.rank,
NEW.content,
NEW.stories_like_this,
NEW.internet_web_site_id,
NEW.harvest_time,
NEW.valid_time,
NEW.keyword,
NEW.article_id,
NEW.media_type,
NEW.source_type,
NEW.created_at,
NEW.autonomy_fed_at,
NEW.language;
RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

The function tests perfectly but it is a bit more complex. It should
route approximately 1 million records every day to the right partition.
Any thoughts or words of caution?
There will be a performance impact because the dynamic statement must be
prepared whenever it is used, but that should not be too bad with a
simple INSERT statement.

Note that you remove one hard-coded dependency on the partitions, but
introduce another one on the column names.

You might get away shorter and more flexibly with something like that:

....
V_VALS text:=' VALUES($1.*)';
....
execute V_INS USING NEW;
....

I tried it on PostgreSQL 8.4, I don't know if it works as nicely
on older versions.

Yours,
Laurenz Albe

Reply With Quote
  #3  
Old   
Mladen Gogala
 
Posts: n/a

Default Re: Review question - 05-17-2011 , 07:19 AM



On Tue, 17 May 2011 10:34:29 +0200, Laurenz Albe wrote:


Quote:
You might get away shorter and more flexibly with something like that:

...
V_VALS text:=' VALUES($1.*)';
...
execute V_INS USING NEW;
Thanks, Laurenz. I will try that.



--
http://mgogala.byethost5.com

Reply With Quote
  #4  
Old   
Mladen Gogala
 
Posts: n/a

Default Re: Review question - 05-18-2011 , 01:19 PM



On Tue, 17 May 2011 10:34:29 +0200, Laurenz Albe wrote:

Quote:
You might get away shorter and more flexibly with something like that:

...
V_VALS text:=' VALUES($1.*)';
...
execute V_INS USING NEW;
...
Works as a charm on 9.0.4.



--
http://mgogala.freehostia.com

Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.3
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.