Issue Details (XML | Word | Printable)

Key: MDL-20734
Type: Sub-task Sub-task
Status: Resolved Resolved
Resolution: Fixed
Priority: Minor Minor
Assignee: Eloy Lafuente (stronk7)
Reporter: Eloy Lafuente (stronk7)
Votes: 1
Watchers: 1
Operations

Add/Edit UI Mockup to this issue
If you were logged in you would be able to see more operations.
Moodle
MDL-14679

insert/update/set_field expected behaviour is to cast empty string to 0 for numeric columns

Created: 04/Nov/09 03:52 AM   Updated: 04/Nov/09 09:19 PM
Return to search
Component/s: Database SQL/XMLDB
Affects Version/s: 2.0
Fix Version/s: 2.0

Database: MySQL, PostgreSQL, Microsoft SQL, Oracle
Participants: David Mudrak, Eloy Lafuente (stronk7) and Petr Skoda
Security Level: None
QA Assignee: Petr Skoda
Resolved date: 04/Nov/09
Affected Branches: MOODLE_20_STABLE
Fixed Branches: MOODLE_20_STABLE


 Description  « Hide
Expected behaviour to get cross-db support is to automatically cast empty strings to 0 in the following functions:

- insert_record
- update_record
- set_field

Rationale: DBs are idiot:

- MSSQL allows empties on int fields and saves them as 0, but not in decimal fields no matter of the nullability of the field)
- Oracle allows empties on int fields and saves them as NULL and only in NOT NULL fields. Same for decimal fields.
- MySQL doesn't allow empties in int/decimal fields (strict mode). Error.
- PG doesn't allow empties in int/decimal fields). Error.

So I guess we only can move to the "perform casting" alternative. Is the only that will work cross-db. The other (not perform casting) won't work as far as MSSQL and Oracle sometimes accept those empty strings.

 All   Comments   Change History   Version Control      Sort Order: Ascending order - Click to sort in descending order
Eloy Lafuente (stronk7) committed 1 file to 'Moodle CVS' - 04/Nov/09 03:53 AM
MDL-20734 Changed tests behaviour so insert/update/set_field will be expected to cast
empty strings (in numeric columns) to 0
MODIFY lib/dml/simpletest/testdml.php   Rev. 1.60    (+28 -39 lines)
Eloy Lafuente (stronk7) added a comment - 04/Nov/09 03:54 AM
Test now are checking the expected behaviour (cast empty to 0). These need fix:

MySQL: insert/update/set_field
PostgreSQL: set_field

coming soon...ciao


Eloy Lafuente (stronk7) made changes - 04/Nov/09 03:55 AM
Field Original Value New Value
Summary insert/update/set_field expected behaviour is to cast empty string to 0 insert/update/set_field expected behaviour is to cast empty string to 0 for numeric columns
Eloy Lafuente (stronk7) committed 2 files to 'Moodle CVS' - 04/Nov/09 07:34 AM
MDL-20734 empties and zeros - implemented the normalise_value() function in
mysql and postgres to perform central normalisation of values for insert/
update/set_field. Now all DB drivers cast empty strings to 0 when working
with numeric columns (integer and decimal)
MODIFY lib/dml/pgsql_native_moodle_database.php   Rev. 1.43    (+42 -44 lines)
MODIFY lib/dml/mysqli_native_moodle_database.php   Rev. 1.45    (+40 -23 lines)
Eloy Lafuente (stronk7) added a comment - 04/Nov/09 07:40 AM
Done,

implemented the normalise_value() function in mysql and postgresql drives (was already in mssql and oracle) that performs all the default "normalisation" like casting empty strings to cero when working with numeric columns.

Tests passing now.

Resolving as fixed.

Petr, my only concern is if we should, in moodle_database.php:

/**
     * Normalise values based in RDBMS dependencies (booleans, LOBs...)
     *
     * @param database_column_info $column column metadata corresponding with the value we are going to normalise
     * @param mixed $value value we are going to normalise
     * @return mixed the normalised value
     */
    private abstract function normalise_value($column, $value);

in order to "force" drivers implementators to have such good habit.

Ciao


Eloy Lafuente (stronk7) made changes - 04/Nov/09 07:40 AM
Status Open [ 1 ] Resolved [ 5 ]
Resolution Fixed [ 1 ]
QA Assignee skodak
Petr Skoda added a comment - 04/Nov/09 05:22 PM
you mean "protected abstract" right? +10 for that

Eloy Lafuente (stronk7) added a comment - 04/Nov/09 06:07 PM
ah, I was thinking really "private", cannot that be done?

Petr Skoda added a comment - 04/Nov/09 06:10 PM - edited
private + abstract? looks weird, I doubt you would be able to call it from moodel_database if defined in native drivers. What other use would it have?

I did not test it, it might actually work in this weird PHP OOP model


Eloy Lafuente (stronk7) added a comment - 04/Nov/09 06:30 PM
private + abstract means that ANY DB driver must implement it and only can be used by it. That's what I was exactly trying to do. And has sense. IMO.

If we do it protected that means that potential childs will be able to use it, but are we going to have childs of native drivers? I don't think so.


David Mudrak added a comment - 04/Nov/09 06:40 PM
I do not know if it applies here too but usually I saw protected instead of private for the UnitTesting purposes - ie if you need to have a testable subclass of the native driver. I suppose the DB testing scheme may be different though.

Eloy Lafuente (stronk7) added a comment - 04/Nov/09 07:00 PM
I don't think unit testing is the key here. We aren't going to have one test_normalise_value() function at all, because it will be covered by all the insert/update/set_field tests instead.

Petr Skoda added a comment - 04/Nov/09 07:05 PM
I do not like forcing people to define something private in drivers - private measn do it in any way you like which imo includes not use nay function for that at all

Eloy Lafuente (stronk7) added a comment - 04/Nov/09 09:03 PM
That's a good point, oki, declaring it as protected abstract. Ciao

Eloy Lafuente (stronk7) committed 7 files to 'Moodle CVS' - 04/Nov/09 09:19 PM
MDL-20734 normalise_value() - moving from private to protected everywhere and abstracting
MODIFY lib/dml/pgsql_native_moodle_database.php   Rev. 1.44    (+1 -1 lines)
MODIFY lib/dml/oci_native_moodle_database.php   Rev. 1.31    (+1 -1 lines)
MODIFY lib/dml/sqlite3_pdo_moodle_database.php   Rev. 1.17    (+11 -0 lines)
MODIFY lib/dml/moodle_database.php   Rev. 1.105    (+9 -0 lines)
MODIFY lib/dml/simpletest/testdml.php   Rev. 1.61    (+1 -0 lines)
MODIFY lib/dml/mssql_native_moodle_database.php   Rev. 1.13    (+1 -1 lines)
MODIFY lib/dml/mysqli_native_moodle_database.php   Rev. 1.46    (+1 -1 lines)
Eloy Lafuente (stronk7) added a comment - 04/Nov/09 09:19 PM
Done!