davidfetter has asked for the wisdom of the Perl Monks concerning the following question:

O gu's of ru's,

I'm looking for ways to turn arrays in PostgreSQL (www.postgresql.org) into arrays in Perl. Ideally, there's some way to walk the PostgreSQL array data structure and By Some Magic(TM), turn them into Perl arrays. This is for PL/Perl, by the way, although it would probably apply to DBD::Pg too.

Any pointers as to how to do this or to whom to talk with about such things would be greatly appreciated.

Replies are listed 'Best First'.
Re: PostgreSQL arrays -> Perl arrays
by siracusa (Friar) on Jul 13, 2005 at 12:09 UTC

    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
Re: PostgreSQL arrays -> Perl arrays
by tphyahoo (Vicar) on Jul 13, 2005 at 09:05 UTC