Bug #42980 Client doesn't set NUM_FLAG for DECIMAL

Submitted: 18 Feb 2009 17:09 Modified: 12 Nov 2009 20:59
Reporter: Andrey Hristov Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Data Types Severity:S2 (Serious)
Version:5.1.30, 5.0.79-bzr, 6.0 OS:Any
Assigned to: Guilhem Bichot CPU Architecture:Any

[18 Feb 2009 17:09] Andrey Hristov
Description:
DECIMAL is listed as a numeric type but the metadata sent by the server doesn't mark it as such with NUM_FLAG. UNSIGNED_FLAG is however set, depending on the field. All other numeric types have NUM_FLAG set. Be sure to start you command line client with --column-type-info . And be sure it is 5.1, because 5.0's client doesn't support this option.
Can be checked with (that all other numeric types have NUM_FLAG set)

create table manycols(tiny tinyint, tiny_uns tinyint unsigned, small smallint, small_uns smallint unsigned, medium mediumint, medium_uns mediumint unsigned, int_col int, int_col_uns int unsigned, big bigint, big_uns bigint unsigned, decimal_col decimal(10,5), decimal_col_uns decimal(10,5) unsigned, fcol float, fcol_uns float unsigned, dcol double, dcol_uns double unsigned, date_col date, time_col time, timestamp_col timestamp, year_col year, bit_col bit(5),  char_col char(5), varchar_col varchar(10), binary_col binary(10), varbinary_col varbinary(10), tinyblob_col tinyblob, blob_col blob, mediumblob_col mediumblob, longblob_col longblob, text_col text, mediumtext_col mediumtext, longtext_col longtext);
select * from manycols;

How to repeat:
+--------------+
| version()    |
+--------------+
| 5.1.31-debug |
+--------------+
1 row in set (0.00 sec)

mysql> create table t1(dec_f decimal(10,5), dec_f_uns decimal(10,5) unsigned);
Query OK, 0 rows affected (0.00 sec)

mysql> select * from t1;
Field   1:  `dec_f`
Catalog:    `def`
Database:   `test`
Table:      `t1`
Org_table:  `t1`
Type:       NEWDECIMAL
Collation:  binary (63)
Length:     12
Max_length: 0
Decimals:   5
Flags:

Field   2:  `dec_f_uns`
Catalog:    `def`
Database:   `test`
Table:      `t1`
Org_table:  `t1`
Type:       NEWDECIMAL
Collation:  binary (63)
Length:     11
Max_length: 0
Decimals:   5
Flags:      UNSIGNED

0 rows in set (0.00 sec)

Suggested fix:
Send NUM_FLAG for DECIMAL columns
[18 Feb 2009 17:42] MySQL Verification Team
Thank you for the bug report. Verified as described:

c:\dbs>5.0\bin\mysql --port=3500 -T -uroot test
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.0.79-Win x86-64 bzr revno:2741-log Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> create table t1(dec_f decimal(10,5), dec_f_uns decimal(10,5) unsigned);
Query OK, 0 rows affected (0.06 sec)

mysql> select * from t1;
Field   1:  `dec_f`
Catalog:    `def`
Database:   `test`
Table:      `t1`
Org_table:  `t1`
Type:       NEWDECIMAL
Collation:  binary (63)
Length:     12
Max_length: 0
Decimals:   5
Flags:

Field   2:  `dec_f_uns`
Catalog:    `def`
Database:   `test`
Table:      `t1`
Org_table:  `t1`
Type:       NEWDECIMAL
Collation:  binary (63)
Length:     11
Max_length: 0
Decimals:   5
Flags:      UNSIGNED

0 rows in set (0.01 sec)

mysql>
[28 Aug 2009 13:51] Guilhem Bichot
I found out that it's not the Server who sends or has to send this piece of information, it's the client which is expected to find out: the buggy code is in sql-common/client.c.
[28 Aug 2009 15:18] Guilhem Bichot
According to the manul, NUM_FLAG should be set for TIMESTAMP too:
http://dev.mysql.com/doc/refman/5.4/en/c-api-datatypes.html
"NUM_FLAG indicates that a column is numeric. This includes columns with a type of MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY, MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG, MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE, MYSQL_TYPE_NULL, MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_LONGLONG, MYSQL_TYPE_INT24, and MYSQL_TYPE_YEAR."
[29 Aug 2009 17:18] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/81933

2876 Guilhem Bichot	2009-08-29
      Fix for BUG#42980 "Client doesn't set NUM_FLAG for DECIMAL and TIMESTAMP":
      DECIMAL and TIMESTAMP used to have NUM_FLAG, but NEWDECIMAL was forgotten.
      It's correct that TIMESTAMP does not have the flag nowadays (manual will be updated, connectors
      developers will be notified).
     @ client/mysqldump.c
        IS_NUM_FIELD(f) removed and replaced by its definition (f>flags & NUM_FLAG).
     @ include/mysql.h
        - IS_NUM_FIELD() is removed because name is too close to IS_NUM() and it is not used a lot
        - INTERNAL_NUM_FIELD() is removed:
          * it forgets to test NEWDECIMAL (when IS_NUM() was updated for NEWDECIMAL we forgot
          to update INTERNAL_NUM_FIELD()), that's why client didn't mark NEWDECIMAL with NUM_FLAG (a bug).
          * it has an obsolete test for length of the TIMESTAMP field: test became accidentally wrong when length
          of TIMESTAMP was changed to always be 19 (when the format was changed from YYYYMMDDhhmmss to
          YYYY-MM-DD hh:mm:ss), never 8 or 14 anymore. That obsolete test caused TIMESTAMP to lose NUM_FLAG,
          which was an accidental but good change (see below).
          * IS_NUM() should be used instead
        - IS_NUM(f) is changed: TIMESTAMP used to be parsable as a number without quotes (when it was formatted as
        "YYYYMMDDhhmmss"); but it is not anymore (now that it is "YYYY-MM-DD hh:mm:ss"), so it should not have NUM_FLAG
        (mysqldump needs to quote TIMESTAMP values), so IS_NUM() should return false for it.
     @ libmysqld/lib_sql.cc
        use IS_NUM() instead of INTERNAL_NUM_FIELD()
     @ mysql-test/r/bigint.result
        result change: NEWDECIMAL fields now have NUM_FLAG (32768)
     @ mysql-test/r/metadata.result
        result change: NEWDECIMAL fields now have NUM_FLAG (32768)
     @ mysql-test/r/mysqldump.result
        DECIMAL columns are not quoted anymore by mysqldump. Which is ok, the parser does not need '' for them
     @ mysql-test/r/ps_2myisam.result
        result change: NEWDECIMAL fields now have NUM_FLAG (32768)
     @ mysql-test/r/ps_3innodb.result
        result change: NEWDECIMAL fields now have NUM_FLAG (32768)
     @ mysql-test/r/ps_4heap.result
        result change: NEWDECIMAL fields now have NUM_FLAG (32768)
     @ mysql-test/r/ps_5merge.result
        result change: NEWDECIMAL fields now have NUM_FLAG (32768)
     @ mysql-test/suite/ndb/r/ps_7ndb.result
        result change: NEWDECIMAL fields now have NUM_FLAG (32768)
     @ mysql-test/t/metadata.test
        test for BUG#42980
     @ sql-common/client.c
        use IS_NUM() instead of INTERNAL_NUM_FIELD()
[30 Sep 2009 10:44] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/85183

2880 Guilhem Bichot	2009-09-30
      Fix for BUG#42980 "Client doesn't set NUM_FLAG for DECIMAL and TIMESTAMP":
      DECIMAL and TIMESTAMP used to have NUM_FLAG, but NEWDECIMAL was forgotten.
      It's correct that TIMESTAMP does not have the flag nowadays (manual will be updated, connectors
      developers will be notified).
     @ client/mysqldump.c
        IS_NUM_FIELD(f) removed and replaced by its definition (f>flags & NUM_FLAG).
     @ include/mysql.h
        - IS_NUM_FIELD() is removed because name is too close to IS_NUM() and it is not used a lot
        - INTERNAL_NUM_FIELD() is removed:
          * it forgets to test NEWDECIMAL (when IS_NUM() was updated for NEWDECIMAL we forgot
          to update INTERNAL_NUM_FIELD()), that's why client didn't mark NEWDECIMAL with NUM_FLAG (a bug).
          * it has an obsolete test for length of the TIMESTAMP field: test became accidentally wrong when length
          of TIMESTAMP was changed to always be 19 (when the format was changed from YYYYMMDDhhmmss to
          YYYY-MM-DD hh:mm:ss), never 8 or 14 anymore. That obsolete test caused TIMESTAMP to lose NUM_FLAG,
          which was an accidental but good change (see below).
          * IS_NUM() should be used instead
        - IS_NUM(f) is changed: TIMESTAMP used to be parsable as a number without quotes (when it was formatted as
        "YYYYMMDDhhmmss"); but it is not anymore (now that it is "YYYY-MM-DD hh:mm:ss"), so it should not have NUM_FLAG
        (mysqldump needs to quote TIMESTAMP values), so IS_NUM() should return false for it.
     @ libmysqld/lib_sql.cc
        use IS_NUM() instead of INTERNAL_NUM_FIELD()
     @ mysql-test/r/bigint.result
        result change: NEWDECIMAL fields now have NUM_FLAG (32768)
     @ mysql-test/r/metadata.result
        result change: NEWDECIMAL fields now have NUM_FLAG (32768)
     @ mysql-test/r/mysqldump.result
        DECIMAL columns are not quoted anymore by mysqldump. Which is ok, the parser does not need '' for them
     @ mysql-test/r/ps_2myisam.result
        result change: NEWDECIMAL fields now have NUM_FLAG (32768)
     @ mysql-test/r/ps_3innodb.result
        result change: NEWDECIMAL fields now have NUM_FLAG (32768)
     @ mysql-test/r/ps_4heap.result
        result change: NEWDECIMAL fields now have NUM_FLAG (32768)
     @ mysql-test/r/ps_5merge.result
        result change: NEWDECIMAL fields now have NUM_FLAG (32768)
     @ mysql-test/suite/ndb/r/ps_7ndb.result
        result change: NEWDECIMAL fields now have NUM_FLAG (32768)
     @ mysql-test/t/metadata.test
        test for BUG#42980
     @ sql-common/client.c
        use IS_NUM() instead of INTERNAL_NUM_FIELD()
[30 Sep 2009 12:05] Guilhem Bichot
queued to mysql-next-mr-bugfixing.

Doc info:

1) According to the manul, NUM_FLAG should be set for TIMESTAMP:
http://dev.mysql.com/doc/refman/5.4/en/c-api-datatypes.html
"NUM_FLAG indicates that a column is numeric. This includes columns with a type of
MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY, MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG, MYSQL_TYPE_FLOAT,
MYSQL_TYPE_DOUBLE, MYSQL_TYPE_NULL, MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_LONGLONG,
MYSQL_TYPE_INT24, and MYSQL_TYPE_YEAR."
But this is wrong:
1a) in fact TIMESTAMP lost NUM_FLAG when it was changed from "YYYYMMDDhhmmss" to "YYYY-MM-DD hh:mm:ss".
1b) and it's correct that it lost it: this syntax above is not parsable as a number and needs quotes in INSERT (for example mysqldump needs to quote TIMESTAMP values otherwise it creates syntax errors). NUM_FLAG means that the parser can parse the field value as a number (digits, and no need for quotes). 
1c) so this patch changes nothing (TIMESTAMP still doesn't have NUM_FLAG), the manual portion needs to be updated.

2) this patch makes NEWDECIMAL have NUM_FLAG, just like DECIMAL always had.
NEWDECIMAL should thus be added to the manual portion quoted above in 1).
[9 Oct 2009 8:47] Bugs System
Pushed into 6.0.14-alpha (revid:alik@ibmvm-20091009083208-0o0f0i9w1sq3c1kn) (version source revid:ingo.struewing@sun.com-20091001194257-a6xrw9u0ccx24qgn) (merge vers: 6.0.14-alpha) (pib:12)
[12 Oct 2009 15:51] Paul DuBois
Guilhem,
re: 1a), Do you mean the NUM_FLAG was lost for TIMESTAMP when TIMESTAMP changed format in 4.1? If so, then I guess all versions of the manual should be changed to reflect what you note in 1c)?

re: 2), this is now pushed to 6.0.14, will it also go to 5.5.x?
[13 Oct 2009 7:09] Guilhem Bichot
Hello Paul,
1) 4.0 doesn't build on my laptop so I cannot say for 4.0; but for sure, 4.1 client does not report NUM_FLAG for TIMESTAMP fields on 4.1 servers, as I see in mysql-4.1/mysql-test/r/metadata.result: the field "k" created at line 11 has flags 1249 and so does not have 32748 which is NUM_FLAG.
Apart from those facts, yes the logical explanation is the change in syntax of timestamps (added ":" and space).
2) I don't know, it is on a list which I sent to Staale Deraas for consideration of backporting, but he will be the decider
[13 Oct 2009 13:04] Paul DuBois
Guilhem,

FYI: This is what I get when I connect to a 4.0.30 server. Looks like the NUM flag is set for the TIMESTAMP column, in contrast to current behavior.

mysql> drop table t;
Query OK, 0 rows affected (0.00 sec)

mysql> create table t (t timestamp, i int, c char(5));
Query OK, 0 rows affected (0.01 sec)

mysql> select * from t;
Field   1:  `t`
Catalog:    ``
Database:   ``
Table:      `t`
Org_table:  `t`
Type:       TIMESTAMP
Collation:  ? (0)
Length:     14
Max_length: 0
Decimals:   0
Flags:      NOT_NULL UNSIGNED ZEROFILL TIMESTAMP NUM 

Field   2:  `i`
Catalog:    ``
Database:   ``
Table:      `t`
Org_table:  `t`
Type:       LONG
Collation:  ? (0)
Length:     11
Max_length: 0
Decimals:   0
Flags:      NUM 

Field   3:  `c`
Catalog:    ``
Database:   ``
Table:      `t`
Org_table:  `t`
Type:       STRING
Collation:  ? (0)
Length:     5
Max_length: 0
Decimals:   0
Flags:      

I'll ask Staale about 5.5.x. Thanks for the info!
[15 Oct 2009 0:21] Paul DuBois
Noted in 6.0.14 changelog.

The NUM_FLAG bit of the MYSQL_FIELD.flags member now is set for
columns of type MYSQL_TYPE_NEWDECIMAL. 

Setting report to NDI pending push into 5.5.x.
[19 Oct 2009 8:35] Guilhem Bichot
Hello Paul. Actually the fix was pushed in next-mr-bugfixing, and is in next-mr now. So, the fix is in 5.5.x now. Not sure you need a changelog entry for 6.0.14.
[19 Oct 2009 16:42] Guilhem Bichot
Paul, the fix is not and will not be in mysql-trunk; it's in mysql-next-mr (I verified).
[20 Oct 2009 11:54] Paul DuBois
Setting report to NDI pending push into 5.5.x.
[12 Nov 2009 8:19] Bugs System
Pushed into 5.5.0-beta (revid:alik@sun.com-20091110093229-0bh5hix780cyeicl) (version source revid:alik@ibmvm-20091009130916-0ijstmmz3efzx20g) (merge vers: 5.5.0-beta) (pib:13)
[12 Nov 2009 20:59] Paul DuBois
Noted in 5.5.0 changelog.
[16 Dec 2010 8:34] Georgi Kodinov
Bug #55824 is fixed by the fix for this bug.

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.077 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.