The module is broken under PostgreSQL. The reason is that it contains code that compares date types with integer types using non SQL99-compliant implicit casting. See for example http://drupal.org/node/555536 and http://www.postgresql.org/docs/8.3/static/release-8-3.html (E.12.2.1). This results in errors like the following:
warning: pg_query() [function.pg-query]: Query failed: ERROR: operator does not exist: date >= integer LINE 6: FROM statspro WHERE day >= 20100731 ^ HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. in /var/www/drupal/includes/database.pgsql.inc on line 139.
user warning: query: SELECT day, nuser, auser, nnode, cnode, comment, pi, upi, error, uerror, warning, uwarning, emergency, uemergency, alert, ualert, critical, ucritical FROM statspro WHERE day >= 20100731 in /var/www/drupal/sites/all/modules/statspro/statspro.inc on line 193.
Please fix this!
| Comment | File | Size | Author |
|---|---|---|---|
| #9 | statspro-inc-897438-9.patch | 9.79 KB | lifepillar |
| #4 | statspro-inc-897438-4.patch | 10.23 KB | lifepillar |
Comments
Comment #1
rsevero commentedFirst of all let me thank you for the bug report.
Unfortunately I won't be able to pay the adequate attention to it now as I'm really overloaded.
As a way to speed things up, do you know exactly what changes would be necessary in the SQL for PostgreSQL? If you could send me a corrected version of the SQL it would be really helpful.
Comment #2
lifepillar commentedAs a way to speed things up, do you know exactly what changes would be necessary in the SQL for PostgreSQL?
Unfortunately, no. I know that casting issues are problematic to tackle in an cross-DBMS way. The best would be revising the design to avoid casts entirely, but I guess that this would be too much work.
The module generates many where clauses using the
'%s >= %u'pattern. I know that enclosing the integer between single quotes (that is,'%s >= \'%u\') would work in both MySQL and PostgreSQL. I have tried to make such changes, but I still get query errors (or, maybe, I have generated different errors). I will try to look into the code further (I'd really need the module to work), but I cannot guarantee a patch.Comment #3
rsevero commentedSee what you can do.
If you manage to produce a working SQL command (both in MySQL and PostgreSQL) it would be great. This way I could make the patch.
Comment #4
lifepillar commentedEventually, it was not too difficult to circumvent implicit casts: I just had to add more checks based on the value of $use_timestamp. Attached you find a patch, which I have tested with PostgreSQL 8.4 and it works for me. I have not tested it with MySQL, but I see no reason why it shouldn't work there as well.
In a couple of places, I have also changed dates of the form YYYY-MM-00 to YYYY-MM-01, because the former is not a valid date value in PostgreSQL. I have no idea whether this change would cause wrong ranges to be generated.
Comment #5
rsevero commentedThanks for the patch. It will be of great help.
The first thing that attracted my attention is the places were you changed YYYY-MM-00 to YYYY-MM-01. In my quick look, YYYY-MM-00 was used as a parameter to strtotime. It produces a timestamp with which a parameter for SQL is created. It's not a parameter used directly in SQL so I believe this shouldn't be a problem for PostgreSQL.
I also believe these specific changes will produce wrong ranges.
Have the use of YYYY-MM-00 generated errors for you?
Comment #6
lifepillar commentedNo, I did not get errors: that was precautionary :)
I do not understand the logic of
get_last_day_of_*functions, actually. Say,get_last_day_of_month_from_referencecontains the following conditional:As far as I can see, if
$use_timestampis false, that function returns a date in YYYYMMDD format. The latter is obtained by converting the $last timestamp, which, unless the month is December, has been obtained from a string YYYY-MM-00. Wouldn't this result in an invalid date? Or am I missing something?Comment #7
rsevero commentedThe catch is the use of "strtotime". It supports some rather exotic syntaxs and options that I took advantage of. Take a look at http://www.php.net/manual/en/datetime.formats.date.php
Comment #8
lifepillar commentedAh, ok, date(strtotime('YYYY-MM-00')) yields a correct date. I agree, then, that there is no need to change the day to 01.
Comment #9
lifepillar commentedHere is the updated patch.
Comment #10
rsevero commentedApplied with http://drupal.org/cvs?commit=442696.
Thanks for your help and sorry for the long delay.