[Dbix-class] The consequences of undefined behaviour in find

Zbigniew Lukasiak zzbbyy at gmail.com
Thu Jan 24 07:53:08 GMT 2008


This started with me trying to add some new features to create - they
were rejected because I was using update_or_create and it does not
always work, so I went and tried to fix update_or_create and I found
out that this bug is a result of two things:

1. that you need to delete the primary key when you have them
undefined and try to insert the row in PostgreSQL
2. that when you delete the pk instead of leaving it undef then find
will not work as advertised

My plead to a workaround for 1) - by simply deleting the PK in the Pg
storage driver was rejected so those that use PostgreSQL are forced to
live with the consequences of using find with the PK deleted.

First about the nature of the problem. When called on a ResultSet
object find tries to determine if the query it receives and the
internal conditions of the ResultSet object do include at least one
full unique constraint (for example a primary key). But it is not
always possible to do that. Let me quote from one of the core
developers about that problem:

> Of course you can't always determine. But if you don't know, then you default
> to "no it doesn't produce a unique row" and provide some way for the user to
> say "actually I know it does and I accept you can't help me if I'm wrong" :)

The following methods use find and will silently create a new row
instead of using an existing one in that case

update_or_create

update_or_create_related

find_or_create

find_or_create_related

find_or_new

find_or_new_related

This is even further complicated by the fact that the current
implementation does not do exactly what is quoted above - it tries to
'guess' what row should be returned - and that means that sometimes it
has the opposite result: the above mentioned functions will silently
update or find an existing row instead of creating a new one.


The consequence of that is that you should not use these methods in
libraries where you cannot say "actually I know it does and I accept
you can't help me if I'm wrong" because you don't know what ResultSet
and query you receive.

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



More information about the DBIx-Class mailing list