aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/interfaces/odbc/columninfo.c2
-rw-r--r--src/interfaces/odbc/connection.c37
-rw-r--r--src/interfaces/odbc/connection.h38
-rw-r--r--src/interfaces/odbc/drvconn.c2
-rw-r--r--src/interfaces/odbc/info.c54
-rw-r--r--src/interfaces/odbc/psqlodbc.h4
-rw-r--r--src/interfaces/odbc/psqlodbc.rc8
7 files changed, 117 insertions, 28 deletions
diff --git a/src/interfaces/odbc/columninfo.c b/src/interfaces/odbc/columninfo.c
index fa56824011d..9e5223b83b3 100644
--- a/src/interfaces/odbc/columninfo.c
+++ b/src/interfaces/odbc/columninfo.c
@@ -81,7 +81,7 @@ ConnInfo *ci;
new_adtsize = (Int2) SOCK_get_int(sock, 2);
/* If 6.4 protocol, then read the atttypmod field */
- if ( ! PROTOCOL_63(ci) && ! PROTOCOL_62(ci)) {
+ if (PG_VERSION_GE(conn, 6.4)) {
mylog("READING ATTTYPMOD\n");
new_atttypmod = (Int4) SOCK_get_int(sock, 4);
diff --git a/src/interfaces/odbc/connection.c b/src/interfaces/odbc/connection.c
index fe1344df8ab..98fbca2f794 100644
--- a/src/interfaces/odbc/connection.c
+++ b/src/interfaces/odbc/connection.c
@@ -98,6 +98,8 @@ static char *func = "SQLConnect";
/* get the values for the DSN from the registry */
getDSNinfo(ci, CONN_OVERWRITE);
+ /* initialize pg_version from connInfo.protocol */
+ CC_initialize_pg_version(conn);
/* override values from DSN info with UID and authStr(pwd)
This only occurs if the values are actually there.
@@ -253,6 +255,10 @@ ConnectionClass *rv;
rv->translation_handle = NULL;
rv->DataSourceToDriver = NULL;
rv->DriverToDataSource = NULL;
+ memset(rv->pg_version, 0, sizeof(rv->pg_version));
+ rv->pg_version_number = .0;
+ rv->pg_version_major = 0;
+ rv->pg_version_minor = 0;
/* Initialize statement options to defaults */
@@ -1365,6 +1371,28 @@ static char *func = "CC_lookup_lo";
result = SQLFreeStmt(hstmt, SQL_DROP);
}
+/* This function initializes the version of PostgreSQL from
+ connInfo.protocol that we're connected to.
+ h-inoue 01-2-2001
+*/
+void
+CC_initialize_pg_version(ConnectionClass *self)
+{
+ strcpy(self->pg_version, self->connInfo.protocol);
+ if (PROTOCOL_62(&self->connInfo)) {
+ self->pg_version_number = (float) 6.2;
+ self->pg_version_major = 6;
+ self->pg_version_minor = 2;
+ } else if (PROTOCOL_63(&self->connInfo)) {
+ self->pg_version_number = (float) 6.3;
+ self->pg_version_major = 6;
+ self->pg_version_minor = 3;
+ } else {
+ self->pg_version_number = (float) 6.4;
+ self->pg_version_major = 6;
+ self->pg_version_minor = 4;
+ }
+}
/* This function gets the version of PostgreSQL that we're connected to.
This is used to return the correct info in SQLGetInfo
DJP - 25-1-2001
@@ -1376,6 +1404,7 @@ HSTMT hstmt;
StatementClass *stmt;
RETCODE result;
char *szVersion = "0.0";
+int major, minor;
static char *func = "CC_lookup_pg_version";
mylog( "%s: entering...\n", func);
@@ -1389,6 +1418,7 @@ static char *func = "CC_lookup_pg_version";
}
stmt = (StatementClass *) hstmt;
+ /* get the server's version if possible */
result = SQLExecDirect(hstmt, "select version()", SQL_NTS);
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
SQLFreeStmt(hstmt, SQL_DROP);
@@ -1407,10 +1437,13 @@ static char *func = "CC_lookup_pg_version";
return;
}
- /* There's proably a nicer way of doing this... */
/* Extract the Major and Minor numbers from the string. */
/* This assumes the string starts 'Postgresql X.X' */
- sprintf(szVersion, "%c.%c", self->pg_version[11], self->pg_version[13]);
+ if (sscanf(self->pg_version, "%*s %d.%d", &major, &minor) >= 2) {
+ sprintf(szVersion, "%d.%d", major, minor);
+ self->pg_version_major = major;
+ self->pg_version_minor = minor;
+ }
self->pg_version_number = (float) atof(szVersion);
mylog("Got the PostgreSQL version string: '%s'\n", self->pg_version);
diff --git a/src/interfaces/odbc/connection.h b/src/interfaces/odbc/connection.h
index 8251271a05c..8222d985180 100644
--- a/src/interfaces/odbc/connection.h
+++ b/src/interfaces/odbc/connection.h
@@ -163,6 +163,41 @@ typedef struct {
/* Macro to determine is the connection using 6.3 protocol? */
#define PROTOCOL_63(conninfo_) (strncmp((conninfo_)->protocol, PG63, strlen(PG63)) == 0)
+/*
+ * Macros to compare the server's version with a specified version
+ * 1st parameter: pointer to a ConnectionClass object
+ * 2nd parameter: major version number
+ * 3rd parameter: minor version number
+ */
+#define SERVER_VERSION_GT(conn, major, minor) \
+ ((conn)->pg_version_major > major || \
+ ((conn)->pg_version_major == major && (conn)->pg_version_minor > minor))
+#define SERVER_VERSION_GE(conn, major, minor) \
+ ((conn)->pg_version_major > major || \
+ ((conn)->pg_version_major == major && (conn)->pg_version_minor >= minor))
+#define SERVER_VERSION_EQ(conn, major, minor) \
+ ((conn)->pg_version_major == major && (conn)->pg_version_minor == minor)
+#define SERVER_VERSION_LE(conn, major, minor) (! SERVER_VERSION_GT(conn, major, minor))
+#define SERVER_VERSION_LT(conn, major, minor) (! SERVER_VERSION_GE(conn, major, minor))
+/*#if ! defined(HAVE_CONFIG_H) || defined(HAVE_STRINGIZE)*/
+#define STRING_AFTER_DOT(string) (strchr(#string, '.') + 1)
+/*#else
+#define STRING_AFTER_DOT(str) (strchr("str", '.') + 1)
+#endif*/
+/*
+ * Simplified macros to compare the server's version with a
+ * specified version
+ * Note: Never pass a variable as the second parameter.
+ * It must be a decimal constant of the form %d.%d .
+ */
+#define PG_VERSION_GT(conn, ver) \
+ (SERVER_VERSION_GT(conn, (int) ver, atoi(STRING_AFTER_DOT(ver))))
+#define PG_VERSION_GE(conn, ver) \
+ (SERVER_VERSION_GE(conn, (int) ver, atoi(STRING_AFTER_DOT(ver))))
+#define PG_VERSION_EQ(conn, ver) \
+ (SERVER_VERSION_EQ(conn, (int) ver, atoi(STRING_AFTER_DOT(ver))))
+#define PG_VERSION_LE(conn, ver) (! PG_VERSION_GT(conn, ver))
+#define PG_VERSION_LT(conn, ver) (! PG_VERSION_GE(conn, ver))
/* This is used to store cached table information in the connection */
struct col_info {
@@ -223,6 +258,8 @@ struct ConnectionClass_ {
char errormsg_created; /* has an informative error msg been created? */
char pg_version[MAX_INFO_STRING]; /* Version of PostgreSQL we're connected to - DJP 25-1-2001 */
float pg_version_number;
+ Int2 pg_version_major;
+ Int2 pg_version_minor;
};
@@ -258,6 +295,7 @@ int CC_send_function(ConnectionClass *conn, int fnid, void *result_buf, int *act
char CC_send_settings(ConnectionClass *self);
void CC_lookup_lo(ConnectionClass *conn);
void CC_lookup_pg_version(ConnectionClass *conn);
+void CC_initialize_pg_version(ConnectionClass *conn);
void CC_log_error(char *func, char *desc, ConnectionClass *self);
diff --git a/src/interfaces/odbc/drvconn.c b/src/interfaces/odbc/drvconn.c
index 332ccc5cbb1..2cbe6e6a87a 100644
--- a/src/interfaces/odbc/drvconn.c
+++ b/src/interfaces/odbc/drvconn.c
@@ -113,6 +113,8 @@ int len = 0;
/* Fill in any default parameters if they are not there. */
getDSNdefaults(ci);
+ /* initialize pg_version */
+ CC_initialize_pg_version(conn);
#ifdef WIN32
dialog:
diff --git a/src/interfaces/odbc/info.c b/src/interfaces/odbc/info.c
index 681c72759d0..bf43d6522b5 100644
--- a/src/interfaces/odbc/info.c
+++ b/src/interfaces/odbc/info.c
@@ -69,7 +69,7 @@ RETCODE SQL_API SQLGetInfo(
static char *func = "SQLGetInfo";
ConnectionClass *conn = (ConnectionClass *) hdbc;
ConnInfo *ci;
-char *p = NULL;
+char *p = NULL, tmp[MAX_INFO_STRING];
int len = 0, value = 0;
RETCODE result;
@@ -193,9 +193,8 @@ RETCODE result;
case SQL_DBMS_VER: /* ODBC 1.0 */
/* The ODBC spec wants ##.##.#### ...whatever... so prepend the driver */
/* version number to the dbms version string */
- p = POSTGRESDRIVERVERSION;
- strcat(p, " ");
- strcat(p, conn->pg_version);
+ sprintf(tmp, "%s %s", POSTGRESDRIVERVERSION, conn->pg_version);
+ p = tmp;
break;
case SQL_DEFAULT_TXN_ISOLATION: /* ODBC 1.0 */
@@ -255,7 +254,7 @@ RETCODE result;
case SQL_IDENTIFIER_QUOTE_CHAR: /* ODBC 1.0 */
/* the character used to quote "identifiers" */
- p = PROTOCOL_62(ci) ? " " : "\"";
+ p = PG_VERSION_LE(conn, 6.2) ? " " : "\"";
break;
case SQL_KEYWORDS: /* ODBC 2.0 */
@@ -341,7 +340,7 @@ RETCODE result;
case SQL_MAX_ROW_SIZE: /* ODBC 2.0 */
len = 4;
- if (conn->pg_version_number >= (float) 7.1) { /* Large Rowa in 7.1+ */
+ if (PG_VERSION_GE(conn, 7.1)) { /* Large Rowa in 7.1+ */
value = MAX_ROW_SIZE;
} else { /* Without the Toaster we're limited to the blocksize */
value = BLCKSZ;
@@ -358,11 +357,13 @@ RETCODE result;
case SQL_MAX_STATEMENT_LEN: /* ODBC 2.0 */
/* maybe this should be 0? */
len = 4;
- if (conn->pg_version_number >= (float) 7.0) { /* Long Queries in 7.0+ */
+ if (PG_VERSION_GE(conn, 7.0)) { /* Long Queries in 7.0+ */
value = MAX_STATEMENT_LEN;
- } else { /* Prior to 7.0 we used 2*BLCKSZ */
+ } else if (PG_VERSION_GE(conn, 6.5)) /* Prior to 7.0 we used 2*BLCKSZ */
value = (2*BLCKSZ);
- }
+ else /* Prior to 6.5 we used BLCKSZ */
+ value = BLCKSZ;
+
break;
case SQL_MAX_TABLE_NAME_LEN: /* ODBC 1.0 */
@@ -431,7 +432,7 @@ RETCODE result;
case SQL_OJ_CAPABILITIES: /* ODBC 2.01 */
len = 4;
- if (conn->pg_version_number >= (float) 7.1) { /* OJs in 7.1+ */
+ if (PG_VERSION_GE(conn, 7.1)) { /* OJs in 7.1+ */
value = (SQL_OJ_LEFT |
SQL_OJ_RIGHT |
SQL_OJ_FULL |
@@ -445,11 +446,11 @@ RETCODE result;
break;
case SQL_ORDER_BY_COLUMNS_IN_SELECT: /* ODBC 2.0 */
- p = (PROTOCOL_62(ci) || PROTOCOL_63(ci)) ? "Y" : "N";
+ p = (PG_VERSION_LE(conn, 6.3)) ? "Y" : "N";
break;
case SQL_OUTER_JOINS: /* ODBC 1.0 */
- if (conn->pg_version_number >= (float) 7.1) { /* OJs in 7.1+ */
+ if (PG_VERSION_GE(conn, 7.1)) { /* OJs in 7.1+ */
p = "Y";
} else { /* OJs not in <7.1 */
p = "N";
@@ -937,7 +938,8 @@ HSTMT htbl_stmt;
RETCODE result;
char *tableType;
char tables_query[STD_STATEMENT_LEN];
-char table_name[MAX_INFO_STRING], table_owner[MAX_INFO_STRING], relhasrules[MAX_INFO_STRING];
+char table_name[MAX_INFO_STRING], table_owner[MAX_INFO_STRING], relkind_or_hasrules[MAX_INFO_STRING];
+ConnectionClass *conn;
ConnInfo *ci;
char *prefix[32], prefixes[MEDIUM_REGISTRY_LEN];
char *table_type[32], table_types[MAX_INFO_STRING];
@@ -955,6 +957,7 @@ mylog("%s: entering...stmt=%u\n", func, stmt);
stmt->manual_result = TRUE;
stmt->errormsg_created = TRUE;
+ conn = (ConnectionClass *) (stmt->hdbc);
ci = &stmt->hdbc->connInfo;
result = SQLAllocStmt( stmt->hdbc, &htbl_stmt);
@@ -970,8 +973,14 @@ mylog("%s: entering...stmt=%u\n", func, stmt);
/* Create the query to find out the tables */
/* ********************************************************************** */
- strcpy(tables_query, "select relname, usename, relhasrules from pg_class, pg_user");
- strcat(tables_query, " where relkind = 'r'");
+ if (PG_VERSION_GE(conn, 7.1)) { /* view is represented by its relkind since 7.1 */
+ strcpy(tables_query, "select relname, usename, relkind from pg_class, pg_user");
+ strcat(tables_query, " where relkind in ('r', 'v')");
+ }
+ else {
+ strcpy(tables_query, "select relname, usename, relhasrules from pg_class, pg_user");
+ strcat(tables_query, " where relkind = 'r'");
+ }
my_strcat(tables_query, " and usename like '%.*s'", szTableOwner, cbTableOwner);
my_strcat(tables_query, " and relname like '%.*s'", szTableName, cbTableName);
@@ -1039,6 +1048,9 @@ mylog("%s: entering...stmt=%u\n", func, stmt);
/* match users */
+ if (PG_VERSION_LT(conn, 7.1)) /* filter out large objects in older versions */
+ strcat(tables_query, " and relname !~ '^xinv[0-9]+'");
+
strcat(tables_query, " and usesysid = relowner");
strcat(tables_query, " order by relname");
@@ -1073,7 +1085,7 @@ mylog("%s: entering...stmt=%u\n", func, stmt);
return SQL_ERROR;
}
result = SQLBindCol(htbl_stmt, 3, SQL_C_CHAR,
- relhasrules, MAX_INFO_STRING, NULL);
+ relkind_or_hasrules, MAX_INFO_STRING, NULL);
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errormsg = tbl_stmt->errormsg;
stmt->errornumber = tbl_stmt->errornumber;
@@ -1131,7 +1143,10 @@ mylog("%s: entering...stmt=%u\n", func, stmt);
}
/* Determine if the table name is a view */
- view = (relhasrules[0] == '1');
+ if (PG_VERSION_GE(conn, 7.1)) /* view is represented by its relkind since 7.1 */
+ view = (relkind_or_hasrules[0] == 'v');
+ else
+ view = (relkind_or_hasrules[0] == '1');
/* It must be a regular table */
regular_table = ( ! systable && ! view);
@@ -1214,6 +1229,7 @@ Int4 field_type, the_type, field_length, mod_length, precision;
char useStaticPrecision;
char not_null[MAX_INFO_STRING], relhasrules[MAX_INFO_STRING];
ConnInfo *ci;
+ConnectionClass *conn;
mylog("%s: entering...stmt=%u\n", func, stmt);
@@ -1226,6 +1242,7 @@ ConnInfo *ci;
stmt->manual_result = TRUE;
stmt->errormsg_created = TRUE;
+ conn = (ConnectionClass *) (stmt->hdbc);
ci = &stmt->hdbc->connInfo;
/* ********************************************************************** */
@@ -1236,7 +1253,7 @@ ConnInfo *ci;
" from pg_user u, pg_class c, pg_attribute a, pg_type t"
" where u.usesysid = c.relowner"
" and c.oid= a.attrelid and a.atttypid = t.oid and (a.attnum > 0)",
- PROTOCOL_62(ci) ? "a.attlen" : "a.atttypmod");
+ PG_VERSION_LE(conn, 6.2) ? "a.attlen" : "a.atttypmod");
my_strcat(columns_query, " and c.relname like '%.*s'", szTableName, cbTableName);
my_strcat(columns_query, " and u.usename like '%.*s'", szTableOwner, cbTableOwner);
@@ -2315,7 +2332,6 @@ Int2 result_cols;
stmt->errormsg = "Couldn't allocate memory for SQLForeignKeys result.";
stmt->errornumber = STMT_NO_MEMORY_ERROR;
SC_log_error(func, "", stmt);
- SQLFreeStmt(htbl_stmt, SQL_DROP);
return SQL_ERROR;
}
diff --git a/src/interfaces/odbc/psqlodbc.h b/src/interfaces/odbc/psqlodbc.h
index b0d8539eb79..54fd4e2eeae 100644
--- a/src/interfaces/odbc/psqlodbc.h
+++ b/src/interfaces/odbc/psqlodbc.h
@@ -6,7 +6,7 @@
*
* Comments: See "notice.txt" for copyright and license information.
*
- * $Id: psqlodbc.h,v 1.29 2001/01/26 22:41:59 momjian Exp $
+ * $Id: psqlodbc.h,v 1.30 2001/02/06 02:21:12 inoue Exp $
*/
#ifndef __PSQLODBC_H__
@@ -41,7 +41,7 @@ typedef UInt4 Oid;
#define DRIVERNAME "PostgreSQL ODBC"
#define DBMS_NAME "PostgreSQL"
-#define POSTGRESDRIVERVERSION "07.01.0001"
+#define POSTGRESDRIVERVERSION "07.01.0002"
#ifdef WIN32
#define DRIVER_FILE_NAME "PSQLODBC.DLL"
diff --git a/src/interfaces/odbc/psqlodbc.rc b/src/interfaces/odbc/psqlodbc.rc
index 1d934106d3b..503b478372a 100644
--- a/src/interfaces/odbc/psqlodbc.rc
+++ b/src/interfaces/odbc/psqlodbc.rc
@@ -204,8 +204,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 7,1,0,1
- PRODUCTVERSION 7,1,0,1
+ FILEVERSION 7,1,0,2
+ PRODUCTVERSION 7,1,0,2
FILEFLAGSMASK 0x3L
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -223,14 +223,14 @@ BEGIN
VALUE "Comments", "PostgreSQL ODBC driver\0"
VALUE "CompanyName", "Insight Distribution Systems\0"
VALUE "FileDescription", "PostgreSQL Driver\0"
- VALUE "FileVersion", " 07.01.0001\0"
+ VALUE "FileVersion", " 07.01.0002\0"
VALUE "InternalName", "psqlodbc\0"
VALUE "LegalCopyright", "\0"
VALUE "LegalTrademarks", "ODBC(TM) is a trademark of Microsoft Corporation. Microsoft® is a registered trademark of Microsoft Corporation. Windows(TM) is a trademark of Microsoft Corporation.\0"
VALUE "OriginalFilename", "psqlodbc.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "Microsoft Open Database Connectivity\0"
- VALUE "ProductVersion", " 07.01.0001\0"
+ VALUE "ProductVersion", " 07.01.0002\0"
VALUE "SpecialBuild", "\0"
END
END