Skip Menu |

This queue is for tickets about the DBD-ODBC CPAN distribution.

Report information
The Basics
Id: 41713
Status: resolved
Priority: 0/
Queue: DBD-ODBC

People
Owner: Nobody in particular
Requestors: eremmel [...] zonnet.nl
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: (no value)
Fixed in: 1.17_3



Subject: ODBC driver does not support SQL_COLUMN_DISPLAY_SIZE on SQLTables()
DBD-ODBC-1.17 : (ODBC.pm 11768 2008-09-12 13:00:28Z mjevans) perl : v5.10.0 built for MSWin32-x86-multi-thread, Binary build 1004 [287188] provided by ActiveState, Built Sep 3 2008 13:16:37 I use a propriety ODBC driver that does not support SQL_COLUMN_DISPLAY_SIZE and SQL_COLUMN_LENGTH on statement handles that come from a call to SQLTables() and SQLColumns(). I did some debugging to find out and made a 'fix' in dbdimp.c,dbd_descibe(). The function dbd_descibe() contains via an #ifdef a fallback when in the interface does not support SQL_COLUMN_DISPLAY_SIZE and SQL_COLUMN_LENGTH, I extended this. Now the interface accepts when the implementation does not support those column attributes and falls back to a default value. The point that I address it here rather at the implementator of the ODBC-driver is that this driver works fine with MS office, cognos etc. Also in respect to retrieving meta data like table and column info. I hope that you will except this change so I've not to stick to my private build and it gives me the possibility to utilize Perl in combination with this driver to a broader audience that myself. Please find attached a fix in diff-C3 format and a trace file based on this fix. In this trace I perform a list of some tables, get the columns of a table and perform a query on that table. The first two actions show the problem of the not supported attributes the later not. Regards, JHF
Subject: dbdimp_c_fix_diffC3.txt
*** DBD-ODBC-1.17\dbdimp.c Fri Sep 12 15:01:28 2008 --- DBD-ODBC-1.17-new\dbdimp.c Mon Dec 15 12:25:36 2008 *************** *** 2067,2075 **** NULL, 0, NULL , &fbh->ColDisplaySize);/* TBD: 3.0 update */ if (!SQL_SUCCEEDED(rc)) { ! dbd_error( ! h, rc, "describe/SQLColAttributes/SQL_COLUMN_DISPLAY_SIZE"); ! break; } else if (DBIc_TRACE(imp_sth, 0, 0, 8)) { TRACE1(imp_sth, " display size = %ld\n", fbh->ColDisplaySize); } --- 2067,2078 ---- NULL, 0, NULL , &fbh->ColDisplaySize);/* TBD: 3.0 update */ if (!SQL_SUCCEEDED(rc)) { ! if( DBIc_TRACE(imp_sth, 0, 0, 8) ) { ! TRACE1(imp_sth, " describe/SQLColAttributes/SQL_COLUMN_DISPLAY_SIZE not supported, will be equal to SQL_COLUMN_LENGTH\n",0); ! } ! /* ColDisplaySize will be made equal to ColLength */ ! fbh->ColDisplaySize = 0; ! rc = SQL_SUCCESS; } else if (DBIc_TRACE(imp_sth, 0, 0, 8)) { TRACE1(imp_sth, " display size = %ld\n", fbh->ColDisplaySize); } *************** *** 2086,2093 **** SQL_COLUMN_LENGTH, NULL, 0, NULL ,&fbh->ColLength); if (!SQL_SUCCEEDED(rc)) { ! dbd_error(h, rc, "describe/SQLColAttributes/SQL_COLUMN_LENGTH"); ! break; } else if (DBIc_TRACE(imp_sth, 0, 0, 8)) { TRACE1(imp_sth, " column length = %ld\n", fbh->ColLength); } --- 2089,2099 ---- SQL_COLUMN_LENGTH, NULL, 0, NULL ,&fbh->ColLength); if (!SQL_SUCCEEDED(rc)) { ! fbh->ColLength = 2001; /* XXX! */ ! if( DBIc_TRACE(imp_sth, 0, 0, 8) ) { ! TRACE1(imp_sth, " describe/SQLColAttributes/SQL_COLUMN_LENGT not supported, fallback on %d\n",fbh->ColLength); ! } ! rc = SQL_SUCCESS; } else if (DBIc_TRACE(imp_sth, 0, 0, 8)) { TRACE1(imp_sth, " column length = %ld\n", fbh->ColLength); }
Subject: dbdimp_c_fix_trace.txt

Message body is not shown because it is too large.

Thank you for this submission. I will start taking a look at it this evening and try and get back to you in a day or so. Unless it adversely affects functionality with other ODBC drivers I cannot see why it should not be included in the next release of DBD::ODBC but I'll know more when I've had a chance to look at it. Martin -- Martin J. Evans Wetherby, UK
I made some changes to your patch. TRACE1 calls with no substitution args for the printf format can be TRACE0. The second think is that the 2001 default should really be configurable so I'll work on making it so (not your problem but your patch highlighted it). The final thing is that it seems a waste of time to keep calling SQLColAttributes once you know it fails for SQL_COLUMN_DISPLAY_SIZE and SQL_COLUMN_LENGTH. However, on the last point, if I understand your posting, these values are only not returned for SQLTables and SQLColumns calls. If you can confirm that these attributes work at other times then there is nothing else to do. If on the other hand you are saying you driver never succeeds on these attributes then after the first call fails we can record that fact and always just default. Get back to me and I can send you a version to test then I will release it. Martin -- Martin J. Evans Wetherby, UK
Just forgot. It would be useful to know what the ODBC driver is so I can at least document why we do this in the source code. Martin -- Martin J. Evans Wetherby, UK
Your patch is now applied with minor modification and I've made default column display size a $dbh and $sth attribute. Just need to write tests for it. If you want a 1.17_3 development release to test please let me know. I'd rather you try it before it is released. Martin -- Martin J. Evans Wetherby, UK
From: eremmel [...] zonnet.nl
On Ma. Dec. 15 16:30:28 2008, MJEVANS wrote: Show quoted text
> If you want a 1.17_3 development release to test please let me > know. I'd rather you try it before it is released.
Please send me a patch I will test it against the drivers I use.
From: eremmel [...] zonnet.nl
On Ma. Dec. 15 15:22:16 2008, MJEVANS wrote: Show quoted text
> However, on the last point, if I understand your posting, these values > are only not returned for SQLTables and SQLColumns calls. If you can > confirm that these attributes work at other times then there is nothing > else to do. If on the other hand you are saying you driver never > succeeds on these attributes then after the first call fails we can > record that fact and always just default. > > Martin
I glad that you understood my posting (only SQLTables and SQLColumns do not support those attributes). BTW disabling those attributes 'forever' when they fail once might limit the functionality for other drivers as well to much. Skipping those calls per request after first failure makes sense to me.
From: eremmel [...] zonnet.nl
On Ma. Dec. 15 15:23:22 2008, MJEVANS wrote: Show quoted text
> Just forgot. It would be useful to know what the ODBC driver is so I can > at least document why we do this in the source code. > > Martin
The driver name is: DSN name: Infor Integration ODBC driver This driver is developed to access (read-only) Infor ERP LN, Infor Baan IV, etc and gives uniform access to data irrespective of implementation database of the ERP software.
Thank you for all the information. I am adding a few tests and will then put a distrib together for you to try. Expect to be done by lunch, uk time. Martin -- Martin J. Evans Wetherby, UK
Try this: ftp://ftp.easysoft.com/pub/DBD-ODBC-1.17_3.tar.gz You'll note a new odbc_column_display_size attribute which defaults to what was hard-coded before. There are new tests in 03bind to check you can get/set it. Martin -- Martin J. Evans Wetherby, UK
From: eremmel [...] zonnet.nl
On Di. Dec. 16 04:41:31 2008, MJEVANS wrote: Show quoted text
> Try this: > Martin
Hi Martin, great work and nice to make it configurable. I got it working after some debugging. The property odbc_column_display_size is copied from dbh to sth during odbc_st_prepare_sv, but calling SQLTables/SQLColumns is not going via prepare. I doubt whether one should break after failing on SQL_COLUMN_LENGTH in dbd_describe. I saw you added some new tests. A few are failing against MS access db. Is that know to you, or need you more details? Find details: *** dbdimp-1173.c Tue Dec 16 10:22:08 2008 --- dbdimp.c Tue Dec 16 15:17:15 2008 *************** *** 1487,1492 **** --- 1487,1493 ---- imp_sth->hstmt = SQL_NULL_HSTMT; return 0; } + imp_sth->odbc_column_display_size = imp_dbh->odbc_column_display_size; return build_results(sth,rc); } *************** *** 2108,2114 **** "supported, fallback on %d\n", fbh->ColLength); } rc = SQL_SUCCESS; - break; } else if (DBIc_TRACE(imp_sth, 0, 0, 8)) { TRACE1(imp_sth, " column length = %ld\n", fbh->ColLength); } --- 2109,2114 ---- *************** *** 4961,4966 **** --- 4961,4967 ---- return 0; } + imp_sth->odbc_column_display_size = imp_dbh->odbc_column_display_size; return build_results(sth,rc); } *************** t/rt_39841..............ok 1/28# Looks like you planned 28 tests but only ran 14. t/rt_39841..............dubious Test returned status 255 (wstat 65280, 0xff00) DIED. FAILED tests 15-28 Failed 14/28 tests, 50.00% okay (less 11 skipped tests: 3 okay, 10.71%) t/rt_39897..............ok
On Tue Dec 16 09:38:59 2008, eremmel wrote: Show quoted text
> Hi Martin, great work and nice to make it configurable. I got it working > after some debugging. The property odbc_column_display_size is copied > from dbh to sth during odbc_st_prepare_sv, but calling > SQLTables/SQLColumns is not going via prepare. I doubt whether one > should break after failing on SQL_COLUMN_LENGTH in dbd_describe.
Good point. I didn't have a driver to test this on or I'd have spotted that and it seemed like a lot of effort to deliberately break one of our drivers to test it when you had one already. Show quoted text
> I saw you added some new tests. A few are failing against MS access db. > Is that know to you, or need you more details?
I'll get someone here to run against Access and see how we get on. If we don't reproduce I may get back to you. Show quoted text
> Find details: > *** dbdimp-1173.c Tue Dec 16 10:22:08 2008 > --- dbdimp.c Tue Dec 16 15:17:15 2008 > *************** > *** 1487,1492 **** > --- 1487,1493 ---- > imp_sth->hstmt = SQL_NULL_HSTMT; > return 0; > } > + imp_sth->odbc_column_display_size =
imp_dbh->odbc_column_display_size; see notes below Show quoted text
> return build_results(sth,rc); > } > *************** > *** 2108,2114 **** > "supported, fallback on %d\n", fbh->ColLength); > } > rc = SQL_SUCCESS; > - break;
fixed - I'm afraid I manually applied your patch late last night and forgot to delete the break. Show quoted text
> } else if (DBIc_TRACE(imp_sth, 0, 0, 8)) { > TRACE1(imp_sth, " column length = %ld\n",
fbh->ColLength); Show quoted text
> } > --- 2109,2114 ---- > *************** > *** 4961,4966 **** > --- 4961,4967 ---- > return 0; > } > > + imp_sth->odbc_column_display_size =
imp_dbh->odbc_column_display_size; see notes below Show quoted text
> return build_results(sth,rc); > } > *************** > t/rt_39841..............ok 1/28# Looks like you planned 28 tests but > only ran 14. > t/rt_39841..............dubious > Test returned status 255 (wstat 65280, 0xff00) > DIED. FAILED tests 15-28 > Failed 14/28 tests, 50.00% okay (less 11 skipped tests: 3 okay, > 10.71%) > t/rt_39897..............ok
Will look into this. Although your driver only does this on SQLTables and SQLColumns and hence the fix you supplied would work the problem you found is for anything calling build_results so I've moved the: imp_sth->odbc_column_display_size = imp_dbh->odbc_column_display_size; into build_results. In the mean time a new 1.17_3 is in the same place as before with the fixes you outlined just done slightly differently. Thanks again for you input. Martin -- Martin J. Evans Wetherby, UK
From: eremmel [...] zonnet.nl
On Di. Dec. 16 10:44:59 2008, MJEVANS wrote: Show quoted text
> Although your driver only does this on SQLTables and SQLColumns and > hence the fix you supplied would work the problem you found is for > anything calling build_results so I've moved the: > > imp_sth->odbc_column_display_size = imp_dbh->odbc_column_display_size; > > into build_results. > > Martin
Hi Martin, I tested this new version and it works great, thank you for being so supportive. This might not be the right place, but I like to make a few minor remark, please just consider those as as things that you might consider and nothing more. 1: Show quoted text
>Good point. I didn't have a driver to test this on
My practice is in these cases, to add in the debug build e.g. an environment var that indicates which and how the function should fail, to test recovery code. 2: I also noticed that you set a number of properties in odbc_st_prepare_sv like odbc_query_timeout etc. Those might be applicable (I do not know the ODBC interface so well) to the sth returned by SQLTables and SQLColumns as well. 3: I build the ODBC.dll with Visual Studio 6.0 and SDK Feb 2003. I needed to add the library MSVCRT.lib or MSVCRTD.lib to the Makefile for ODBC.dll.
On Wed Dec 17 05:03:12 2008, eremmel wrote: Show quoted text
> On Di. Dec. 16 10:44:59 2008, MJEVANS wrote:
> > Although your driver only does this on SQLTables and SQLColumns and > > hence the fix you supplied would work the problem you found is for > > anything calling build_results so I've moved the: > > > > imp_sth->odbc_column_display_size = imp_dbh->odbc_column_display_size; > > > > into build_results. > > > > Martin
> > Hi Martin, > > I tested this new version and it works great, thank you for being so > supportive.
No problem. I will mark this rt as fixed when I release 1.17_3. Show quoted text
> This might not be the right place, but I like to make a few minor > remark, please just consider those as as things that you might consider > and nothing more.
I'll reply here now but if you want to follow this up can you email directly at martin dot evans at easysoft dot com. Show quoted text
> 1:
> >Good point. I didn't have a driver to test this on
> My practice is in these cases, to add in the debug build e.g. an > environment var that indicates which and how the function should fail, > to test recovery code.
Yes, I could have done that but in the end I'd be testing the change as I expected it to work and your driver may not have worked like I understood from you. In this case I was pushed for time and felt it was easiest for you to verify the change but I'm sorry I got it wrong first time and obviously caused you to waste some time. Show quoted text
> 2: > I also noticed that you set a number of properties in odbc_st_prepare_sv > like odbc_query_timeout etc. Those might be applicable (I do not know > the ODBC interface so well) to the sth returned by SQLTables and > SQLColumns as well.
Yes, you are correct and I noticed that and made a note of it but in this case I decided to leave alone the bits which are not definitely broken but in any case I don't really think any apply. Show quoted text
> 3: > I build the ODBC.dll with Visual Studio 6.0 and SDK Feb 2003. I needed > to add the library MSVCRT.lib or MSVCRTD.lib to the Makefile for ODBC.dll.
Could you send me privately the details of what error you got and how you fixed it so I can add a note about it in the windows readme? BTW, I referred to you as eremmel in the Changes file as I do not know your name. If you would prefer something else let me know. Martin -- Martin J. Evans Wetherby, UK