[Dbix-class] Problem with scalar ref when inserting complex objects

Matt S Trout dbix-class at trout.me.uk
Thu Feb 14 14:14:10 GMT 2008


On Wed, Feb 13, 2008 at 03:52:56PM -0200, Jose Fonseca wrote:
> Hi, this is my first message here, so first of all let me thank you all for
> creating DBIx::Class and for the support you all give here. I've been
> lurking for a while on the web transcriptions and learn tons from it. (And
> excuse me for the large message!).
> 
> SYNOPSIS
> The SELECT COUNT(*) queries which precede some complex object inserts is
> generated incorrectly when a scalar ref is passed as literal to be passed
> directly to the DB. This is a documented feature of SQL::Abstract but does
> not produce the expected behavior on DBIx::Class(or does it?).
> 
> In my case inserting a single CustomerLogin works fine, with the scalar ref
> and all.
> 
> BUT when inserting that exactly same CustomerLogin within a Customer, for
> example, with the following hashref
> 
> my $create_hash = {
> customer_name => "Obi Wan",
> customer_address => "I live here",
> logins => [
>     {
>        login => 'Obi',
>        membersince => \'NOW()'
>     }
> ]
> }
> 
> DBIx::Class does a count(*) from logins first with broken SQL as described
> below.
> 
> DESCRIPTION
> When you pass a ref scalar to a ResultSet()->create(), it correctly passes
> the value directly to the DB.
> 
> For instance when inserting a \'my string' it places 'my string' within the
> values() list, without a placeholder.  That is all fine, it's the documented
> SQL::Abstract behavior.
> 
> The problem happens when you give DBIx::Class a scalar ref for INSERTion but
> it does a count(*) before the INSERT. It then inserts the literal into the
> count(*) query's WHERE string without an operator. You inteded the literal
> only for an INSERT but DBIx::Class used it for a SELECT too.
> 
> EXAMPLE
> $SCHEMA->resultset('Base::Customer')->create({[.....SNIP...], mycolumn =>
> \'my string' });
> 
> DBIx::Class for some reason does something similar to a
> 
> $SCHEMA->resultset('Base::Customer')->search({ [.....SNIP...],  mycolumn =>
> \'my string' },{})->count();
> 
> which produces
> 
> SELECT COUNT( * ) FROM customers me WHERE ( [...sNIP...] *AND mycolumn 'my
> string'*  )

Bugger.

Can you backtrace it and find where it's making that query from? I'm betting
it's a numification of the resultset that's triggering the overload that
shouldn't be happening in the first place.

If that's true we can simply make it not do that query at all :)

-- 
      Matt S Trout       Need help with your Catalyst or DBIx::Class project?
   Technical Director                    http://www.shadowcat.co.uk/catalyst/
 Shadowcat Systems Ltd.  Want a managed development or deployment platform?
http://chainsawblues.vox.com/            http://www.shadowcat.co.uk/servers/



More information about the DBIx-Class mailing list