5

I just noticed, that propel converts numeric values to strings in generated setter methods. My problem with that is, since I am using german locale, float values are insert with a comma instead of a dot. For example: "3.5" results in a string "3,5". I am using PostgreSQL, which obviously expects 3.5.

Version info: In case it is relevant, I am using: PHP 5.3.9, Propel 1.6 with Symfony 2.2.

Details:

The table definition looks like this:

<table name="account_entry">
    ...
    <column name="amount" type="decimal" size="12" scale="2" required="true" />
    ...
</table>

The generated setAmount() method looks like this:

public function setAmount($v)
{
    if ($v !== null && is_numeric($v)) {
        $v = (string) $v;
    }

    if ($this->amount !== $v) {
        $this->amount = $v;
        $this->modifiedColumns[] = AccountEntryPeer::AMOUNT;
    }


    return $this;
} // setAmount()

Saving the object results in a PostgreSQL error:

Invalid text representation: 7 ERROR: invalid input syntax for type numeric: "3,5"

It took me a while to find the place where this conversion happens. As you can see the float value is being casted to string in setAmount(). Up to now I have never noticed that casting a float value to string results in a string containing a locale specific decimal separator.

I wonder why propel converts a float value into a string in the first place? Is there some workaround for this?

The only workaround I came up with is really ugly and annoying:

setlocale(LC_ALL, 'en_US');
$ae->setAmount(3.5);
setlocale(LC_ALL, 'de_DE');
Leif
  • 1,076
  • 10
  • 16
  • It seems that it is [the *default* behavior](https://github.com/propelorm/Propel/blob/master/generator/lib/builder/om/PHP5ObjectBuilder.php#L1844-1873) to handle column. But according to the way the SQL is generated (to insert for example), [it seems](https://github.com/propelorm/Propel/blob/master/generator/lib/builder/sql/DataSQLBuilder.php#L172-180) that it should be casted *again* to match the native column type. You might check [issue on Github](https://github.com/propelorm/Propel/issues) and/or submit one – j0k Mar 26 '13 at 08:57
  • Thanks for your research. I posted the question on the propel mailing list. I want to avoid creating bug reports, if it might not be a bug. – Leif Mar 26 '13 at 09:44

1 Answers1

5

The problem is that Propel converts the PHP field that relates to that column into a native PHP type in the setter (as @j0k mentions), but if you look a little deeper you see the issue. In the PropelTypes.php helper class, on line 76 you can see that the native PHP type for "decimal" is listed as "string".

Compare this to the "float" native type which is listed as "double". I'm not sure if this is intentional or not, but in any case, your issue may be solved by simply switching the column to type="float" or type="double".

Propel should convert that into whatever type your DBMS requires.

j0k
  • 22,600
  • 28
  • 79
  • 90
Jordan Kasper
  • 13,153
  • 3
  • 36
  • 55
  • Thanks! Changing the type from decimal to double does indeed solve my problem. I still consider it a workaround though, because PostgreSQL uses double as type now and not decimal(x,y). But this is fine for my case. – Leif Mar 26 '13 at 17:06
  • Glad it worked. I'm honestly not sure why the core Propel folks would have defaulted the native type to "string", but maybe it makes sense for some DBMS's. – Jordan Kasper Mar 26 '13 at 18:19
  • 3
    It's because the DECIMAL field in databases is precise, while the native floating point handling on the CPU is not. Thus Propel plays it safe by returning the exact value in a string, and letting you worry about arithmetic and storage. See f.e. [link](http://msdn.microsoft.com/en-us/library/c151dt3s%28v=vs.80%29.aspx) – untitled8468927 May 30 '13 at 11:36