---559023410-851401618-1039913737=:6184 Content-Type: TEXT/PLAIN; charset=US-ASCII Dear Tim, Here's a new set of patches against the original DBI v1.32 for the files: Driver.xst dbd_xsh.h lib/DBI/DBD.pm The patches are gzipped. To apply them, use: gunzip DBI.patches.gz cd DBI-1.32 patch -p0 <../DBI.patches The DBD.pm file has undergone a whole lot more change -- it is, I think, in even better shape than the version shipped earlier. If you need them, I can redo the patches against that revised version of the file, but I'd rather not if I don't have to. The dbd_xsh.h file has some additions and subtractions and amendments. Most notably, I'd modified the interface to dbd_db_do to match what I'd expect it to need, and to match the corresponding code added in Driver.xst. And I've added, as discussed, the dbd_dr_data_sources define which can be used by drivers that need to call a C code function to determine the available data sources. I've put #ifdef's in place around almost all the code fragments in Driver.xst. There are a couple which are not #ifdef'd; I'm willing to discuss these with you. I've added a code fragment for data_sources that is generated only if dbd_dr_data_sources is defined. I've added a code fragment for 'do' which is generated only if dbd_db_do is defined. I've also fixed the bug with dbd_db_finish3 vs dbd_st_finish3. We need to notify all the driver developers if these are to remain in place; their dbdimp.h header must provide name mappings for all of the functions which they implement. Hence, I've copied this to dbi-dev! The list of function names are: dbd_init dbd_discon_all dbd_dr_data_sources dbd_db_login6 dbd_db_login dbd_db_do dbd_db_commit dbd_db_rollback dbd_db_disconnect dbd_db_destroy dbd_db_STORE_attrib dbd_db_FETCH_attrib dbd_st_prepare dbd_st_rows dbd_st_execute dbd_st_fetch dbd_st_finish3 dbd_st_finish dbd_st_destroy dbd_st_blob_read dbd_st_STORE_attrib dbd_st_FETCH_attrib dbd_bind_ph Of these, a driver normally implements either dbd_db_login6 or dbd_db_login (but not, usually, both), and either dbd_st_finish3 or dbd_st_finish (but not both). Implementing dbd_st_rows and dbd_db_do is optional. Note that there was a previous declaration of dbd_db_do in dbd_xsh.h but (a) it was never invoked by Driver.xst code, and (b) the parameter list was incomplete for the upgraded $dbh->do($sql, @params) function. The dbd_dr_data_sources function is optional too; it is only defined by drivers that need to call a C function to determine the list of available data sources (eg DBD::Informix). I have tested them with a patched version of DBI that now claims it is version 1.33 (yeah, I'm going to have to force install the official version when it is available). That change isn't in these files, of course. I've also built a new version of DBD::Informix that insists it uses DBI v1.33. As you already know, Tim, the material in DBD.pm is very substantially revised (it's about 2330 lines of diff for a new file of length 2668 lines). Compared with the draft I sent you earlier this week, this version has had some more reordering on the material so it is more comprehensible. It formats well under pod2html and then printing on the screen. The only controversial bit is, I think, the changes made in the section on Generating a GetInfo Package -- maybe Steffen should take a look? Are you able to give any indication of when a DBI 1.33 might be released? I've got a new version of DBD::Informix lined up waiting on that official release. I can organize it so that it works with DBI 1.32 if absolutely necessary, though that would then break when DBI 1.33 is finally released, so I'd rather wait. -- Jonathan Leffler #include <disclaimer.h> STSM, Informix Database Engineering, IBM Data Management Phone: +1 650-926-6921 Fax: +1 650-926-6971 Tie-line: 630-6921 Email: jleffler@us.ibm.com Guardian of DBD::Informix v1.04.PC1 -- http://dbi.perl.org ---559023410-851401618-1039913737=:6184 Content-Type: APPLICATION/octet-stream; name="DBI.patches.gz" Content-Transfer-Encoding: BASE64 Content-ID: <Pine.GSO.4.50.0212141655370.6184@anubis.menlo.ibm.com> Content-Description: Gzipped patches for dbd_xsh.h, Driver.xst, lib/DBI/DBD.pm Content-Disposition: attachment; filename="DBI.patches.gz" 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 9tCB7q8ojOMH17TSxv8FHbSYpPF7AQA= ---559023410-851401618-1039913737=:6184--
![]() |
0 |
![]() |
Dear Tim (and others who've worked on the metadata methods), I'd like to check on my understanding of what's required from the metadata methods such as $dbh->tables. Specifically, there are three distinct possible ways in which a tablename (for sake of example) can be used: 1. In an SQL statement - eg the FROM clause of a SELECT statement. 2. In a catalog query, as a placeholder value. 3. In a catalog query, as a string literal. Further, each of those representations can be different. To take an extreme example: 1. FROM "I said, ""Don't!""" 2. I said, "Don't!" 3. 'I said, "Don''t!"' Although I haven't actually created this particular table name in Informix, I've created equivalent ones -- they routinely break software that is not very carefully designed. Which version of this name should methods such as $dbh->tables return? I assume that the correct option is 2, not least because that is also the format that is stored in the system catalog. The $dbh->quote method will convert from notation 2 to notation 3. AFAIK, there is no DBI standard method to convert from notation 2 to notation 1 -- is that correct? Should there be? $dbh->identifier? I need to know because Informix provides me with a problem; it only recognizes delimited identifiers (notation 1) when a specific environment variable (it happens to be $ENV{DELIMIDENT}) is set. For 99.99% of people, this doesn't matter. They don't have table names that require delimiting -- not least because Informix is remarkably good at disentangling CREATE TABLE TABLE(NULL CHAR(2) NOT NULL, INT DATE NOT NULL, DATE DECIMAL NOT NULL); SQL-92 would require CREATE TABLE "TABLE"("NULL" CHAR(2) NOT NULL, "INT" DATE NOT NULL, "DATE" DECIMAL NOT NULL). However, if you do not have $ENV{DELIMIDENT} set, then it is not safe to use double quotes around identifiers; they will be misinterpreted as strings (for reasons of pre-standard (pre-SQL-86) ancient history). As long as the names are usable as C identifiers, there is no need to treat the names specially. So, a simple-minded process that just encloses table names in double quotes is no good; it will break most Informix code. The schema name (referred to as owner in Informix parlance) can be enclosed in single or double quotes without causing much trouble, as it happens. Column names are subject to the same whimsical treatment as table names. In released versions of DBD::Informix, this is handled incompletely; it sort of implements a very old version of the specification, and attempts to return most values in notation 1 (but doesn't do a very good job of that, either). I'm wondering though what the correct implementation should do. Can the DBI standard implementation of tables handle this? Which of the three notations does it support? What information does it need from $dbh->get_info to handle this? Can it really handle all the vicissitudes of Informix's peculiar notions. I'm trying to work out exactly what in the Informix world correlates with a catalog -- it could be database name without server, or it could be database name plus server -- eg dbase vs dbase@server -- or it could be irrelevant. That mainly has implications for how extensive a set of queries are needed to resolve a really general $dbh->tables query. It is far easier to regard it as irrelevant (as the DBI specification suggests) than not. I think this is mainly an internal issue (to DBD::Informix) which will be resolved in favour of simplicity of implementation over thoroughness of answer -- partly on grounds of performance, partly on grounds of usefulness, and mainly because it is hard to do the job right (I'd have to filter the list of databases generated by a non-SQL method with a simulation of the LIKE procedure -- which granted isn't too hard: LIKE "foo_bar%x" corresponds to m/^foo.bar.*x$/). An additional problem in this area is that the full notation for a column in Informix is: dbase@server:owner.table.column The database name is constrained to be equivalent to a C identifier (up to 128 characters, though), and the server name is likewise constrained. For those components, quotes are neither necessary nor acceptable. The server name is optional and when omitted it is the '@' that vanishes, leaving dbase:owner.table.column. If the database is the current database, then the 'dbase:' part can be omitted. The owner is optional in most types of Informix database regardless of the owner (schema) to which it belongs - but in a MODE ANSI database, it is necessary if you do not own the table. Oh, and if the column is a row type, it is possible to address elements of the row using one or more extra levels of ".identifier". And there are still more gotcha's. In general, if the name is not quoted, it is case-converted to lower case. Exception: unquoted owner names in a MODE ANSI database are converted to upper case; exception to the exception: the unquoted owner name informix is not converted to upper case. If a table name is a delimited identifier, it is case-sensitive; otherwise it is not. Ditto for column names. OTOH, upper case in database or server names is not supported at all for all practical purposes. I'm also wondering how this affects the $dbh->get_info() method. I'm guessing that if DELIMIDENT is set, then it is OK to say 'the quote character for delimited identifiers is double-quote'; I'm wondering what I should say when DELIMIDENT is not set -- undef is very tempting, but is it correct? (Actually, my life is really contorted; if the Informix database server is started with DELIMIDENT set in its environment, it won't matter whether the client ever sets the environment or not -- that server is running with delimited identifiers enabled. But there isn't an easy way to find out whether this obscure circumstance applies other than by trying to use a delimited identifier and seeing whether you get an error or not.) Another related question: how does $dbh->tables('%','','') compare with DBI->data_sources()? Since this is explicitly called out as a special case in $dbh->tables(), I presume it is different from what DBI->data_sources() is expected to return - but how? Or is it a feature that actually should be omitted from the non-experimental specification of $dbh->tables()? Now you know why I'm balding! -- Jonathan Leffler (jleffler@earthlink.net, jleffler@us.ibm.com) #include <disclaimer.h> Guardian of DBD::Informix 1.04.PC1 -- http://dbi.perl.org/
![]() |
0 |
![]() |
On Sun, Dec 15, 2002 at 10:16:47PM -0800, Jonathan Leffler wrote: > Dear Tim (and others who've worked on the metadata methods), > > I'd like to check on my understanding of what's required from the > metadata methods such as $dbh->tables. Specifically, there are three > distinct possible ways in which a tablename (for sake of example) can > be used: > > 1. In an SQL statement - eg the FROM clause of a SELECT statement. > 2. In a catalog query, as a placeholder value. > 3. In a catalog query, as a string literal. > > Further, each of those representations can be different. To take an > extreme example: > > 1. FROM "I said, ""Don't!""" > 2. I said, "Don't!" > 3. 'I said, "Don''t!"' > > Although I haven't actually created this particular table name in > Informix, I've created equivalent ones -- they routinely break > software that is not very carefully designed. > > Which version of this name should methods such as $dbh->tables return? Simple: Just return the tru name of the table (2, in your example). The code that _uses_ the name needs to look after any quoting etc it needs. > I assume that the correct option is 2, not least because that is also > the format that is stored in the system catalog. Yes. > The $dbh->quote method will convert from notation 2 to notation 3. Yes. > AFAIK, there is no DBI standard method to convert from notation 2 to > notation 1 -- is that correct? Should there be? $dbh->identifier? You must have missed $dbh->quote_identifier being added to DBI 1.21. > I need to know because Informix provides me with a problem; it only > recognizes delimited identifiers (notation 1) when a specific > environment variable (it happens to be $ENV{DELIMIDENT}) is set. For > 99.99% of people, this doesn't matter. They don't have table names > that require delimiting -- not least because Informix is remarkably > good at disentangling CREATE TABLE TABLE(NULL CHAR(2) NOT NULL, INT > DATE NOT NULL, DATE DECIMAL NOT NULL); SQL-92 would require CREATE > TABLE "TABLE"("NULL" CHAR(2) NOT NULL, "INT" DATE NOT NULL, "DATE" > DECIMAL NOT NULL). However, if you do not have $ENV{DELIMIDENT} set, > then it is not safe to use double quotes around identifiers; they will > be misinterpreted as strings (for reasons of pre-standard (pre-SQL-86) > ancient history). As long as the names are usable as C identifiers, > there is no need to treat the names specially. > > So, a simple-minded process that just encloses table names in double > quotes is no good; it will break most Informix code. The schema name > (referred to as owner in Informix parlance) can be enclosed in single > or double quotes without causing much trouble, as it happens. Column > names are subject to the same whimsical treatment as table names. > > In released versions of DBD::Informix, this is handled incompletely; > it sort of implements a very old version of the specification, and > attempts to return most values in notation 1 (but doesn't do a very > good job of that, either). I'm wondering though what the correct > implementation should do. Can the DBI standard implementation of > tables handle this? Newer versions are better. See the code. > What information does it need from $dbh->get_info to handle this? Can > it really handle all the vicissitudes of Informix's peculiar notions. Probably not. See the code: sub tables { my ($dbh, @args) = @_; my $sth = $dbh->table_info(@args) or return; my $tables = $sth->fetchall_arrayref or return; my @tables; if ($dbh->get_info(29)) { # SQL_IDENTIFIER_QUOTE_CHAR @tables = map { $dbh->quote_identifier( @{$_}[0,1,2] ) } @$tables; } else { # temporary old style hack (yeach) @tables = map { my $name = $_->[2]; if ($_->[1]) { my $schema = $_->[1]; # a sad hack (mostly for Informix I recall) my $quote = ($schema eq uc($schema)) ? '' : '"'; $name = "$quote$schema$quote.$name" } $name; } @$tables; } return @tables; } sub quote_identifier { my ($dbh, @id) = @_; my $attr = (@id > 3) ? pop @id : undef; my $info = $dbh->{dbi_quote_identifier_cache} ||= [ $dbh->get_info(29) || '"', # SQL_IDENTIFIER_QUOTE_CHAR $dbh->get_info(41) || '.', # SQL_CATALOG_NAME_SEPARATOR $dbh->get_info(114) || 1, # SQL_CATALOG_LOCATION ]; my $quote = $info->[0]; foreach (@id) { # quote the elements next unless defined; s/$quote/$quote$quote/g; # escape embedded quotes $_ = qq{$quote$_$quote}; } # strip out catalog if present for special handling my $catalog = (@id >= 3) ? shift @id : undef; # join the dots, ignoring any null/undef elements (ie schema) my $quoted_id = join '.', grep { defined } @id; if ($catalog) { # add catalog correctly $quoted_id = ($info->[2] == 2) # SQL_CL_END ? $quoted_id . $info->[1] . $catalog : $catalog . $info->[1] . $quoted_id; } return $quoted_id; } > I'm trying to work out exactly what in the Informix world correlates > with a catalog -- it could be database name without server, or it > could be database name plus server -- eg dbase vs dbase@server -- or > it could be irrelevant. Few databases support catalogs. Though I think some simple ones like ODBC CSV drivers use it for the directory the files are in. > That mainly has implications for how > extensive a set of queries are needed to resolve a really general > $dbh->tables query. It is far easier to regard it as irrelevant (as > the DBI specification suggests) than not. I think this is mainly an > internal issue (to DBD::Informix) which will be resolved in favour of > simplicity of implementation over thoroughness of answer -- partly on > grounds of performance, partly on grounds of usefulness, and mainly > because it is hard to do the job right (I'd have to filter the list of > databases generated by a non-SQL method with a simulation of the LIKE > procedure -- which granted isn't too hard: LIKE "foo_bar%x" > corresponds to m/^foo.bar.*x$/). In general you whould do whatever Informix's own ODBC driver does. Remember the principle that it ought to be possible to interchange the use of DBD::Foo with DBD::ODBC using Foo's ODBC driver, with no changes to the application. > An additional problem in this area is that the full notation for a > column in Informix is: > > dbase@server:owner.table.column > > The database name is constrained to be equivalent to a C identifier > (up to 128 characters, though), and the server name is likewise > constrained. For those components, quotes are neither necessary nor > acceptable. The server name is optional and when omitted it is the > '@' that vanishes, leaving dbase:owner.table.column. If the database > is the current database, then the 'dbase:' part can be omitted. The > owner is optional in most types of Informix database regardless of the > owner (schema) to which it belongs - but in a MODE ANSI database, it > is necessary if you do not own the table. Oh, and if the column is a > row type, it is possible to address elements of the row using one or > more extra levels of ".identifier". > > And there are still more gotcha's. In general, if the name is not > quoted, it is case-converted to lower case. Exception: unquoted owner > names in a MODE ANSI database are converted to upper case; exception > to the exception: the unquoted owner name informix is not converted to > upper case. If a table name is a delimited identifier, it is > case-sensitive; otherwise it is not. Ditto for column names. OTOH, > upper case in database or server names is not supported at all for all > practical purposes. > > I'm also wondering how this affects the $dbh->get_info() method. I'm > guessing that if DELIMIDENT is set, then it is OK to say 'the quote > character for delimited identifiers is double-quote'; I'm wondering > what I should say when DELIMIDENT is not set -- undef is very > tempting, but is it correct? (Actually, my life is really contorted; > if the Informix database server is started with DELIMIDENT set in its > environment, it won't matter whether the client ever sets the > environment or not -- that server is running with delimited > identifiers enabled. But there isn't an easy way to find out whether > this obscure circumstance applies other than by trying to use a > delimited identifier and seeing whether you get an error or not.) > > Another related question: how does $dbh->tables('%','','') compare > with DBI->data_sources()? Since this is explicitly called out as a > special case in $dbh->tables(), I presume it is different from what > DBI->data_sources() is expected to return - but how? Or is it a > feature that actually should be omitted from the non-experimental > specification of $dbh->tables()? See the DBI docs. data_sources is about DBI DSN's. > Now you know why I'm balding! Yeap. I don't envy you task. You're life will be easier if you get the latest Informix ODBC driver and the latest DBD::ODBC (development release I think) and see how they behave. The implementors of Informix's ODBC driver must have faced many of these issues and addressed them in an officially acepted way. Tim.
![]() |
0 |
![]() |
Tim Bunce wrote: > On Sun, Dec 15, 2002 at 10:16:47PM -0800, Jonathan Leffler wrote: > >>Dear Tim (and others who've worked on the metadata methods), >> >>I'd like to check on my understanding of what's required from the >>metadata methods such as $dbh->tables. [...] Thanks for the feedback, Tim. {Yes, I missed reading quote_identifier:-(} Yet another question -- given the specifications of type_info_all and type_info, how does type_info get hold of the SQL_DATA_TYPE, SQL_DATETIME_SUB and INTERVAL_PRECISION fields, given that they are not listed in the type_info_all structure? Also, the spiel for SQL_DATA_TYPE says: <quote>This column is the same as the DATA_TYPE column, except for interval or datetime types. For interval and datetime data types, the SQL_DATA_TYPE field will return SQL_INTERVAL or SQL_DATETIME, and the SQL_DATETIME_SUB field will return the subcode for the specific interval or datetime data type. If this field is NULL, then the driver does not support or report on interval or date types.</quote> Questions arising: 1. That last 'date' should be 'datetime' to be consistent. 2. What does the DATA_TYPE field contain when this field contains SQL_DATETIME or SQL_INTERVAL? Not that value - but which value? In the context of type_info_all, you say 'driver-specific columns of information ... start at column index 50 to leave room for expansion'. How do you write an initializer for the gap between the 14 (17?) defined attributes and the index where the driver-specific attributes can start? Or is that a subtle hint not to define driver-specific attributes? I'm looking at the code with lines like: [ 'INTEGER', SQL_INTEGER, undef, "", "", undef, ... ], With the first 14 columns defined, there has to be 36 empty columns left unefined, or zeroed, or something; is there a neat notation to do that? 36*undef or something useful? Or do you have to manually go in and add the entries at type_info_all[n][50] = $newval; and repeat ad nauseam? -- Jonathan Leffler (jleffler@earthlink.net, jleffler@us.ibm.com) #include <disclaimer.h> Guardian of DBD::Informix 1.04.PC1 -- http://dbi.perl.org/
![]() |
0 |
![]() |
On Mon, Dec 16, 2002 at 03:21:12AM -0800, Jonathan Leffler wrote: > > Yet another question -- given the specifications of type_info_all and > type_info, how does type_info get hold of the SQL_DATA_TYPE, > SQL_DATETIME_SUB and INTERVAL_PRECISION fields, given that they are > not listed in the type_info_all structure? Ah, [...rummages in ODBC 3.5 reference book...] Okay, I've just added these extra items to the info to be returned by type_info_all: SQL_DATA_TYPE => 16, DATETIME_SUB => 17, NUM_PREC_RADIX => 18, INTERVAL_PRECISION=> 19, I'd just left them out when I added the extra field descriptions into the type_info docs. Note that DATETIME_SUB is misspelled with an SQL_ prefix in the docs. That's wrong. Fixed now. Driver authors please note! > Also, the spiel for SQL_DATA_TYPE says: > > <quote>This column is the same as the DATA_TYPE column, except for > interval or datetime types. For interval and datetime data types, the > SQL_DATA_TYPE field will return SQL_INTERVAL or SQL_DATETIME, and the > SQL_DATETIME_SUB field will return the subcode for the specific > interval or datetime data type. If this field is NULL, then the > driver does not support or report on interval or date types.</quote> > > Questions arising: > 1. That last 'date' should be 'datetime' to be consistent. Yeap. Fixed. Thanks. > 2. What does the DATA_TYPE field contain when this field contains > SQL_DATETIME or SQL_INTERVAL? Not that value - but which value? The "consise" type integer, ie 112 for SQL_INTERVAL_HOUR_TO_SECOND. So when SQL_DATA_TYPE = SQL_DATETIME or SQL_INTERVAL then DATA_TYPE == DATETIME_SUB. (Yes, DATETIME_SUB does seem redundant but that's what the ODBC spec calls for.) > In the context of type_info_all, you say 'driver-specific columns of > information ... start at column index 50 to leave room for expansion'. > How do you write an initializer for the gap between the 14 (17?) > defined attributes and the index where the driver-specific attributes > can start? Or is that a subtle hint not to define driver-specific > attributes? I'm looking at the code with lines like: > > [ 'INTEGER', SQL_INTEGER, undef, "", "", undef, ... ], > > With the first 14 columns defined, there has to be 36 empty columns > left unefined, or zeroed, or something; is there a neat notation to do > that? 36*undef or something useful? ..., (undef) x 36, ... (The undef must be in parens to get the "x" operator to replicat the list.) Tim.
![]() |
0 |
![]() |
Tim Bunce wrote: > [...] > > Note that DATETIME_SUB is misspelled with > an SQL_ prefix in the docs. That's wrong. Fixed now. Really? <http://msdn.microsoft.com/library/en-us/odbc/htm/odbcsqlgettypeinfo.asp?frame=false> [...] > > 2. What does the DATA_TYPE field contain when this field contains > > SQL_DATETIME or SQL_INTERVAL? Not that value - but which value? > > The "consise" type integer, ie 112 for SQL_INTERVAL_HOUR_TO_SECOND. > So when SQL_DATA_TYPE = SQL_DATETIME or SQL_INTERVAL then > DATA_TYPE == DATETIME_SUB. (Yes, DATETIME_SUB does seem redundant > but that's what the ODBC spec calls for.) IMO, there is a hidden rule for interval or datetime data types: DATA_TYPE == 10 * SQL_DATA_TYPE + SQL_DATETIME_SUB e.g.: SQL_INTERVAL_HOUR_TO_SECOND == 10 * SQL_INTERVAL + SQL_CODE_HOUR_TO_SECOND 112 == 10 * 10 + 12 SQL_TYPE_TIMESTAMP == 10 * SQL_DATETIME + SQL_CODE_TIMESTAMP 93 == 10 * 9 + 3 Steffen
![]() |
0 |
![]() |
> > Yeap. I don't envy you task. You're life will be easier if > you get the latest Informix ODBC driver and the latest > DBD::ODBC (development release I think) and see how they > behave. The implementors of Informix's ODBC driver must have > faced many of these issues and addressed them in an > officially acepted way. My $0.02: Get DBD::ODBC 1.01 please! It's no longer a development release. :) Regards, Jeff
![]() |
0 |
![]() |
On Mon, Dec 16, 2002 at 03:04:48PM +0100, Steffen Goeldner wrote: > Tim Bunce wrote: > > > [...] > > > > Note that DATETIME_SUB is misspelled with > > an SQL_ prefix in the docs. That's wrong. Fixed now. > > Really? > > <http://msdn.microsoft.com/library/en-us/odbc/htm/odbcsqlgettypeinfo.asp?frame=false> Ah, thanks for the catch! I'll fix it. [grumble] I'd forgotten that the ODBC 3.5 book I have isn't as accurate as it should be. I can't find my Microsoft book at the moment. > > > 2. What does the DATA_TYPE field contain when this field contains > > > SQL_DATETIME or SQL_INTERVAL? Not that value - but which value? > > > > The "consise" type integer, ie 112 for SQL_INTERVAL_HOUR_TO_SECOND. > > So when SQL_DATA_TYPE = SQL_DATETIME or SQL_INTERVAL then > > DATA_TYPE == DATETIME_SUB. (Yes, DATETIME_SUB does seem redundant > > but that's what the ODBC spec calls for.) > > IMO, there is a hidden rule for interval or datetime data types: > > DATA_TYPE == 10 * SQL_DATA_TYPE + SQL_DATETIME_SUB > > e.g.: > > SQL_INTERVAL_HOUR_TO_SECOND == 10 * SQL_INTERVAL + SQL_CODE_HOUR_TO_SECOND > 112 == 10 * 10 + 12 > > SQL_TYPE_TIMESTAMP == 10 * SQL_DATETIME + SQL_CODE_TIMESTAMP > 93 == 10 * 9 + 3 Thanks, I've added the "DATA_TYPE == 10 * SQL_DATA_TYPE + SQL_DATETIME_SUB" example to the docs. (And put "subcode" in italics as a reminder to me :) Tim.
![]() |
0 |
![]() |
--------------3A9F9B23AA75A4D71297B74C Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Jonathan Leffler wrote: > [...] > > The only controversial bit is, I think, the changes made in the > section on Generating a GetInfo Package -- maybe Steffen should take a > look? Done. Since double quotes are required for your $driver variable, there is a potential 'double quote trap'. I attached a few changes. Steffen --------------3A9F9B23AA75A4D71297B74C Content-Type: text/plain; charset=us-ascii; name="DBD.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="DBD.diff" *** DBD.pm Mon Dec 16 23:09:57 2002 --- DBD.pm-new Mon Dec 16 23:04:19 2002 *************** *** 2572,2585 **** $dbh->{ PrintError } = 1; $driver = "<foo>" unless defined $driver; ! print <<PERL; ! package DBD::$driver::GetInfo; ! use DBD::$driver(); ! my \$sql_driver = $driver; my \$sql_ver_fmt = '%02d.%02d.%04d'; # ODBC version string: ##.##.##### ! my \$sql_driver_ver = sprintf \$sql_ver_fmt, split (/\./, \$DBD::$driver::VERSION); my \@Keywords = qw( PERL --- 2572,2585 ---- $dbh->{ PrintError } = 1; $driver = "<foo>" unless defined $driver; ! print <<"PERL"; ! package DBD::${driver}::GetInfo; ! use DBD::${driver}(); ! my \$sql_driver = '$driver'; my \$sql_ver_fmt = '%02d.%02d.%04d'; # ODBC version string: ##.##.##### ! my \$sql_driver_ver = sprintf \$sql_ver_fmt, split (/\./, \$DBD::${driver}::VERSION); my \@Keywords = qw( PERL *************** *** 2595,2601 **** sub sql_data_source_name { my $dbh = shift; ! return 'dbi:$sql_driver:' . $dbh->{Name}; } sub sql_keywords { return join ',', @Keywords; --- 2595,2601 ---- sub sql_data_source_name { my $dbh = shift; ! return "dbi:$sql_driver:" . $dbh->{Name}; } sub sql_keywords { return join ',', @Keywords; --------------3A9F9B23AA75A4D71297B74C--
![]() |
0 |
![]() |