in reply to PostgreSQL arrays -> Perl arrays

EDIT: Ack, nevermind the example below the <hr>, I missed the PL/Perl part of the question. Inside PL/Perl, if the array values are represented by strings, then you could parse them into Perl arrays, manipulate them, and then format them back into Postgres's string form using Rose::DB's parse_array() and format_array() methods. But that's hardly efficient when compared to some sort of "native" manipulation within PL/* ... :-/

AFAIK, there's no good way to apply any fancy tricks to DBD::Pg's internals because the array values all get stringified once they actually leave the database. (i.e., By the time DBD::Pg gets them, they're strings). Last time I checked, even Postgre's native PL/PgSQL language isn't too great at manipulating array values in-place (push, pop, splice, etc.) which leads me to believe that Pg's array value internal representation is not "public." (If it was presumably PL/PgSQL, at least, would know how to manipulate it.) Maybe Pg 8.x improved this?

Asking on the pgsql-general mailing list is your best bet. They can direct you to a more specific list if no one on "general" can answer your questions.

Anyway, here's the string-based version:

use Rose::DB; Rose::DB->register_db ( domain => 'default', type => 'default', driver => 'Pg', ); $db = Rose::DB->new; $s = '{2,"four",6,8}'; $a = $db->parse_array($s); pop(@$a); $a->[2]++; $f = $db->format_array($a); # '{2,"four",7}'

I've got a column type for Postgres's native array type in Rose::DB::Object. It's the way I manipulate Postgres's array column values on the Perl side of things:

The table:

CREATE TABLE mywidgets ( id SERIAL NOT NULL PRIMARY KEY, name VARCHAR(255) NOT NULL, nums INT[] );

The class:

package MyWidget; use base 'Rose::DB::Object'; MyWidget->meta->table('mywidgets'); MyWidget->meta->columns ( id => { type => 'serial', not_null => 1, primary_key => 1 }, name => { type => 'varchar', length => 255, not_null => 1 }, nums => { type => 'array' }, ); MyWidget->meta->error_mode('fatal'); MyWidget->meta->initialize; 1;

Examples of array column value manipulation:

$n = MyWidget->new(name => 'Sprocket', nums => [ 2, 4, 6, 8 ]); $n->save; $n2 = MyWidget->new(id => $n->id); $n2->load; print $n2->nums->[1]; # 4