Bug #81382 GetSchema() and MySqlDataAdapter returning different types of data
Description:
When you create a view that contains a fixed integer number as a field, calling GetSchema() will yield the DATA_TYPE of this field as an Int (32-bit) field. However, when you use a data adapter to retrieve data from this field, the data adapter returns the integer as a BIGINT (64-bit).
How to repeat:
This issue and behavior can easily be replicated. First, create a new MySql database. Then create a new table called Artists:
|------------------------------------------------------------|
| Field Name | Data Type | Comments |
|------------|-------------|---------------------------------|
| ArtistId | INT | Primary Key / Auto-Increment |
| FirstName | VARCHAR(45) | |
| LastName | VARCHAR(45) | |
|------------------------------------------------------------|
Now insert at least one row into this table:
INSERT INTO Artists (FirstName, LastName) VALUES ('Bill', 'Clinton');
Now create a new view in MySql called MyView containing this SQL SELECT statement:
SELECT
`FirstName` AS `FirstName`,
`LastName` AS `LastName`,
9 AS `Nine`
FROM
`Artist`
Finally, open Visual Studio and create a new C# console application and add a reference to MySql.Data.Dll and type in the following program (change the connection string, of course):
using System;
using System.Data;
using MySql.Data.MySqlClient;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
const string connectionString = "user id=userid;password=password;database=TestDb;server=mysql-server;convertzerodatetime=True;port=3306";
string schemaDataType = "";
using (var connection = new MySqlConnection(connectionString))
{
connection.Open();
using (DataTable table = connection.GetSchema("Columns"))
{
foreach (DataRow row in table.Rows)
{
if (!((string) row["COLUMN_NAME"]).Equals("Nine")) continue;
schemaDataType = (string)row["DATA_TYPE"];
break;
}
}
connection.Close();
}
// schemaDataType == "int"
Console.WriteLine(schemaDataType);
DataTable tbl;
using (var connection = new MySqlConnection(connectionString))
{
using (var command = new MySqlCommand("SELECT * FROM MyView", connection))
{
connection.Open();
using (var adapter = new MySqlDataAdapter())
{
using (var ds = new DataSet())
{
adapter.SelectCommand = command;
adapter.Fill(ds);
tbl = ds.Tables[0];
}
}
connection.Close();
}
}
// adapterDataType == "Int64"
// schemaDataType != adapterDataType // WHY?
string adapterDataType = (tbl.Rows[0]["Nine"]).GetType().ToString();
Console.WriteLine(adapterDataType);
}
}
}
Running this program will first print "int", which is what GetSchema() is reporting as the data type. According to the MySql Guide, an INT is 4 bytes of storage (32-bits).
Below that, using a MySqlDataAdapter, the program prints "Int64", which is obviously 64-bits.
Suggested fix:
My "hack" to temporarily get around this issue is to create a function in MySql that converts a 64-bit number into a 32-bit number:
CREATE FUNCTION BigToInt (n BIGINT) RETURNS INTEGER RETURN n;
Then I modify my view, like this:
SELECT
`FirstName` AS `FirstName`,
`LastName` AS `LastName`,
BigToInt(9) AS `Nine`
FROM
`Artist`
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.040 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.
Description: When you create a view that contains a fixed integer number as a field, calling GetSchema() will yield the DATA_TYPE of this field as an Int (32-bit) field. However, when you use a data adapter to retrieve data from this field, the data adapter returns the integer as a BIGINT (64-bit). How to repeat: This issue and behavior can easily be replicated. First, create a new MySql database. Then create a new table called Artists: |------------------------------------------------------------| | Field Name | Data Type | Comments | |------------|-------------|---------------------------------| | ArtistId | INT | Primary Key / Auto-Increment | | FirstName | VARCHAR(45) | | | LastName | VARCHAR(45) | | |------------------------------------------------------------| Now insert at least one row into this table: INSERT INTO Artists (FirstName, LastName) VALUES ('Bill', 'Clinton'); Now create a new view in MySql called MyView containing this SQL SELECT statement: SELECT `FirstName` AS `FirstName`, `LastName` AS `LastName`, 9 AS `Nine` FROM `Artist` Finally, open Visual Studio and create a new C# console application and add a reference to MySql.Data.Dll and type in the following program (change the connection string, of course): using System; using System.Data; using MySql.Data.MySqlClient; namespace ConsoleApplication5 { class Program { static void Main(string[] args) { const string connectionString = "user id=userid;password=password;database=TestDb;server=mysql-server;convertzerodatetime=True;port=3306"; string schemaDataType = ""; using (var connection = new MySqlConnection(connectionString)) { connection.Open(); using (DataTable table = connection.GetSchema("Columns")) { foreach (DataRow row in table.Rows) { if (!((string) row["COLUMN_NAME"]).Equals("Nine")) continue; schemaDataType = (string)row["DATA_TYPE"]; break; } } connection.Close(); } // schemaDataType == "int" Console.WriteLine(schemaDataType); DataTable tbl; using (var connection = new MySqlConnection(connectionString)) { using (var command = new MySqlCommand("SELECT * FROM MyView", connection)) { connection.Open(); using (var adapter = new MySqlDataAdapter()) { using (var ds = new DataSet()) { adapter.SelectCommand = command; adapter.Fill(ds); tbl = ds.Tables[0]; } } connection.Close(); } } // adapterDataType == "Int64" // schemaDataType != adapterDataType // WHY? string adapterDataType = (tbl.Rows[0]["Nine"]).GetType().ToString(); Console.WriteLine(adapterDataType); } } } Running this program will first print "int", which is what GetSchema() is reporting as the data type. According to the MySql Guide, an INT is 4 bytes of storage (32-bits). Below that, using a MySqlDataAdapter, the program prints "Int64", which is obviously 64-bits. Suggested fix: My "hack" to temporarily get around this issue is to create a function in MySql that converts a 64-bit number into a 32-bit number: CREATE FUNCTION BigToInt (n BIGINT) RETURNS INTEGER RETURN n; Then I modify my view, like this: SELECT `FirstName` AS `FirstName`, `LastName` AS `LastName`, BigToInt(9) AS `Nine` FROM `Artist`