Bug #27475 | mysql_fetch_field do NOT report correctly certain field types | ||
---|---|---|---|
Submitted: | 27 Mar 2007 15:25 | Modified: | 2 Apr 2007 23:15 |
Reporter: | Alonso Murillo | Email Updates: | |
Status: | Verified | Impact on me: | |
Category: | MySQL Server: Data Types | Severity: | S2 (Serious) |
Version: | Mysql 5.0.37/5.BK/4.1BK | OS: | Windows (Wincows/Linux) |
Assigned to: | Assigned Account | CPU Architecture: | Any |
Tags: | BLOB, longtext, Mediumtext, text, Tinyblob, tinytext, wrong field type |
[27 Mar 2007 15:25]
Alonso Murillo
[27 Mar 2007 16:19]
MySQL Verification Team
Thank you for the bug report. Could you please provide a complete test case: create table script and the C API client code. Thanks in advance.
[31 Mar 2007 13:59]
Alonso Murillo
// Includes... #include <iostream> #include <windows.h> #include <mysql/mysql.h> #include <mysql/mysqld_error.h> #include <cstring> #include <cstdio> using namespace std; // Programa principal int main() { // Variables MYSQL *myData; MYSQL_RES *res; MYSQL_ROW row; MYSQL_FIELD *columna; int i, j, k, l; unsigned long *lon; MYSQL_ROW_OFFSET pos; // Intentar iniciar MySQL: if(!(myData = mysql_init(0))) { // Imposible crear el objeto myData cout << "ERROR: imposible crear el objeto myData." << endl; rewind(stdin); getchar(); return 1; } // Debe existir un usuario "curso" con clave de acceso "clave" y // con al menos el privilegio "SELECT" sobre la tabla // "prueba.gente" if(!mysql_real_connect(myData, NULL, "curso", "clave", "prueba", MYSQL_PORT, NULL, 0)) { // No se puede conectar con el servidor en el puerto especificado. cout << "Imposible conectar con servidor mysql en el puerto " << MYSQL_PORT << " Error: " << mysql_error(myData) << endl; mysql_close(myData); rewind(stdin); getchar(); return 1; } // Conectar a base de datos. if(mysql_select_db(myData, "prueba")) { // Imposible seleccionar la base de datos, posiblemente no existe. cout << "ERROR: " << mysql_error(myData) << endl; mysql_close(myData); rewind(stdin); getchar(); return 2; } // Hacer una consulta con el comando "SELECT * FROM gente": if(mysql_query(myData, "SELECT * FROM gente")) { // Error al realizar la consulta: cout << "ERROR: " << mysql_error(myData) << endl; mysql_close(myData); rewind(stdin); getchar(); return 2; } // Almacenar el resultado de la consulta: if((res = mysql_store_result(myData))) { // Obtener el número de registros seleccionados: i = (int) mysql_num_rows(res); // Obtener el número de columnsa por fila: j = (int) mysql_num_fields(res); // Mostrar el número de registros seleccionados: cout << "Consulta: SELECT * FROM gente" << endl; cout << "Numero de filas encontradas: " << i << endl; cout << "Numero de columnas por fila: " << j << endl; // Información sobre columnas usando mysql_fetch_field: cout << endl << "Informacion sobre columnas:" << endl; for(l = 0; l < j; l++) { columna = mysql_fetch_field(res); cout << "Nombre: " << columna->name << endl; cout << "Longitud: " << columna->length << endl; cout << "Tipo: " << (columna->type ? columna->type << endl; // THE RESULT TYPE FOR TEXT FIELD 252 // Liberar el resultado de la consulta: mysql_free_result(res); } // Cerrar la conexión mysql_close(myData); // Esperar a que se pulse una tecla y salir. rewind(stdin); getchar(); return 0; }
[2 Apr 2007 23:15]
MySQL Verification Team
Thank you for the bug report. #include <my_global.h> #include <m_string.h> #include "mysql.h" #define DB_HOST "localhost" #define DB_USER "root" #define DB_PASSW "" #define DB_NAME "test" #define DB_PORT 3306 #define DB_UNIX_SOCKET "/tmp/mysql.sock" /* NULL */ #define CREATE_QUERY "Create Table if not exists tb_type (col_TinyBlob tinyblob, \ col_Blob blob,col_TinyText tinytext,col_Text text,col_MediumText mediumtext, \ col_LongText longtext)" #define SELECT_QUERY "select * from tb_type" void main( void ) { MYSQL mysql; MYSQL_RES *result; unsigned int num_fields; unsigned int i; MYSQL_FIELD *fields; mysql_init(&mysql); if (!mysql_real_connect(&mysql,DB_HOST,DB_USER,DB_PASSW,DB_NAME, DB_PORT,DB_UNIX_SOCKET,0)) { printf("Error: %s\n",mysql_error(&mysql)); return; } else printf("Connected to the server: %s\n",mysql_get_server_info(&mysql)); if (mysql_query( &mysql, CREATE_QUERY) ) { printf("Error (query): %s\n", mysql_error( &mysql )); mysql_close( &mysql ); return; } if (mysql_query( &mysql, SELECT_QUERY) ) { printf("Error (query): %s\n", mysql_error( &mysql )); mysql_close( &mysql ); return; } result = mysql_store_result(&mysql); num_fields = mysql_num_fields(result); fields = mysql_fetch_fields(result); for(i = 0; i < num_fields; i++) { printf("%s: %u\n",fields[i].name, fields[i].type); } mysql_free_result(result); mysql_close(&mysql); } [miguel@light 5.0]$ ./bug27475 Connected to the server: 5.0.40-debug col_TinyBlob: 252 col_Blob: 252 col_TinyText: 252 col_Text: 252 col_MediumText: 252 col_LongText: 252 [miguel@light 5.0]$ cat /etc/issue Fedora Core release 6 (Zod) Kernel \r on an \m [[miguel@light 4.1]$ ./bug27475 Connected to the server: 4.1.23-debug col_TinyBlob: 252 col_Blob: 252 col_TinyText: 252 col_Text: 252 col_MediumText: 252 col_LongText: 252 [miguel@light 4.1]$ [miguel@light 5.1]$ ./bug27475 Connected to the server: 5.1.18-beta-debug col_TinyBlob: 252 col_Blob: 252 col_TinyText: 252 col_Text: 252 col_MediumText: 252 col_LongText: 252 #define packet_error (~(unsigned long) 0) enum enum_field_types { 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, MYSQL_TYPE_DATE, MYSQL_TYPE_TIME, MYSQL_TYPE_DATETIME, MYSQL_TYPE_YEAR, MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR, MYSQL_TYPE_BIT, MYSQL_TYPE_NEWDECIMAL=246, MYSQL_TYPE_ENUM=247, MYSQL_TYPE_SET=248, MYSQL_TYPE_TINY_BLOB=249, MYSQL_TYPE_MEDIUM_BLOB=250, MYSQL_TYPE_LONG_BLOB=251, MYSQL_TYPE_BLOB=252, MYSQL_TYPE_VAR_STRING=253, MYSQL_TYPE_STRING=254, MYSQL_TYPE_GEOMETRY=255 };
[13 Nov 2007 16:18]
Brad House
I ran into this issue too, and there is a workaround of if fields[i].type is MYSQL_TYPE_BLOB, you can check fields[i].charsetnr and if it is NOT 63, then it is a TEXT field, otherwise it is a BLOB. I got that workaround from here: http://bugs.mysql.com/bug.php?id=11974 It appears to work in 5.0.45 at least... You'd think the C API could do that check on its own internally and return MYSQL_TYPE_STRING instead in those instances...
[18 Jun 2008 11:10]
Konstantin Osipov
Jim, are you going to look at this bug anytime soon?
[20 Feb 2009 14:12]
Tonci Grgin
Omer, what is the "acceptable workaround" here??? This is killing me with connectors, see Bug#24886 for example. Requesting re-triage as connectors simply can't rely on guessing the correct metadata or depend on such slow implementation of I__S. Server version: 5.1.31 MySQL Community Server (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> create table test43055 (vcfld VARCHAR (50) NOT NULL PRIMARY KEY, txtfld TEXT) Engine=MyISAM charset latin1; Query OK, 0 rows affected (0.02 sec) mysql> select * from test43055; Field 1: `vcfld` Catalog: `def` Database: `test` Table: `test43055` Org_table: `test43055` Type: VAR_STRING Collation: latin1_swedish_ci (8) Length: 50 Max_length: 0 Decimals: 0 Flags: NOT_NULL PRI_KEY NO_DEFAULT_VALUE PART_KEY Field 2: `txtfld` Catalog: `def` Database: `test` Table: `test43055` Org_table: `test43055` Type: BLOB <<<<< Collation: latin1_swedish_ci (8) Length: 65535 Max_length: 0 Decimals: 0 Flags: BLOB 0 rows in set (0.00 sec)
[14 Jul 2009 6:22]
Tonci Grgin
Thanks for info Jim.