![]() | |
![]() |
| | Thread Tools | Display Modes |
#1
| |||
| |||
|
|
Field | Type | Null | Key | Default | Extra | |
|
id | int(11) | NO | PRI | NULL | auto_increment | employee | int(11) | YES | | NULL | customer | int(11) | YES | | NULL | shipping | int(11) | YES | | NULL | date | date | YES | | NULL | dispatch_date | date | YES | | NULL | vat | int(11) | YES | | NULL | discount | int(11) | YES | | NULL | paid | enum('yes','no') | YES | | no | valid | enum('yes','no') | YES | | no | invoiced | enum('yes','no') | YES | | no | shipped | enum('yes','no','part') | YES | | no | customer_order | char(32) | YES | | NULL | details | text | YES | | NULL | payment_reference | char(32) | YES | | NULL | shipping_method | char(64) | YES | | NULL | tracking_number | char(32) | YES | | NULL | +-------------------+-------------------------+------+-----+---------+----------------+ |
#2
| |||
| |||
|
|
Not quite sure what is going on here.. I have a test database running on 5.2.6-1 and production is on 5.2.0-8 A select that works on production breaks on test. The condition is for a field 'shipped' != 'yes' show fields in orders; +-------------------+-------------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------------+-------------------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | employee | int(11) | YES | | NULL | | | customer | int(11) | YES | | NULL | | | shipping | int(11) | YES | | NULL | | | date | date | YES | | NULL | | | dispatch_date | date | YES | | NULL | | | vat | int(11) | YES | | NULL | | | discount | int(11) | YES | | NULL | | | paid | enum('yes','no') | YES | | no | | | valid | enum('yes','no') | YES | | no | | | invoiced | enum('yes','no') | YES | | no | | | shipped | enum('yes','no','part') | YES | | no | | | customer_order | char(32) | YES | | NULL | | | details | text | YES | | NULL | | | payment_reference | char(32) | YES | | NULL | | | shipping_method | char(64) | YES | | NULL | | | tracking_number | char(32) | YES | | NULL | | +-------------------+-------------------------+------+-----+---------+----------------+ Now if this enumerated field is NULL, which it is if it hasn't been explicitly set, production accepts that is a match for "!='yes'" whereas test does not. Is this me, a bug or what? i.e. the simple test select * from orders where shipped !='yes' ; produces a different result on the two machines. With identical data. Obviously there are ways around this. Its trivial to fix the code, but I want to know why its happening. Further to this, I have fixed the problem by disallowing nulls...in the |
#3
| |||
| |||
|
|
The Natural Philosopher wrote: Not quite sure what is going on here.. I have a test database running on 5.2.6-1 and production is on 5.2.0-8 A select that works on production breaks on test. The condition is for a field 'shipped' != 'yes' show fields in orders; +-------------------+-------------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------------+-------------------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | employee | int(11) | YES | | NULL | | | customer | int(11) | YES | | NULL | | | shipping | int(11) | YES | | NULL | | | date | date | YES | | NULL | | | dispatch_date | date | YES | | NULL | | | vat | int(11) | YES | | NULL | | | discount | int(11) | YES | | NULL | | | paid | enum('yes','no') | YES | | no | | | valid | enum('yes','no') | YES | | no | | | invoiced | enum('yes','no') | YES | | no | | | shipped | enum('yes','no','part') | YES | | no | | | customer_order | char(32) | YES | | NULL | | | details | text | YES | | NULL | | | payment_reference | char(32) | YES | | NULL | | | shipping_method | char(64) | YES | | NULL | | | tracking_number | char(32) | YES | | NULL | | +-------------------+-------------------------+------+-----+---------+----------------+ Now if this enumerated field is NULL, which it is if it hasn't been explicitly set, production accepts that is a match for "!='yes'" whereas test does not. Is this me, a bug or what? i.e. the simple test select * from orders where shipped !='yes' ; produces a different result on the two machines. With identical data. Obviously there are ways around this. Its trivial to fix the code, but I want to know why its happening. Further to this, I have fixed the problem by disallowing nulls...in the field... but the question still arises as to why.. |
#4
| |||
| |||
|
|
If you accept NULL in a YES/NO type column (i.e., if you want to implement tri-state logic) then you need to explicitly test for NOT NULL before doing any Boolean comparisons. |
#5
| |||
| |||
|
|
The Natural Philosopher wrote: The Natural Philosopher wrote: Not quite sure what is going on here.. I have a test database running on 5.2.6-1 and production is on 5.2.0-8 A select that works on production breaks on test. The condition is for a field 'shipped' != 'yes' show fields in orders; +-------------------+-------------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------------+-------------------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | employee | int(11) | YES | | NULL | | | customer | int(11) | YES | | NULL | | | shipping | int(11) | YES | | NULL | | | date | date | YES | | NULL | | | dispatch_date | date | YES | | NULL | | | vat | int(11) | YES | | NULL | | | discount | int(11) | YES | | NULL | | | paid | enum('yes','no') | YES | | no | | | valid | enum('yes','no') | YES | | no | | | invoiced | enum('yes','no') | YES | | no | | | shipped | enum('yes','no','part') | YES | | no | | | customer_order | char(32) | YES | | NULL | | | details | text | YES | | NULL | | | payment_reference | char(32) | YES | | NULL | | | shipping_method | char(64) | YES | | NULL | | | tracking_number | char(32) | YES | | NULL | | +-------------------+-------------------------+------+-----+---------+----------------+ Now if this enumerated field is NULL, which it is if it hasn't been explicitly set, production accepts that is a match for "!='yes'" whereas test does not. Is this me, a bug or what? i.e. the simple test select * from orders where shipped !='yes' ; produces a different result on the two machines. With identical data. Obviously there are ways around this. Its trivial to fix the code, but I want to know why its happening. Further to this, I have fixed the problem by disallowing nulls...in the field... but the question still arises as to why.. I can't say why one system gives you different answers than the other, but the production system is behaving correctly. ANY Boolean comparison where one (or both) of the operands is NULL should return false -- I believe that is the expected (ANSI?) behavior. |
|
If you accept NULL in a YES/NO type column (i.e., if you want to implement tri-state logic) then you need to explicitly test for NOT NULL before doing any Boolean comparisons. |
#6
| |||
| |||
|
|
Robert Hairgrove wrote: The Natural Philosopher wrote: The Natural Philosopher wrote: Not quite sure what is going on here.. I have a test database running on 5.2.6-1 and production is on 5.2.0-8 A select that works on production breaks on test. The condition is for a field 'shipped' != 'yes' show fields in orders; +-------------------+-------------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------------+-------------------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | employee | int(11) | YES | | NULL | | | customer | int(11) | YES | | NULL | | | shipping | int(11) | YES | | NULL | | | date | date | YES | | NULL | | | dispatch_date | date | YES | | NULL | | | vat | int(11) | YES | | NULL | | | discount | int(11) | YES | | NULL | | | paid | enum('yes','no') | YES | | no | | | valid | enum('yes','no') | YES | | no | | | invoiced | enum('yes','no') | YES | | no | | | shipped | enum('yes','no','part') | YES | | no | | | customer_order | char(32) | YES | | NULL | | | details | text | YES | | NULL | | | payment_reference | char(32) | YES | | NULL | | | shipping_method | char(64) | YES | | NULL | | | tracking_number | char(32) | YES | | NULL | | +-------------------+-------------------------+------+-----+---------+----------------+ Now if this enumerated field is NULL, which it is if it hasn't been explicitly set, production accepts that is a match for "!='yes'" whereas test does not. Is this me, a bug or what? i.e. the simple test select * from orders where shipped !='yes' ; produces a different result on the two machines. With identical data. Obviously there are ways around this. Its trivial to fix the code, but I want to know why its happening. Further to this, I have fixed the problem by disallowing nulls...in the field... but the question still arises as to why.. I can't say why one system gives you different answers than the other, but the production system is behaving correctly. ANY Boolean comparison where one (or both) of the operands is NULL should return false -- I believe that is the expected (ANSI?) behavior. FALSE in a comparison for, or against? I went in at pure mysql level to delve into this: no other software involved.. Definitely one version behaves differently from the other. If you accept NULL in a YES/NO type column (i.e., if you want to implement tri-state logic) then you need to explicitly test for NOT NULL before doing any Boolean comparisons. It gets worse actually. I set explicit defaults to 'no' and it doesn't actually set the enum value to 'no'. Instead of null, it simply returns a blank field. So my enumerated field can take on values NULL and '' as well as the three enumerated values. |
#7
| |||
| |||
|
|
Robert Hairgrove wrote: If you accept NULL in a YES/NO type column (i.e., if you want to implement tri-state logic) then you need to explicitly test for NOT NULL before doing any Boolean comparisons. Actually, I just re-read your OP and saw that this column can also have other values 'part' ... you should definitely keep NULLs out of this column, IMHO -- especially since you have a default value of 'no'. |
#8
| |||
| |||
|
|
Op 4-3-2010 12:45, The Natural Philosopher schreef: Robert Hairgrove wrote: The Natural Philosopher wrote: The Natural Philosopher wrote: Not quite sure what is going on here.. I have a test database running on 5.2.6-1 and production is on 5.2.0-8 A select that works on production breaks on test. The condition is for a field 'shipped' != 'yes' show fields in orders; +-------------------+-------------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------------+-------------------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | employee | int(11) | YES | | NULL | | | customer | int(11) | YES | | NULL | | | shipping | int(11) | YES | | NULL | | | date | date | YES | | NULL | | | dispatch_date | date | YES | | NULL | | | vat | int(11) | YES | | NULL | | | discount | int(11) | YES | | NULL | | | paid | enum('yes','no') | YES | | no | | | valid | enum('yes','no') | YES | | no | | | invoiced | enum('yes','no') | YES | | no | | | shipped | enum('yes','no','part') | YES | | no | | | customer_order | char(32) | YES | | NULL | | | details | text | YES | | NULL | | | payment_reference | char(32) | YES | | NULL | | | shipping_method | char(64) | YES | | NULL | | | tracking_number | char(32) | YES | | NULL | | +-------------------+-------------------------+------+-----+---------+----------------+ Now if this enumerated field is NULL, which it is if it hasn't been explicitly set, production accepts that is a match for "!='yes'" whereas test does not. Is this me, a bug or what? i.e. the simple test select * from orders where shipped !='yes' ; produces a different result on the two machines. With identical data. Obviously there are ways around this. Its trivial to fix the code, but I want to know why its happening. Further to this, I have fixed the problem by disallowing nulls...in the field... but the question still arises as to why.. I can't say why one system gives you different answers than the other, but the production system is behaving correctly. ANY Boolean comparison where one (or both) of the operands is NULL should return false -- I believe that is the expected (ANSI?) behavior. FALSE in a comparison for, or against? I went in at pure mysql level to delve into this: no other software involved.. Definitely one version behaves differently from the other. If you accept NULL in a YES/NO type column (i.e., if you want to implement tri-state logic) then you need to explicitly test for NOT NULL before doing any Boolean comparisons. It gets worse actually. I set explicit defaults to 'no' and it doesn't actually set the enum value to 'no'. Instead of null, it simply returns a blank field. So my enumerated field can take on values NULL and '' as well as the three enumerated values. but that is documented (http://dev.mysql.com/doc/refman/5.1/en/enum.html) For example, a column specified as ENUM('one', 'two', 'three') can have any of the values shown here. The index of each value is also shown. Value Index NULL NULL '' 0 'one' 1 'two' 2 'three' 3 There's also something about default values of an enum-field there, did you check if SELECT 0+shipped FROM table gives same values on test and production? Thanks Luuk, I found that as well. |
|
test | +------+ NULL | +------+ |
#9
| |||
| |||
|
|
Robert Hairgrove wrote: Robert Hairgrove wrote: If you accept NULL in a YES/NO type column (i.e., if you want to implement tri-state logic) then you need to explicitly test for NOT NULL before doing any Boolean comparisons. Actually, I just re-read your OP and saw that this column can also have other values 'part' ... you should definitely keep NULLs out of this column, IMHO -- especially since you have a default value of 'no'. As a side remark, it would really be nice if MySQL implemented enforced CHECK constraints ... since it does not, you might want to keep the admissible values for the "shipped" column in a separate table and have a foreign key constraint. Better than enum, IMHO... |
#10
| ||||
| ||||
|
|
Ok. this gets even stranger.. BOTH systems return the following.. mysql> select (NULL !='yes') as test; +------+ | test | +------+ | NULL | +------+ The question is, is NULL true, or false!! |
|
It gets more confusing, because both data bases return the same thing in the case of: select id from orders where (NULL!='yes') |
|
BUT completely different sets when I use any of the enumerated fields viz. select id from orders where paid !='yes'; |
|
I have disallowed nulls in all enumerated fields now, since their behaviours in this comparison seems 'undefined' |
![]() |
| Thread Tools | |
| Display Modes | |
| |