On Sat, Jan 26, 2013 at 07:21:56PM +1100, Peter Rabbitson wrote: > On Fri, Jan 25, 2013 at 10:59:46PM +0000, Tim Bunce wrote: > > 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. > > Perhaps there is a mismatch of understanding here. For me the only > benefit of using a cached statement is to avoid a prepare. Executing the > *same* statement with the *same* values *without* rebind does not seem > to be possible in the first place (according to the docs at least):
I don't follow you here Peter. This should work fine: $sth = $dbh->prepare_cached($sql); $sth->bind_param(1, $foo); $sth->execute(); $sth->execute(); $sth->execute(); $sth->execute(); > > $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); > > Yes, otherwise it may get lost before the consequent execute(). > > 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. > > That won't work as per my above remark. Now that I think of it your > cached statements are not copies, they are extra refs. Which means that > you can't really weaken it in the cached ones only. > > > 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. > > If this is possible - docs/tests should reflect that (I am still fuzzy > on what the semantics are, hence no patches to offer). Does the example above clarify it? > > 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. > > After finish() won't work, because the app (DBIC in this case) doesn't > know to call finish() before garbage collection, which never happens > because of the circular ref. Augh! > > Bound values are meant to persist across finish(), so there are still risks. > > Also undocumented ;) Bound values are spec'd to persist in general. No need to mention finish(). > > I'm not keen on adding another attribute just to control this edge case. > > No, we shouldn't. After running through your thought process (thank you) > it is clear this can not be fixed with conventional approaches. I need > to wrap up Variable::Entangled that we specced out with Aristotle at > last YAPC::EU but then neither of us got to completion. > > In the meantime stalling the bugreport with a link to this discussion > sounds sane. Will do. Tim.