[Dbix-class] find redux

Zbigniew Lukasiak zzbbyy at gmail.com
Fri Feb 1 09:23:33 GMT 2008


On Feb 1, 2008 9:31 AM, Matt S Trout <dbix-class at trout.me.uk> wrote:
> On Thu, Jan 31, 2008 at 11:09:19AM +0100, Zbigniew Lukasiak wrote:
>
> > On Jan 31, 2008 10:39 AM, Matt S Trout <dbix-class at trout.me.uk> wrote:
> > > On Wed, Jan 30, 2008 at 07:57:02PM +0100, Zbigniew Lukasiak wrote:
> > > > Hi Matt,
> > > >
> > > > You are a mystery to me - but I'll try to comply and interleave my
> > > > comments with your original post as you wish.
> > > >
> > > > On Jan 24, 2008 1:14 PM, Matt S Trout <dbix-class at trout.me.uk> wrote:
> > > > > =head1 calling cases
> > > > >
> > > > > Case 1 - called with 'key' attr and all columns for that key[0]
> > > > > Case 2 - called with 'key' attr and not all columns for that key
> > > > >
> > > > > Case 3 - called without 'key' attr and with a unique key's worth of cols[0]
> > > > > Case 4 - called without key and no unique set of columns
> > > > >
> > > > > =head1 08000
> > > > >
> > > > > Current behaviour (I think, please correct me if I'm wrong):
> > > > >
> > > > > 1: does the expected query, ignoring other columns
> > > >
> > > > This is not true.  Here is example:
> > > >
> > > > my $cd = $schema->resultset("CD")->first;
> > > > my $artist_rs = $schema->resultset("Artist")->search( { artistid =>
> > > > $cd->artist->artistid } );
> > > > $schema->storage->debug(1);
> > > > $artist_rs->find( { name => 'some other name' }, { key => 'primary' }
> > > > );  # this is the query
> > > >
> > > > __OUTPUT__
> > > >
> > > > t/61findnot......SELECT me.artistid, me.name FROM artist me WHERE ( (
> > > > ( me.name = ? ) AND ( artistid = ? ) ) ): 'some other name', '1'
> > > >
> > > > As you can see it it did not ignore the 'name' column.
> > >
> > > So what you're basically saying is, if one or more of the columns for the
> > > key comes from the search condition already on the rs rather than find,
> > > it treats it as case 2 when it should treat it as case 1? (and presumably
> > > similarly where the key attr isn't supplied the case 4 code path is followed
> > > when case 3 should be)
> >
> > Yes.  The problem I see is that it might be not easy (or perhaps even
> > impossible) to find all columns used effectively in "the search
> > condition already on the rs".  I mean: if it is in a clause like {
> > 'some_col' => { '>', 100 } } then this is not enough - you need to
> > find conditions that really uniquely identify the value of the column.
> >
> > That's why I proposed to not check if it is case 1 or case 2 - but
> > just assume that the user knows what he is doing - and treat
> > everything as case 1. Or at least add a flag for that.
>
> Do you mean "ignore any column provided that isn't part of the key" ?
>
> That would probably achieve the aim, and not mess up search-as-restriction,
> and be a relatively minor change.
>

Yes - just ignore any column that is not part of the key in any case
and then return the first row returned by the query.  You can also
check if it exhausted the cursor (as you proposed in one of the
emails).  It would be nice to return 'undef' in the case 2 - but it
might be impossible to recognize if we are in 1 or 2. This is actually
very simple solution - and it amounts to removing the code for
checking if we are in 1 or 2 and adding to the documentation a
paragraph that find does what it is asked for and does not check the
query.

And once again why it might be impossible to recognize if we are in 2
- that is because the "the search condition already on the rs" can be
a complex Abstract::SQL structure.  You are right that the same can
happen in the main query, I did not think about it, because I was just
thinking about the find_or_create cases, but this only supports my
point even further.


-- 
Zbigniew Lukasiak
http://brudnopis.blogspot.com/



More information about the DBIx-Class mailing list