Bug #64084 | Connector returning Long instead of Int | ||
---|---|---|---|
Submitted: | 20 Jan 2012 16:47 | Modified: | 23 Feb 2012 19:19 |
Reporter: | Sam Kimmel | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Documentation | Severity: | S2 (Serious) |
Version: | 5 | OS: | Windows (Win 7 Pro 64-bit) |
Assigned to: | John Russell | CPU Architecture: | Any |
[20 Jan 2012 16:47]
Sam Kimmel
[20 Jan 2012 17:11]
Valeriy Kravchuk
You are right, server returns these data as LONGLONG, that is, 64 bit integer: macbook-pro:5.5 openxs$ bin/mysql -uroot --column-type-info test Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 25 Server version: 5.5.20-debug-log Source distribution Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> SELECT CAST(1 As SIGNED) As ID; Field 1: `ID` Catalog: `def` Database: `` Table: `` Org_table: `` Type: LONGLONG Collation: binary (63) Length: 1 Max_length: 1 Decimals: 0 Flags: NOT_NULL BINARY NUM +----+ | ID | +----+ | 1 | +----+ 1 row in set (0.11 sec) mysql> SELECT LAST_INSERT_ID() As ID; Field 1: `ID` Catalog: `def` Database: `` Table: `` Org_table: `` Type: LONGLONG Collation: binary (63) Length: 21 Max_length: 1 Decimals: 0 Flags: NOT_NULL BINARY NUM +----+ | ID | +----+ | 0 | +----+ 1 row in set (0.10 sec) but a) why do expect something else, 32 bit int, and b) why do you think the bug is in connector, if it is just the metadata server returns?
[20 Jan 2012 17:18]
Sam Kimmel
Based on the information you posted, it is not a bug in the Connector. If the server is telling you it is LONG there isn't much you can do. Would you say this is a bug in MySQL Server if I am explicitly converting to a 32-bit integer but it is returning it as LONG from the server?
[20 Jan 2012 17:42]
Valeriy Kravchuk
Sorry, but where do you convert to 32-bit integer on server side? Please, read http://dev.mysql.com/doc/refman/5.5/en/cast-functions.html#function_cast: "MySQL supports arithmetic with both signed and unsigned 64-bit values. If you are using numeric operators (such as + or -) and one of the operands is an unsigned integer, the result is unsigned by default (see Section 11.6.1, “Arithmetic Operators”). You can override this by using the SIGNED or UNSIGNED cast operator to cast a value to a signed or unsigned 64-bit integer, respectively." 64-bit is mentioned explicitly. I'd say this is not a bug actually.
[20 Jan 2012 18:18]
Sam Kimmel
Overlooked the part talking about 64-bit with CAST/CONVERT. Kind of curios as to why they don't support CAST as SMALLINT/BIGINT? The only reason I am casting in the first place is that LAST_INSERT_ID() is returning a 64-bit number when the identity column is only 32-bits. mysql> SELECT id FROM webpage LIMIT 1; Field 1: 'ID' Catalog: 'def' Database: 'skimmel' Table: 'webpage' Org_table: 'webpage' Type: LONG Collation: binary (63) Length: 11 Max_length: 1 Decimals: 0 Flags: NOT_NULL PRI_KEY AUTO_INCREMENT NUM PART_KEY +----+ | ID | +----+ | 1 | +----+ 1 row in set (0.00 sec) mysql> INSERT INTO webpage (Name) VALUES ('Test'); SELECT LAST_INSERT_ID(); Query OK, 1 row affected (0.00 sec) Field 1: 'LAST_INSERT_ID()' Catalog: 'def' Database: '' Table: '' Org_table: '' Type: LONGLONG Collation: binary (63) Length: 21 Max_length: 2 Decimals: 0 Flags: NOT_NULL BINARY NUM +------------------+ | LAST_INSERT_ID() | +------------------+ | 10 | +------------------+ 1 row in set (0.00 sec) Maybe I overlooked something in the documentation and LAST_INSERT_ID() will always return 64-bit integer as well?
[24 Jan 2012 14:42]
Valeriy Kravchuk
I do not see this mentioned in the manual, http://dev.mysql.com/doc/refman/5.5/en/information-functions.html#function_last-insert-id. But I assume it's by design. For your CAST request, we have verified verified feature requests for a long time already. See bug #16904 and bug #62926. Do you want me to make a documentation request out of this bug report?
[24 Jan 2012 19:42]
Sam Kimmel
Might be nice to have a line in there about it returning 64-bit integer. Thank you for your help; I really appreciate it.
[25 Jan 2012 11:14]
Valeriy Kravchuk
Let's treat this as a documentation request for last_insert_id() for now. We shell see where it will end up.
[20 Feb 2012 14:28]
Sam Kimmel
Purely informational, as I do not know if this is the intended implementation or not... Out of curiosity I went and created a test numbers table in which I included all the number types. CREATE TABLE `test`.`IntTest` ( `TestBigInt` BIGINT NOT NULL, `TestUBigInt` BIGINT UNSIGNED NOT NULL, `TestInt` INTEGER NOT NULL, `TestUInt` INTEGER UNSIGNED NOT NULL, `TestMedInt` MEDIUMINT NOT NULL, `TestUMedInt` MEDIUMINT UNSIGNED NOT NULL, `TestSmallInt` SMALLINT NOT NULL, `TestUSmallInt` SMALLINT UNSIGNED NOT NULL, `TestTinyInt` TINYINT NOT NULL, `TestUTinyInt` TINYINT UNSIGNED NOT NULL ) ENGINE = InnoDB; When I queried for column type info, I found it interesting that I got LONG as the type for INT, and LONG LONG for BigInt. If this is indeed the case, shouldn't the connector be converting LONG to int and LONG LONG to long? Or am I fundamentally misunderstanding something about MySQL? mysql> SELECT * FROM IntTest; Field 1: `TestBigInt` Catalog: `def` Database: `test` Table: `IntTest` Org_table: `inttest` Type: LONGLONG Collation: binary (63) Length: 20 Max_length: 0 Decimals: 0 Flags: NOT_NULL NO_DEFAULT_VALUE NUM Field 2: `TestUBigInt` Catalog: `def` Database: `test` Table: `IntTest` Org_table: `inttest` Type: LONGLONG Collation: binary (63) Length: 20 Max_length: 0 Decimals: 0 Flags: NOT_NULL UNSIGNED NO_DEFAULT_VALUE NUM Field 3: `TestInt` Catalog: `def` Database: `test` Table: `IntTest` Org_table: `inttest` Type: LONG Collation: binary (63) Length: 11 Max_length: 0 Decimals: 0 Flags: NOT_NULL NO_DEFAULT_VALUE NUM Field 4: `TestUInt` Catalog: `def` Database: `test` Table: `IntTest` Org_table: `inttest` Type: LONG Collation: binary (63) Length: 10 Max_length: 0 Decimals: 0 Flags: NOT_NULL UNSIGNED NO_DEFAULT_VALUE NUM Field 5: `TestMedInt` Catalog: `def` Database: `test` Table: `IntTest` Org_table: `inttest` Type: INT24 Collation: binary (63) Length: 9 Max_length: 0 Decimals: 0 Flags: NOT_NULL NO_DEFAULT_VALUE NUM Field 6: `TestUMedInt` Catalog: `def` Database: `test` Table: `IntTest` Org_table: `inttest` Type: INT24 Collation: binary (63) Length: 8 Max_length: 0 Decimals: 0 Flags: NOT_NULL UNSIGNED NO_DEFAULT_VALUE NUM Field 7: `TestSmallInt` Catalog: `def` Database: `test` Table: `IntTest` Org_table: `inttest` Type: SHORT Collation: binary (63) Length: 6 Max_length: 0 Decimals: 0 Flags: NOT_NULL NO_DEFAULT_VALUE NUM Field 8: `TestUSmallInt` Catalog: `def` Database: `test` Table: `IntTest` Org_table: `inttest` Type: SHORT Collation: binary (63) Length: 5 Max_length: 0 Decimals: 0 Flags: NOT_NULL UNSIGNED NO_DEFAULT_VALUE NUM Field 9: `TestTinyInt` Catalog: `def` Database: `test` Table: `IntTest` Org_table: `inttest` Type: TINY Collation: binary (63) Length: 4 Max_length: 0 Decimals: 0 Flags: NOT_NULL NO_DEFAULT_VALUE NUM Field 10: `TestUTinyInt` Catalog: `def` Database: `test` Table: `IntTest` Org_table: `inttest` Type: TINY Collation: binary (63) Length: 3 Max_length: 0 Decimals: 0 Flags: NOT_NULL UNSIGNED NO_DEFAULT_VALUE NUM 0 rows in set (0.00 sec)
[20 Feb 2012 15:06]
Sam Kimmel
I downloaded the source and started stepping through. The MySqlReader does correctly return Int32 for INGETER. Now I'm trying to figure out why the Entity Framework provider converts all my INT, Auto Increment, Signed primary keys to long in C# when using database first.
[23 Feb 2012 19:19]
Paul DuBois
Thank you for your bug report. This issue has been addressed in the documentation. The updated documentation will appear on our website shortly, and will be included in the next release of the relevant products. Documented that LAST_INSERT_ID() returns BIGINT (64 bits).
[25 Jun 2013 14:33]
Constantin Rusan
The Multiple Birds Hypothesis by The Lazy MySQL Dev One day a little boy wanted to kill seven birds and no less with one stone. He carefully aimed, released the well tensioned slingshot and .... Oh sh--. The ulonglong stone hit the BIGINT window of his grandmother's house. But don't worry, he quickly wrote in the house's documentation that the window is supposed to be broken and everyone lived Happily Ever After!, despite the rain, snow, cold wind and scorching hit coming through the broken (by design) window. In your honest opinion of expert architects and developers: Is this behaviour semantically correct? Consider this: AUTO_INCREMENT can be used on at least the following types of data columns: BIGINT, INT, MEDIUMINT, SMALLINT, TINYINT, DOUBLE, FLOAT. The LAST_INSERT_ID() is documented as returning the last generated AUTO_INCREMENT field value for a table. I expect that if my column is typed INT(11) the function will return a data type consistent with the type of my column (ergo INT(11)) and not a different type of data. I am sorry to say this, but upgrading the documentation in this case was a shameless short-cut to avoiding to fix the bug. In it's current state the LAST_INSERT_ID() in MySQL is as useful as a rubber hammer in a match against The Incredible Hulk. I am sorry to be so a__l. I can only hope someone can understand how frustrated I am... Sincerely yours, Strongly Typed Lt. Data,