On Fri, Jan 25, 2013 at 09:40:07PM +1100, Peter Rabbitson wrote:
> On Fri, Jan 25, 2013 at 10:17:11AM +0000, Tim Bunce wrote:
> > Re https://rt.cpan.org/Public/Bug/Display.html?id=82942
> > 
> > The key question: is this a bug or a feature?
> 
> Can you walk me through your thought process on what makes this a feature?
> Not trying to be difficult, I am just having trouble seeing the use-case ;)

A cache statement is cached because the user asked for it to be cached.

    $sth = $dbh->prepare_cached($sql);

I think it's reasonable to assume that binding a reference value to a
placeholder of a cached statement handle will cause the ref count of the
value to increase.

    $sth->bind_param_inout(1, \@foo);

The particular case in the ticket uses an reference to an object with
stringfy magic:

    $sth->bind_param(1, $object_that_stringifies);

which is an extra wrinkle.

All this seems like reasonable and natural behaviour to me.
However, it also seems potentially inconvenient, as you've found.

So, the question then is what options do we have for "fixing" it?

The most obvious thing to do would be to weaken the refs in
values %{ $sth->{ParamValues} }. That could be done in the
application, so a DBI change isn't strictly needed.

If it's agreed that the DBI should weaken the refs then
we'd need to discuss when. As soon as they're bound?
I can imagine cases where values are bound in a lexical scope
that's exited before the $sth->execute() call, so that's not safe.

After the execute()? No, execute might be called again.

After finish()? Maybe. The docs for finish is already say "Calling finish ...
may also make some statement handle attributes (such as NAME and TYPE)
unavailable if they have not already been accessed (and thus cached)."
It seems reasonable to extend that to say that any references in
ParamValues will be weaked.

Bound values are meant to persist across finish(), so there are still risks.

I'm not keen on adding another attribute just to control this edge case.

Tim.



Reply via email to