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
|