[MDEV-16347] Integer literal is typed as MYSQL_TYPE_LONG Created: 2018-05-31  Updated: 2020-11-05  Resolved: 2018-05-31

Status: Closed
Project: MariaDB Server
Component/s: Data types
Affects Version/s: 10.3.7
Fix Version/s: N/A

Type: Bug Priority: Minor
Reporter: Bradley Grainger Assignee: Alexander Barkov
Resolution: Not a Bug Votes: 0
Labels: datatype, protocol
Environment:

mariadb:10.3.7 Docker image, i.e., Debian Jessie


Attachments: File dump-10_2.pcap     File dump-10_3.pcap    
Issue Links:
Problem/Incident
is caused by MDEV-12619 UNION creates excessive integer colum... Closed
Relates
relates to MDEV-15148 Protocol regression testing for the s... Open
relates to MDEV-16360 For every function, document exactly ... Open

 Description   

In MariaDB 10.2 (and MySQL 5.7, MySQL 8.0), executing SELECT 1; returns a text result set where the column definition packet specifies a type of MYSQL_TYPE_LONGLONG (0x08), i.e., a 64-bit integer.

In MariaDB 10.3, the same query returns a text result set with the type MYSQL_TYPE_LONG (0x03), i.e., a 32-bit integer.

I've attached two packet captures that show the difference: dump-10_2.pcap and dump-10_3.pcap.

This could be a breaking protocol change for strongly-typed clients. For example, in .NET (with the Connector/NET or MySqlConnector libraries), the following code has a breaking change:

using (var connection = new MySqlConnection("..."))
{
	connection.Open();
	using (var command = new MySqlCommand("SELECT 1;", connection))
	{
		var result = command.ExecuteScalar();
		// result.GetType() is System.Int64 in MariaDB 10.2, System.Int32 in MariaDB 10.3
		
		// throws an InvalidCastException with MariaDB 10.3 because .NET cannot unbox an int directly into a long
		var numericResult = (long) command.ExecuteScalar();
	}
}

In .NET, there are workarounds, such as Convert.ToInt32. And perhaps this kind of statement is rare in practice. And while the protocol documentation doesn't specify (AFAIK) how numeric literals should be represented on the wire, I didn't find documentation of this as a deliberate change in behaviour.

Note that SELECT 100000000000; (or some other number outside of the range of a 32-bit signed integer) will automatically promote the type in the result set to LONGLONG.



 Comments   
Comment by Elena Stepanova [ 2018-05-31 ]

It looks like an intentional change made in this commit:
https://github.com/MariaDB/server/commit/ae5b31fe52e272a2cebbdf9bf8c230d622dc8ec3

A cleanup for MDEV-12619 UNION creates excessive integer column types…
… for integer literals
 
Fixing result set metadata for Item_int to match type_handler(),
i.e. MYSQL_TYPE_LONG for small numbers and MYSQL_TYPE_LONGLONG for big numbers.
 10.3  mariadb-10.3.7  mariadb-10.3.6 mariadb-10.3.5 mariadb-10.3.4 mariadb-10.3.3 mariadb-10.3.2 mariadb-10.3.1

Assigning to bar to confirm/clarify.

Comment by Alexander Barkov [ 2018-05-31 ]

It was an intentional change to have SELECT 1 return the result set metadata according to what column type is created on CREATE TABLE t1 AS SELECT 1 AS c1.

Comment by Bradley Grainger [ 2018-05-31 ]

Caused by a change made for MDEV-12619.

Comment by Vladislav Vaintroub [ 2018-05-31 ]

Also, MDEV-12619 changes return value of the following functions to smaller type.

 
strcmp
interval
regexp_instr
connection_id
sign
 
octet_length
char_length
uncompressed_length
coercibility
locate
field
ascii
ord
find_in_set
bit_count
benchmark
sleep
get_lock
release_lock
Item_master_gtid_wait
is_free_lock
is_used_lock
sqlcode
issimple
  isring
isclosed
dimension
numgeometries
numinteriorring
numpoints
srid
gis_debug
json_length
json_depth
crc32
to_days
dayofmonth
dayofyear
quarter
year
hour
minute
second
microsecond
period_add
period_diff
week
yearweek

Generated at Thu Feb 08 08:28:13 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.