# @(#)$Id: GetInfo.pm,v 2004.1 2004/12/01 20:32:53 jleffler Exp $ # # @(#)DBD::Informix::GetInfo # # Derived using a modified version of DBI::DBD::write_getinfo_pm from # DBI v1.32 and a modified version of DBD::ODBC 1.01 compiled to use # the Informix CLI (ODBC) v3.81.0000 driver distributed with ClientSDK # 2.80.UC1 on Solaris 7. # # Copyright 2002-03 IBM # Copyright 2004 Jonathan Leffler # # You may distribute under the terms of either the GNU General Public # License or the Artistic License, as specified in the Perl README file. # #------------------------------------------------------------------------- # Code and explanations follow for DBD::Informix # (IBM Informix Database Driver for Perl DBI Version 2008.0513 (2008-05-13)) #------------------------------------------------------------------------- # # NB: The Informix CLI (ODBC) driver did not provide a list of keywords. # The %info hash was automatically generated by DBI::DBD::write_getinfo_pm # and then manually modified (rather a lot). package DBD::Informix::GetInfo; use strict; use POSIX qw(strftime); use DBD::Informix; use DBI::Const::GetInfoType qw(%GetInfoType); use DBI::Const::GetInfoReturn qw(%GetInfoReturnTypes %GetInfoReturnValues); # Version handling is more than a little bit painful. # Do not fold the 'my' onto the assignment line - antique CPAN related # code gets confused. my $VERSION = "2008.0513"; # Fixup for development system. $VERSION = "2003.00.0000" if ($VERSION =~ m%[:]VERSION[:]%); my $sql_driver = 'Informix'; my $sql_ver_fmt = '%02d.%02d.%04d'; # ODBC version string: ##.##.##### my $dbd_ver_str = defined $DBD::Informix::VERSION ? $DBD::Informix::VERSION : "XXX"; # Fixup for development system (convert date to 3-part version number if not already in correct format) $dbd_ver_str = strftime("%Y.%m.%d", localtime time) if ($dbd_ver_str !~ m%^\d+\.\d+(\.\d+)?%); # Ensure we have 3-part version number. $dbd_ver_str .= ".0" if ($dbd_ver_str =~ m%^\d+\.\d+$%); my $sql_driver_ver = sprintf $sql_ver_fmt, split(/[.]/, $dbd_ver_str); sub sql_data_source_name { my $dbh = shift; my $dsn = $dbh->FETCH(qw{Name}); return "dbi:$sql_driver:$dsn"; } sub sql_user_name { my $dbh = shift; return $dbh->FETCH(qw{ix_Username}); } sub sql_txnsup # Are transactions supported { # SQL_TC_NONE - No transactions. # SQL_TC_DML - DML only allowed in transactions. # SQL_TC_DDL_COMMIT - DML can be rolled back; DDL is committed. # SQL_TC_DDL_IGNORE - DML supported; DDL is ignored. # SQL_TC_ALL - DML and DDL both rolled back. # Informix SE: unlogged => NONE, logged => DDL_COMMIT. # Informix DS: unlogged => NONE, logged => ALL. my $dbh = shift; my %val = %{$GetInfoReturnValues{SQL_TXN_CAPABLE}}; my $rv; if ($dbh->FETCH(qw{ix_LoggedDatabase})) { $rv = $dbh->FETCH(qw{ix_InformixOnLine}) ? $val{SQL_TC_ALL} : $val{SQL_TC_DDL_COMMIT}; } else { $rv = $val{SQL_TC_NONE}; } return $rv; } # Default isolation level sub sql_deftxniso { # SQL_TXN_READ_UNCOMMITTED # DIRTY READ # SQL_TXN_READ_COMMITTED # COMMITTED READ in IDS # SQL_TXN_REPEATABLE_READ # CURSOR STABILITY in IDS # SQL_TXN_SERIALIZABLE # REPEATABLE READ in IDS # Default Isolation: # SE -> DIRTY # IDS unlogged -> DIRTY # IDS logged -> COMMITTED # IDS MODE ANSI -> SERIALIZABLE my $dbh = shift; my %val = %{$GetInfoReturnValues{SQL_DEFAULT_TXN_ISOLATION}}; my $rv = $val{SQL_TXN_READ_UNCOMMITTED}; if ($dbh->FETCH(qw{ix_InformixOnLine}) && $dbh->FETCH(qw{ix_LoggedDatabase})) { $rv = $dbh->FETCH(qw{ix_ModeAnsiDatabase}) ? $val{SQL_TXN_SERIALIZABLE} : $val{SQL_TXN_READ_COMMITTED}; } return $rv; } # Supported isolation levels # NB: Not supported by SET ISOLATION statement but by SQLSetConnectAttr(). sub sql_txniso { # SQL_TXN_READ_UNCOMMITTED # DIRTY READ # SQL_TXN_READ_COMMITTED # COMMITTED READ in IDS # SQL_TXN_REPEATABLE_READ # CURSOR STABILITY in IDS # SQL_TXN_SERIALIZABLE # REPEATABLE READ in IDS # Default Isolation: # SE -> DIRTY # IDS unlogged -> DIRTY # IDS logged -> DIRTY | COMMITTED | REPEATABLE | SERIALIZABLE my $dbh = shift; my %val = %{$GetInfoReturnValues{SQL_DEFAULT_TXN_ISOLATION}}; my $rv = $val{SQL_TXN_READ_UNCOMMITTED}; if ($dbh->FETCH(qw{ix_InformixOnLine}) && $dbh->FETCH(qw{ix_LoggedDatabase})) { $rv |= $val{SQL_TXN_SERIALIZABLE} | $val{SQL_TXN_REPEATABLE_READ} | $val{SQL_TXN_READ_COMMITTED}; } return $rv; } sub sql_servername { my $dbh = shift; my ($rv) = $ENV{INFORMIXSERVER}; $rv = $1 if (defined $dbh->FETCH(qw{Name}) && $dbh->FETCH(qw{Name}) =~ m/@\(\w[-a-zA-Z_0-9.]*\)$/); return $rv; } sub sql_dbms_version { my $dbh = shift; my $sv = $dbh->FETCH(qw{ix_ServerVersion}); # Integer: eg 930 for 9.30.xxx $sv = 0 unless defined $sv; my @av = (int($sv/100), int($sv%100), 0); my $rv = sprintf("$sql_ver_fmt %s", $av[0], $av[1], 0, $av[2]); return $rv; } sub sql_driver_name { my $dbh = shift; return "DBD::$sql_driver"; } sub sql_identquote { my $dbh = shift; my $rv = $ENV{DELIMIDENT} ? '"' : ''; return $rv; } sub sql_storedprocs { my $dbh = shift; return $dbh->FETCH(qw{ix_StoredProcedures}) ? 'Y' : 'N'; } # our %info = ( # Perl 5.005_03 does not accept 'our' no strict; %info = ( 20 => 'Y', # SQL_ACCESSIBLE_PROCEDURES 19 => 'Y', # SQL_ACCESSIBLE_TABLES 0 => 0, # SQL_ACTIVE_CONNECTIONS 116 => 0, # SQL_ACTIVE_ENVIRONMENTS 1 => 0, # SQL_ACTIVE_STATEMENTS 169 => 64, # SQL_AGGREGATE_FUNCTIONS 117 => 0, # SQL_ALTER_DOMAIN 86 => 11, # SQL_ALTER_TABLE 10021 => 0, # SQL_ASYNC_MODE 120 => 0, # SQL_BATCH_ROW_COUNT 121 => 0, # SQL_BATCH_SUPPORT 82 => 64, # SQL_BOOKMARK_PERSISTENCE 114 => 1, # SQL_CATALOG_LOCATION 10003 => 'Y', # SQL_CATALOG_NAME 41 => ':', # SQL_CATALOG_NAME_SEPARATOR 42 => 'database', # SQL_CATALOG_TERM 92 => 1, # SQL_CATALOG_USAGE 10004 => '', # SQL_COLLATING_SEQUENCE 10004 => '', # SQL_COLLATION_SEQ 87 => 'Y', # SQL_COLUMN_ALIAS 22 => 0, # SQL_CONCAT_NULL_BEHAVIOR 53 => 0, # SQL_CONVERT_BIGINT 54 => 0, # SQL_CONVERT_BINARY 55 => 0, # SQL_CONVERT_BIT 56 => 0, # SQL_CONVERT_CHAR 57 => 0, # SQL_CONVERT_DATE 58 => 0, # SQL_CONVERT_DECIMAL 59 => 0, # SQL_CONVERT_DOUBLE 60 => 0, # SQL_CONVERT_FLOAT 48 => 0, # SQL_CONVERT_FUNCTIONS # 173 => undef, # SQL_CONVERT_GUID 61 => 0, # SQL_CONVERT_INTEGER 123 => 0, # SQL_CONVERT_INTERVAL_DAY_TIME 124 => 0, # SQL_CONVERT_INTERVAL_YEAR_MONTH 71 => 0, # SQL_CONVERT_LONGVARBINARY 62 => 0, # SQL_CONVERT_LONGVARCHAR 63 => 0, # SQL_CONVERT_NUMERIC 64 => 0, # SQL_CONVERT_REAL 65 => 0, # SQL_CONVERT_SMALLINT 66 => 0, # SQL_CONVERT_TIME 67 => 0, # SQL_CONVERT_TIMESTAMP 68 => 0, # SQL_CONVERT_TINYINT 69 => 0, # SQL_CONVERT_VARBINARY 70 => 0, # SQL_CONVERT_VARCHAR 122 => 0, # SQL_CONVERT_WCHAR 125 => 0, # SQL_CONVERT_WLONGVARCHAR 126 => 0, # SQL_CONVERT_WVARCHAR 74 => 2, # SQL_CORRELATION_NAME 127 => 0, # SQL_CREATE_ASSERTION 128 => 0, # SQL_CREATE_CHARACTER_SET 129 => 0, # SQL_CREATE_COLLATION 130 => 0, # SQL_CREATE_DOMAIN 131 => 0, # SQL_CREATE_SCHEMA 132 => 1, # SQL_CREATE_TABLE 133 => 0, # SQL_CREATE_TRANSLATION 134 => 3, # SQL_CREATE_VIEW 23 => 1, # SQL_CURSOR_COMMIT_BEHAVIOR 24 => 1, # SQL_CURSOR_ROLLBACK_BEHAVIOR 10001 => 1, # SQL_CURSOR_SENSITIVITY 2 => \&sql_data_source_name, # SQL_DATA_SOURCE_NAME 25 => 'N', # SQL_DATA_SOURCE_READ_ONLY 119 => 0, # SQL_DATETIME_LITERALS 17 => 'Informix', # SQL_DBMS_NAME 18 => \&sql_dbms_version, # SQL_DBMS_VER 18 => \&sql_dbms_version, # SQL_DBMS_VERSION 170 => 3, # SQL_DDL_INDEX 26 => \&sql_deftxniso, # SQL_DEFAULT_TRANSACTION_ISOLATION 26 => \&sql_deftxniso, # SQL_DEFAULT_TXN_ISOLATION 10002 => 'N', # SQL_DESCRIBE_PARAMETER # 171 => undef, # SQL_DM_VER # 3 => undef, # SQL_DRIVER_HDBC # 135 => undef, # SQL_DRIVER_HDESC # 4 => undef, # SQL_DRIVER_HENV # 76 => undef, # SQL_DRIVER_HLIB # 5 => undef, # SQL_DRIVER_HSTMT 6 => 'DBD::Informix', # SQL_DRIVER_NAME # 77 => undef, # SQL_DRIVER_ODBC_VER 7 => $sql_driver_ver, # SQL_DRIVER_VER 136 => 0, # SQL_DROP_ASSERTION 137 => 0, # SQL_DROP_CHARACTER_SET 138 => 0, # SQL_DROP_COLLATION 139 => 0, # SQL_DROP_DOMAIN 140 => 0, # SQL_DROP_SCHEMA 141 => 7, # SQL_DROP_TABLE 142 => 0, # SQL_DROP_TRANSLATION 143 => 7, # SQL_DROP_VIEW 144 => 0, # SQL_DYNAMIC_CURSOR_ATTRIBUTES1 145 => 0, # SQL_DYNAMIC_CURSOR_ATTRIBUTES2 27 => 'N', # SQL_EXPRESSIONS_IN_ORDERBY 8 => 1, # SQL_FETCH_DIRECTION 84 => 0, # SQL_FILE_USAGE 146 => 73217, # SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1 147 => 2176, # SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2 81 => 15, # SQL_GETDATA_EXTENSIONS 88 => 2, # SQL_GROUP_BY 28 => 2, # SQL_IDENTIFIER_CASE 29 => \&sql_identquote, # SQL_IDENTIFIER_QUOTE_CHAR 148 => 3, # SQL_INDEX_KEYWORDS 149 => 0, # SQL_INFO_SCHEMA_VIEWS 172 => 7, # SQL_INSERT_STATEMENT 73 => 'N', # SQL_INTEGRITY 150 => 0, # SQL_KEYSET_CURSOR_ATTRIBUTES1 151 => 0, # SQL_KEYSET_CURSOR_ATTRIBUTES2 # 89 => undef, # SQL_KEYWORDS 113 => 'Y', # SQL_LIKE_ESCAPE_CLAUSE 78 => 1, # SQL_LOCK_TYPES 34 => 128, # SQL_MAXIMUM_CATALOG_NAME_LENGTH 97 => 0, # SQL_MAXIMUM_COLUMNS_IN_GROUP_BY 98 => 16, # SQL_MAXIMUM_COLUMNS_IN_INDEX 99 => 0, # SQL_MAXIMUM_COLUMNS_IN_ORDER_BY 100 => 0, # SQL_MAXIMUM_COLUMNS_IN_SELECT 101 => 0, # SQL_MAXIMUM_COLUMNS_IN_TABLE 30 => 128, # SQL_MAXIMUM_COLUMN_NAME_LENGTH 1 => 0, # SQL_MAXIMUM_CONCURRENT_ACTIVITIES 31 => 128, # SQL_MAXIMUM_CURSOR_NAME_LENGTH 0 => 0, # SQL_MAXIMUM_DRIVER_CONNECTIONS 10005 => 128, # SQL_MAXIMUM_IDENTIFIER_LENGTH 102 => 255, # SQL_MAXIMUM_INDEX_SIZE 104 => 32767, # SQL_MAXIMUM_ROW_SIZE 32 => 32, # SQL_MAXIMUM_SCHEMA_NAME_LENGTH 105 => 0, # SQL_MAXIMUM_STATEMENT_LENGTH # 20000 => undef, # SQL_MAXIMUM_STMT_OCTETS # 20001 => undef, # SQL_MAXIMUM_STMT_OCTETS_DATA # 20002 => undef, # SQL_MAXIMUM_STMT_OCTETS_SCHEMA 106 => 0, # SQL_MAXIMUM_TABLES_IN_SELECT 35 => 128, # SQL_MAXIMUM_TABLE_NAME_LENGTH 107 => 32, # SQL_MAXIMUM_USER_NAME_LENGTH 10022 => 0, # SQL_MAX_ASYNC_CONCURRENT_STATEMENTS 112 => 0, # SQL_MAX_BINARY_LITERAL_LEN 34 => 128, # SQL_MAX_CATALOG_NAME_LEN 108 => 0, # SQL_MAX_CHAR_LITERAL_LEN 97 => 0, # SQL_MAX_COLUMNS_IN_GROUP_BY 98 => 16, # SQL_MAX_COLUMNS_IN_INDEX 99 => 0, # SQL_MAX_COLUMNS_IN_ORDER_BY 100 => 0, # SQL_MAX_COLUMNS_IN_SELECT 101 => 0, # SQL_MAX_COLUMNS_IN_TABLE 30 => 128, # SQL_MAX_COLUMN_NAME_LEN 1 => 0, # SQL_MAX_CONCURRENT_ACTIVITIES 31 => 128, # SQL_MAX_CURSOR_NAME_LEN 0 => 0, # SQL_MAX_DRIVER_CONNECTIONS 10005 => 128, # SQL_MAX_IDENTIFIER_LEN 102 => 255, # SQL_MAX_INDEX_SIZE 32 => 32, # SQL_MAX_OWNER_NAME_LEN 33 => 128, # SQL_MAX_PROCEDURE_NAME_LEN 34 => 128, # SQL_MAX_QUALIFIER_NAME_LEN 104 => 32767, # SQL_MAX_ROW_SIZE 103 => 'N', # SQL_MAX_ROW_SIZE_INCLUDES_LONG 32 => 32, # SQL_MAX_SCHEMA_NAME_LEN 105 => 0, # SQL_MAX_STATEMENT_LEN 106 => 0, # SQL_MAX_TABLES_IN_SELECT 35 => 128, # SQL_MAX_TABLE_NAME_LEN 107 => 32, # SQL_MAX_USER_NAME_LEN 37 => 'y', # SQL_MULTIPLE_ACTIVE_TXN 36 => 'N', # SQL_MULT_RESULT_SETS 111 => 'Y', # SQL_NEED_LONG_DATA_LEN 75 => 1, # SQL_NON_NULLABLE_COLUMNS 85 => 1, # SQL_NULL_COLLATION 49 => 14216543, # SQL_NUMERIC_FUNCTIONS 9 => 1, # SQL_ODBC_API_CONFORMANCE 152 => 1, # SQL_ODBC_INTERFACE_CONFORMANCE 12 => 1, # SQL_ODBC_SAG_CLI_CONFORMANCE 15 => 1, # SQL_ODBC_SQL_CONFORMANCE 73 => 'N', # SQL_ODBC_SQL_OPT_IEF 10 => '-1', # SQL_ODBC_VER 115 => 107, # SQL_OJ_CAPABILITIES 90 => 'Y', # SQL_ORDER_BY_COLUMNS_IN_SELECT 38 => 'Y', # SQL_OUTER_JOINS 115 => 107, # SQL_OUTER_JOIN_CAPABILITIES 39 => 'owner', # SQL_OWNER_TERM 91 => 31, # SQL_OWNER_USAGE 153 => 2, # SQL_PARAM_ARRAY_ROW_COUNTS 154 => 3, # SQL_PARAM_ARRAY_SELECTS 80 => 7, # SQL_POSITIONED_STATEMENTS 79 => 30, # SQL_POS_OPERATIONS 21 => \&sql_storedprocs, # SQL_PROCEDURES 40 => 'procedure', # SQL_PROCEDURE_TERM 114 => 1, # SQL_QUALIFIER_LOCATION 41 => ':', # SQL_QUALIFIER_NAME_SEPARATOR 42 => 'database', # SQL_QUALIFIER_TERM 92 => 1, # SQL_QUALIFIER_USAGE 93 => 2, # SQL_QUOTED_IDENTIFIER_CASE 11 => 'N', # SQL_ROW_UPDATES 39 => 'owner', # SQL_SCHEMA_TERM 91 => 31, # SQL_SCHEMA_USAGE 43 => 3, # SQL_SCROLL_CONCURRENCY 44 => 1, # SQL_SCROLL_OPTIONS 14 => '\\', # SQL_SEARCH_PATTERN_ESCAPE 13 => \&sql_servername, # SQL_SERVER_NAME 94 => '', # SQL_SPECIAL_CHARACTERS 155 => 0, # SQL_SQL92_DATETIME_FUNCTIONS 156 => 0, # SQL_SQL92_FOREIGN_KEY_DELETE_RULE 157 => 0, # SQL_SQL92_FOREIGN_KEY_UPDATE_RULE 158 => 0, # SQL_SQL92_GRANT 159 => 0, # SQL_SQL92_NUMERIC_VALUE_FUNCTIONS 160 => 0, # SQL_SQL92_PREDICATES 161 => 0, # SQL_SQL92_RELATIONAL_JOIN_OPERATORS 162 => 96, # SQL_SQL92_REVOKE 163 => 0, # SQL_SQL92_ROW_VALUE_CONSTRUCTOR 164 => 0, # SQL_SQL92_STRING_FUNCTIONS 165 => 0, # SQL_SQL92_VALUE_EXPRESSIONS 118 => 1, # SQL_SQL_CONFORMANCE 166 => 3, # SQL_STANDARD_CLI_CONFORMANCE 167 => 7681, # SQL_STATIC_CURSOR_ATTRIBUTES1 168 => 0, # SQL_STATIC_CURSOR_ATTRIBUTES2 83 => 0, # SQL_STATIC_SENSITIVITY 50 => 7348061, # SQL_STRING_FUNCTIONS 95 => 31, # SQL_SUBQUERIES 51 => 7, # SQL_SYSTEM_FUNCTIONS 45 => 'table', # SQL_TABLE_TERM 109 => 0, # SQL_TIMEDATE_ADD_INTERVALS 110 => 0, # SQL_TIMEDATE_DIFF_INTERVALS 52 => 1016623, # SQL_TIMEDATE_FUNCTIONS 46 => \&sql_txnsup, # SQL_TRANSACTION_CAPABLE 72 => \&sql_txniso, # SQL_TRANSACTION_ISOLATION_OPTION 46 => \&sql_txnsup, # SQL_TXN_CAPABLE 72 => \&sql_txniso, # SQL_TXN_ISOLATION_OPTION 96 => 3, # SQL_UNION 96 => 3, # SQL_UNION_STATEMENT 47 => \&sql_user_name, # SQL_USER_NAME 10000 => 1995, # SQL_XOPEN_CLI_YEAR ); 1; __END__ =head1 NAME DBD::Informix::GetInfo - Determining your ESQL/C Configuration =head1 SYNOPSIS use DBI; =head1 DESCRIPTION This module is used by IBM Informix Database Driver for Perl DBI Version 2008.0513 (2008-05-13) if you invoke the DBI metadata methods on a DBD::Informix handle. You will seldom if ever have cause to use this module directly. As noted above, this script was originally generated by using a pre-release of the DBI::DBD::write_getinfo_pm method, which invokes an ODBC driver for the DBMS and interprets the results. The output was then modified a lot to take into account the extreme variability in the correct answers for Informix database servers. =head1 AUTHOR Jonathan Leffler =cut