Re: [GENERAL] Perl DBI + binary data in psql not working

From: Dirk Lutzebaeck <lutzeb(at)aeccom(dot)com>
To: Paul Schilling <pfschill(at)direct-learning(dot)com>
Cc: pgsql-general(at)postgreSQL(dot)org, dbi-users(at)fugue(dot)com, Jeffrey Baker <jwb(at)cp(dot)net>, Gerald Richter <richter(at)ecos(dot)de>
Subject: Re: [GENERAL] Perl DBI + binary data in psql not working
Date: 1999-10-13 07:39:22
Message-ID: 14340.14122.248067.822404@ampato.aeccom.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general


Paul Schilling writes:
> I am trying to use Apache::Session + psql and ran into a problem with
> binary data from Storable::nfreeze To demonstrate what is happening I
> wrote this quick script:
>
> #!/usr/bin/perl
> use DBI;
> use strict;
> use Storable qw(nfreeze thaw);
>
> my $dbh = DBI->connect("dbi:Pg:dbname=pfschill", '', '');
> my $st = $dbh->prepare_cached('
> INSERT INTO sessions (id, length, a_session) VALUES (?,?,?)');
>
> my $data = {'stuff' => 'other stuff'};
> my $serialized = nfreeze $data;
> my $session = "1234";
>
> $st->bind_param(1, $session);
> $st->bind_param(2, length $serialized);
> $st->bind_param(3, $serialized);
> $st->execute;
>
> Running this you get:
> DBD::Pg::st execute failed: ERROR: parser: parse error at or near ""
> Database handle destroyed without explicit disconnect.
>

Paul, the problem is that Postgres can't seem to save binary data in
TEXT fields. Apache::Session uses (n)freeze which produces binary data
for a TEXT field. So you can't use vanilla Apache::Session with
Postgres (ie. DBD::Pg) :(

The solution is to patch DBIStore.pm from Apache::Session 1.0.x to use
base64 encoding/decoding:

< use MIME::Base64 qw(encode_base64 decode_base64);
138,139c137,138
< my $serialized = encode_base64(nfreeze $session->{data});
<
---
> my $serialized = nfreeze $session->{data};
>
163d160
< my $serialized = encode_base64(nfreeze $session->{data});
165,167c162
< if (length $serialized > 8000) {
< die "session data too big";
< }
---
> my $serialized = nfreeze $session->{data};
202c197
< $session->{data} = thaw decode_base64($results->[0]);
---
> $session->{data} = thaw $results->[0];

You need the MIME::Base64 package from CPAN.

You might also realize that Postgres has an 8k limit on a row, so
saving big sessions is also a problem.

Jeffrey, I have cc'ed this to you. Maybe you can put two options for
the tie in one of the next version of Apache::Session

DataSourceCantStoreBinary and
DataSourceRowLimit

It would be also possible to write a subclass to DBIStore.pm

Regards,

Dirk

In response to

Browse pgsql-general by date

  From Date Subject
Next Message Mark Jewiss 1999-10-13 07:59:26 Re: [GENERAL] stored procedure revisited
Previous Message Nikolay Mijaylov 1999-10-13 07:37:31 Fw: Indexes?!?!?