From 3afb89d8bff9a38c988d7da89e3d1133fe3aeb3b Mon Sep 17 00:00:00 2001 From: Bernd Helmle Date: Fri, 11 May 2018 15:25:35 +0200 Subject: [PATCH] Change the way we handle connection warnings. Originally we just checked the various SQLCA fields for any 'W' flag set to determine the database features during ifxCreateConnectionXact() and ifxSetConnection(). Now check if any SQLCA warning is set first (SQLCA_WARN_SET), and do the check for any feature warnings only if true. I'm not sure the former behavior was even correct, since it is not obvious when SQLCA warning fields get cleared overall. This commit also adds an is_obsolete field to IfxConnectionInfo connection structure, to remember wether ifxCreateConnectionXact() or ifxSetConnection() got a connection to an obsolete Informix instance version. I'm planning to use this information later, when attacking the bug reported in #19, where IMPORT FOREIGN SCHEMA isn't able to import the table schemas from Informix SE instances, since they don't support extended data types (e.g. sqlxtdtypes). --- ifx_connection.ec | 72 ++++++++++++++++++++++++++++++++++++++--------- ifx_fdw.c | 12 ++++++-- ifx_type_compat.h | 2 ++ 3 files changed, 70 insertions(+), 16 deletions(-) diff --git a/ifx_connection.ec b/ifx_connection.ec index 0c89c02..73129eb 100644 --- a/ifx_connection.ec +++ b/ifx_connection.ec @@ -84,14 +84,36 @@ void ifxCreateConnectionXact(IfxConnectionInfo *coninfo) EXEC SQL CONNECT TO :ifxdsn AS :ifxconname USER :ifxuser USING :ifxpass WITH CONCURRENT TRANSACTION; - if (ifxGetSQLCAWarn(SQLCA_WARN_TRANSACTIONS) == 'W') - { - /* save state into connection info */ - coninfo->tx_enabled = 1; - } + if (ifxGetSQLCAWarn(SQLCA_WARN_SET) == 'W') { + + if (ifxGetSQLCAWarn(SQLCA_WARN_TRANSACTIONS) == 'W') + { + /* save state into connection info */ + coninfo->tx_enabled = 1; + } + + if (ifxGetSQLCAWarn(SQLCA_WARN_ANSI) == 'W') { + /* ANSI compliant database */ + coninfo->db_ansi = 1; + } - if (ifxGetSQLCAWarn(SQLCA_WARN_ANSI) == 'W') - coninfo->db_ansi = 1; + if (ifxGetSQLCAWarn(SQLCA_WARN_NO_IFX_SE) == 'W') { + /* connected to an non-SE instance */ + coninfo->is_obsolete = 0; + } else { + + /* SQLCA_WARN_NO_IFX_SE is not set, assume SE instance */ + coninfo->is_obsolete = 1; + } + + } else { + + /* + * If no warning was set, we implicitely assume an Informix SE + * instance + */ + coninfo->is_obsolete = 1; + } } int ifxStartTransaction(IfxPGCachedConnection *cached, IfxConnectionInfo *coninfo) @@ -477,6 +499,7 @@ int ifxSetConnectionIdent(char *conname) void ifxSetConnection(IfxConnectionInfo *coninfo) { + EXEC SQL BEGIN DECLARE SECTION; char *ifxconname; EXEC SQL END DECLARE SECTION; @@ -489,14 +512,37 @@ void ifxSetConnection(IfxConnectionInfo *coninfo) ifxconname = coninfo->conname; EXEC SQL SET CONNECTION :ifxconname; - if (ifxGetSQLCAWarn(SQLCA_WARN_TRANSACTIONS) == 'W') - { - /* save state into connection info */ - coninfo->tx_enabled = 1; + if (ifxGetSQLCAWarn(SQLCA_WARN_SET) == 'W') { + + if (ifxGetSQLCAWarn(SQLCA_WARN_TRANSACTIONS) == 'W') + { + /* save state into connection info */ + coninfo->tx_enabled = 1; + } + + if (ifxGetSQLCAWarn(SQLCA_WARN_ANSI) == 'W') { + /* ANSI compliant database */ + coninfo->db_ansi = 1; + } + + if (ifxGetSQLCAWarn(SQLCA_WARN_NO_IFX_SE) == 'W') { + /* if 'W' was set, an non-SE instance was detected */ + coninfo->is_obsolete = 0; + } else { + + /* SQLCA_WARN_NO_IFX_SE is not set, assume SE instance */ + coninfo->is_obsolete = 1; + } + + } else { + + /* + * If no warning was set, we implicitely assume an Informix SE + * instance + */ + coninfo->is_obsolete = 1; } - if (ifxGetSQLCAWarn(SQLCA_WARN_ANSI) == 'W') - coninfo->db_ansi = 1; } void ifxPrepareQuery(char *query, char *stmt_name) diff --git a/ifx_fdw.c b/ifx_fdw.c index e6980da..d592356 100644 --- a/ifx_fdw.c +++ b/ifx_fdw.c @@ -2523,7 +2523,8 @@ static IfxCachedConnection * ifxSetupConnection(IfxConnectionInfo **coninfo, /* * Give a warning if we have mismatching DBLOCALE settings. */ - if (ifxGetSQLCAWarn(SQLCA_WARN_DB_LOCALE_MISMATCH) == 'W') + if ((ifxGetSQLCAWarn(SQLCA_WARN_SET) == 'W') + && (ifxGetSQLCAWarn(SQLCA_WARN_DB_LOCALE_MISMATCH) == 'W')) elog(WARNING, "mismatching DBLOCALE \"%s\"", (*coninfo)->db_locale); @@ -2531,8 +2532,8 @@ static IfxCachedConnection * ifxSetupConnection(IfxConnectionInfo **coninfo, * Give a NOTICE in case this is an INFORMIX SE * database instance. */ - if (ifxGetSQLCAWarn(SQLCA_WARN_NO_IFX_SE) == 'W') - elog(NOTICE, "connected to an non-Informix SE instance"); + if ((*coninfo)->is_obsolete == 1) + elog(NOTICE, "connected to a Informix SE instance"); return cached_handle; } @@ -5214,6 +5215,11 @@ static void ifxConnInfoSetDefaults(IfxConnectionInfo *coninfo) coninfo->username = "\0"; coninfo->password = "\0"; + /* + * per default assume non-SE informix instance. + */ + coninfo->is_obsolete = 0; + /* default scan mode */ coninfo->scan_mode = IFX_PLAN_SCAN; } diff --git a/ifx_type_compat.h b/ifx_type_compat.h index e8910b3..f554e85 100644 --- a/ifx_type_compat.h +++ b/ifx_type_compat.h @@ -265,6 +265,7 @@ typedef enum IfxExtendedType IFX_XTD_DBSENDRECV = 21, IFX_XTD_SRVSENDRECV = 22, IFX_XTD_FUNCARG = 23 + } IfxExtendedType; /* @@ -439,6 +440,7 @@ typedef struct IfxConnectionInfo short tx_enabled; /* 0 = n tx, 1 = tx enabled */ int xact_level; /* current nest level of transactions */ short db_ansi; /* 0 = non-ANSI database, 1 = ANSI-enabled database */ + short is_obsolete; /* currently: 0 = non SE instance, 1 = Informix SE instance */ short predicate_pushdown; /* 0 = disabled, 1 = enabled */ short enable_blobs; /* 0 = no special BLOB support, 1 = special BLOB support */