#   @(#)$Id: GetInfo.pm,v 2018.1 2018/05/11 18:33:03 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-18 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
# (Informix Database Driver for Perl DBI Version 2018.1031 (2018-10-31))
#-------------------------------------------------------------------------
#
# 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 warnings;
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 = "2018.1031";
# 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 Informix Database Driver for Perl DBI Version 2018.1031 (2018-10-31) 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