[Devel] Problem with table_version in db.c

Daniel-Constantin Mierla daniel at voice-system.ro
Sun Jul 2 21:26:43 CEST 2006



On 07/02/06 21:02, Matty wrote:
>
> On Sun, 2 Jul 2006, Daniel-Constantin Mierla wrote:
>
>> Hello,
>>
>> On 07/02/06 20:07, Matty wrote:
>>>
>>> Howdy,
>>>
>>> When I attempt to start openser, I am greeted with the following 
>>> error (please continue reading for the reason why):
>>>
>>> $ openser
>>>
>>> [ ..... ]
>>>  0(0) usrloc:preload_udomain: Wrong version v2134024 for table 
>>> <location>, expected v1001
>>>  0(0) register_udomain(): Error while preloading domain 'location'
>>>  0(0) pool_remove: Removing connection from the pool
>>>  0(0) domain_fixup(): Error while registering domain
>>>
>>> I checked the MySQL database (5.22) table and the query being 
>>> issued, and they both check out:
>>>
>>> $ mysql -uroot -p -hmysql
>>> Enter password:
>>> Welcome to the MySQL monitor.  Commands end with ; or \g.
>>> Your MySQL connection id is 35 to server version: 5.0.22-log
>>>
>>> Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
>>>
>>> mysql> use openser
>>> Reading table information for completion of table and column names
>>> You can turn off this feature to get a quicker startup with -A
>>>
>>> Database changed
>>> mysql>  select table_version from version where table_name='location';
>>> +---------------+
>>> | table_version |
>>> +---------------+
>>> |          1001 |
>>> +---------------+
>>> 1 row in set (0.00 sec)
>>>
>>> To see what was going on, I added a break point to table_version and 
>>> dumped res.rows.values just prior to the function returning:
>>>
>>> (gdb) p *res.rows.values
>>> $7 = {type = DB_STRING, nul = 0, val = {int_val = 2134056,
>>>       double_val = 4.6067679823539676e-308, time_val = 2134056,
>>>       string_val = 0x209028 "1001", str_val = {s = 0x209028 "1001",
>>>       len = 0}, blob_val = {s = 0x209028 "1001", len = 0},
>>>       bitmap_val = 2134056}}
>>>
>>> Upon inspecting the code in table_version, I noticed that the 
>>> VAL_INT MACRO is used to return val.int_val to the calling function:
>>>
>>> /* From db.c */
>>> ret = VAL_INT(ROW_VALUES(RES_ROWS(res)));
>>> dbf->free_result(connection, res);
>>> return ret;
>>>
>>> When I dump val.int_val with gdb, I get differenet results each time 
>>> the program runs:
>>>
>>> (gdb) p *res.rows.values.val.int_val
>>> $10 = 825241649
>>>
>>> I did a bit more digging, and it looks like the 'type' field is set 
>>> to 2 (DB_STRING) after the query completes, and val.str_val.s 
>>> contains the result:
>>>
>>> (gdb) x/s res.rows.values.val.str_val.s
>>> 0x209028:        "1001"
>>>
>>> With that said, is there a reason that the "type" field isn't 
>>> checked on return from the query, and the appropriate result used? I 
>>> can submit the patches I am using to address this problem, but I 
>>> wanted to check with the development folks to see why the VAL_INT 
>>> macro is always used.
>> VAL_INT is used because the table_version should be integer number, 
>> but seems not to be in your case. Please check the structure of table 
>> 'version'.
>>
>> describe version;
>> show create table version;
>>
>> However, the check of the result type should be done as you 
>> suggested, I will commit it soon.
>
> Hi Daniel,
>
> I used openser_mysql.sh to create the database. Here is the table 
> description and the SQL used to create the version table:
>
> mysql> describe version;
> +---------------+-------------+------+-----+---------+-------+
> | Field         | Type        | Null | Key | Default | Extra |
> +---------------+-------------+------+-----+---------+-------+
> | table_name    | varchar(64) | NO   | PRI | NULL    |       |
> | table_version | smallint(5) | NO   |     | 0       |       |
> +---------------+-------------+------+-----+---------+-------+
> 2 rows in set (0.00 sec)
>
> mysql> show create table version;
> +---------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
>
> | Table   | Create Table |
> +---------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
>
> | version | CREATE TABLE `version` (
>   `table_name` varchar(64) NOT NULL,
>   `table_version` smallint(5) NOT NULL default '0',
>   PRIMARY KEY  (`table_name`)
> ) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
> +---------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
>
> 1 row in set (0.00 sec)
>
> This seems to match what is the 'create table' statement in 
> openser_mysql.sh:
>
> CREATE TABLE version (
>    table_name varchar(64) NOT NULL primary key,
>    table_version smallint(5) DEFAULT '0' NOT NULL
> ) $TABLE_TYPE;
>
> I am using openser on a Solaris 10 server, and can provide additional 
> details if you need them.

Seems that the type of the column does not match with one of the types 
that are converted by openser to integer. If the type is not recognized, 
then the default is DB_STRING.

Could you edit the modules/mysql/res.c and add next line at the top of 
"for(i = 0; i < n; i++)" statement in function "static inline int 
get_columns(db_con_t* _h, db_res_t* _r)" :


LOG(L_ERR, "column [%d] type = %d\n", i, fields[i].type);

Then locate the mysql_com.h file on your system and send it to me along 
with the output of the log statement.

Cheers,
Daniel


 
>
> - Ryan
> -- 
> UNIX Administrator
> http://daemons.net/~matty
>
> _______________________________________________
> Devel mailing list
> Devel at openser.org
> http://openser.org/cgi-bin/mailman/listinfo/devel
>



More information about the Devel mailing list