in reply to Modification of a read-only

Jonathan,

While <node>tye</node> makes some valid points, I don't think that's what the problem is here. I believe deep down in the DBD::Sybase (that's what driver you're using correct?) there is some little magic that is marking the return'ed ref as read only (disclaimer - I'm not an internals expert).

If we try some of the other fetch methods, we see some interesting things:

my $data; do { while ($data = $res->fetchrow_arrayref()) { if ($res->{syb_result_type} == CS_ROW_RESULT) { if (defined $data) { @$data = map { defined($_) ? $_ : "" } @$data; } } } }

same problem. However:

my @data; do { while (@data = $res->fetchrow_array()) { if ($res->{syb_result_type} == CS_ROW_RESULT) { if (@data) { @data = map { defined($_) ? $_ : "" } @data; } } } }

works. The funny thing is by stepping through the map statement in the debugger, the assignments to $_ are fine, it's just the final assigment to @$data that is barfing. Any Inline or XS writers out there care to comment?

-derby

Replies are listed 'Best First'.
Re: Re: Modification of a read-only
by mpeppler (Vicar) on Oct 09, 2001 at 01:15 UTC
    DBI internals actually allocate the array that is returned by fetch_xxxref() - DBD::Sybase just fills each item as needed.

    DBI also sets this array "read-only", which I had to work-around as Sybase can return multiple result sets with varying number of columns.

    So DBD::Sybase has this code in the fetch routine:

    av = DBIS->get_fbav(imp_sth); num_fields = AvFILL(av)+1; /* XXX The code in the if() below is likely to break with new versions of DBI!!! */ if(num_fields < imp_sth->numCols) { int isReadonly = SvREADONLY(av); if(isReadonly) SvREADONLY_off(av); /* DBI sets this readonly */ i = imp_sth->numCols - 1; while(i >= num_fields) av_store(av, i--, newSV(0)); num_fields = AvFILL(av)+1; if(isReadonly) SvREADONLY_on(av); /* protect against shift @$row etc * +/
    To summarize - the array that is referenced by $data in the code snippet above is read-only, but each of the items in the array are read-write (hence the assignment to @$data fails, but setting $_ for each undef item works).

    Michael

Re: Re: Modification of a read-only
by Jonathan (Curate) on Sep 12, 2001 at 11:18 UTC
    tye makes a valid point (I'm cutting too many corners lately) but your response appears much closer. Yes it is a Sybase database. I'm using fetchrow_arrayref for performance reasons (I'm processing half a million records, about 350Mb of data). I've still got the problem. I want to change the data in the array reference to get rid of warnings but don't want the performance hit of creating another array. Doh!
      I'd use a

      local $^W = 0;
      to get rid of the warnings...

      Michael