Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 5d08521

Browse files
author
Hiroshi Inoue
committed
Improved version handling introduced by Dave Page.
The driver version is 07.01.0002 now. 1) initialized pg_version by DSN's protocol info so that we could always use pg_version info once a connection is established (pg_version() didn't exist before 6.4). PROTOCOL_XX() macros are removed(except from connection.[ch]). 2) provided a few macros to encapsulate connection's version info and replaced existent comparison stuff by those macros. 3) change SQLTables() so that 7.1 servers could show views. In addtion, the following patch from Dave Page is applied. This patch fixes a bug in SQLGetInfo for SQL_DBMS_VER which corrupted the driver version string. The driver version number has also been incremented to 07.01.0002. Regards, Dave. <<odbc.diff>>
1 parent 300e288 commit 5d08521

File tree

7 files changed

+117
-28
lines changed

7 files changed

+117
-28
lines changed

src/interfaces/odbc/columninfo.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ ConnInfo *ci;
8181
new_adtsize = (Int2) SOCK_get_int(sock, 2);
8282

8383
/* If 6.4 protocol, then read the atttypmod field */
84-
if ( ! PROTOCOL_63(ci) && ! PROTOCOL_62(ci)) {
84+
if (PG_VERSION_GE(conn, 6.4)) {
8585

8686
mylog("READING ATTTYPMOD\n");
8787
new_atttypmod = (Int4) SOCK_get_int(sock, 4);

src/interfaces/odbc/connection.c

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ static char *func = "SQLConnect";
9898

9999
/* get the values for the DSN from the registry */
100100
getDSNinfo(ci, CONN_OVERWRITE);
101+
/* initialize pg_version from connInfo.protocol */
102+
CC_initialize_pg_version(conn);
101103

102104
/* override values from DSN info with UID and authStr(pwd)
103105
This only occurs if the values are actually there.
@@ -253,6 +255,10 @@ ConnectionClass *rv;
253255
rv->translation_handle = NULL;
254256
rv->DataSourceToDriver = NULL;
255257
rv->DriverToDataSource = NULL;
258+
memset(rv->pg_version, 0, sizeof(rv->pg_version));
259+
rv->pg_version_number = .0;
260+
rv->pg_version_major = 0;
261+
rv->pg_version_minor = 0;
256262

257263

258264
/* Initialize statement options to defaults */
@@ -1365,6 +1371,28 @@ static char *func = "CC_lookup_lo";
13651371
result = SQLFreeStmt(hstmt, SQL_DROP);
13661372
}
13671373

1374+
/* This function initializes the version of PostgreSQL from
1375+
connInfo.protocol that we're connected to.
1376+
h-inoue 01-2-2001
1377+
*/
1378+
void
1379+
CC_initialize_pg_version(ConnectionClass *self)
1380+
{
1381+
strcpy(self->pg_version, self->connInfo.protocol);
1382+
if (PROTOCOL_62(&self->connInfo)) {
1383+
self->pg_version_number = (float) 6.2;
1384+
self->pg_version_major = 6;
1385+
self->pg_version_minor = 2;
1386+
} else if (PROTOCOL_63(&self->connInfo)) {
1387+
self->pg_version_number = (float) 6.3;
1388+
self->pg_version_major = 6;
1389+
self->pg_version_minor = 3;
1390+
} else {
1391+
self->pg_version_number = (float) 6.4;
1392+
self->pg_version_major = 6;
1393+
self->pg_version_minor = 4;
1394+
}
1395+
}
13681396
/* This function gets the version of PostgreSQL that we're connected to.
13691397
This is used to return the correct info in SQLGetInfo
13701398
DJP - 25-1-2001
@@ -1376,6 +1404,7 @@ HSTMT hstmt;
13761404
StatementClass *stmt;
13771405
RETCODE result;
13781406
char *szVersion = "0.0";
1407+
int major, minor;
13791408
static char *func = "CC_lookup_pg_version";
13801409

13811410
mylog( "%s: entering...\n", func);
@@ -1389,6 +1418,7 @@ static char *func = "CC_lookup_pg_version";
13891418
}
13901419
stmt = (StatementClass *) hstmt;
13911420

1421+
/* get the server's version if possible */
13921422
result = SQLExecDirect(hstmt, "select version()", SQL_NTS);
13931423
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
13941424
SQLFreeStmt(hstmt, SQL_DROP);
@@ -1407,10 +1437,13 @@ static char *func = "CC_lookup_pg_version";
14071437
return;
14081438
}
14091439

1410-
/* There's proably a nicer way of doing this... */
14111440
/* Extract the Major and Minor numbers from the string. */
14121441
/* This assumes the string starts 'Postgresql X.X' */
1413-
sprintf(szVersion, "%c.%c", self->pg_version[11], self->pg_version[13]);
1442+
if (sscanf(self->pg_version, "%*s %d.%d", &major, &minor) >= 2) {
1443+
sprintf(szVersion, "%d.%d", major, minor);
1444+
self->pg_version_major = major;
1445+
self->pg_version_minor = minor;
1446+
}
14141447
self->pg_version_number = (float) atof(szVersion);
14151448

14161449
mylog("Got the PostgreSQL version string: '%s'\n", self->pg_version);

src/interfaces/odbc/connection.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,41 @@ typedef struct {
163163
/* Macro to determine is the connection using 6.3 protocol? */
164164
#define PROTOCOL_63(conninfo_) (strncmp((conninfo_)->protocol, PG63, strlen(PG63)) == 0)
165165

166+
/*
167+
* Macros to compare the server's version with a specified version
168+
* 1st parameter: pointer to a ConnectionClass object
169+
* 2nd parameter: major version number
170+
* 3rd parameter: minor version number
171+
*/
172+
#define SERVER_VERSION_GT(conn, major, minor) \
173+
((conn)->pg_version_major > major || \
174+
((conn)->pg_version_major == major && (conn)->pg_version_minor > minor))
175+
#define SERVER_VERSION_GE(conn, major, minor) \
176+
((conn)->pg_version_major > major || \
177+
((conn)->pg_version_major == major && (conn)->pg_version_minor >= minor))
178+
#define SERVER_VERSION_EQ(conn, major, minor) \
179+
((conn)->pg_version_major == major && (conn)->pg_version_minor == minor)
180+
#define SERVER_VERSION_LE(conn, major, minor) (! SERVER_VERSION_GT(conn, major, minor))
181+
#define SERVER_VERSION_LT(conn, major, minor) (! SERVER_VERSION_GE(conn, major, minor))
182+
/*#if ! defined(HAVE_CONFIG_H) || defined(HAVE_STRINGIZE)*/
183+
#define STRING_AFTER_DOT(string) (strchr(#string, '.') + 1)
184+
/*#else
185+
#define STRING_AFTER_DOT(str) (strchr("str", '.') + 1)
186+
#endif*/
187+
/*
188+
* Simplified macros to compare the server's version with a
189+
* specified version
190+
* Note: Never pass a variable as the second parameter.
191+
* It must be a decimal constant of the form %d.%d .
192+
*/
193+
#define PG_VERSION_GT(conn, ver) \
194+
(SERVER_VERSION_GT(conn, (int) ver, atoi(STRING_AFTER_DOT(ver))))
195+
#define PG_VERSION_GE(conn, ver) \
196+
(SERVER_VERSION_GE(conn, (int) ver, atoi(STRING_AFTER_DOT(ver))))
197+
#define PG_VERSION_EQ(conn, ver) \
198+
(SERVER_VERSION_EQ(conn, (int) ver, atoi(STRING_AFTER_DOT(ver))))
199+
#define PG_VERSION_LE(conn, ver) (! PG_VERSION_GT(conn, ver))
200+
#define PG_VERSION_LT(conn, ver) (! PG_VERSION_GE(conn, ver))
166201

167202
/* This is used to store cached table information in the connection */
168203
struct col_info {
@@ -223,6 +258,8 @@ struct ConnectionClass_ {
223258
char errormsg_created; /* has an informative error msg been created? */
224259
char pg_version[MAX_INFO_STRING]; /* Version of PostgreSQL we're connected to - DJP 25-1-2001 */
225260
float pg_version_number;
261+
Int2 pg_version_major;
262+
Int2 pg_version_minor;
226263
};
227264

228265

@@ -258,6 +295,7 @@ int CC_send_function(ConnectionClass *conn, int fnid, void *result_buf, int *act
258295
char CC_send_settings(ConnectionClass *self);
259296
void CC_lookup_lo(ConnectionClass *conn);
260297
void CC_lookup_pg_version(ConnectionClass *conn);
298+
void CC_initialize_pg_version(ConnectionClass *conn);
261299
void CC_log_error(char *func, char *desc, ConnectionClass *self);
262300

263301

src/interfaces/odbc/drvconn.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ int len = 0;
113113

114114
/* Fill in any default parameters if they are not there. */
115115
getDSNdefaults(ci);
116+
/* initialize pg_version */
117+
CC_initialize_pg_version(conn);
116118

117119
#ifdef WIN32
118120
dialog:

src/interfaces/odbc/info.c

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ RETCODE SQL_API SQLGetInfo(
6969
static char *func = "SQLGetInfo";
7070
ConnectionClass *conn = (ConnectionClass *) hdbc;
7171
ConnInfo *ci;
72-
char *p = NULL;
72+
char *p = NULL, tmp[MAX_INFO_STRING];
7373
int len = 0, value = 0;
7474
RETCODE result;
7575

@@ -193,9 +193,8 @@ RETCODE result;
193193
case SQL_DBMS_VER: /* ODBC 1.0 */
194194
/* The ODBC spec wants ##.##.#### ...whatever... so prepend the driver */
195195
/* version number to the dbms version string */
196-
p = POSTGRESDRIVERVERSION;
197-
strcat(p, " ");
198-
strcat(p, conn->pg_version);
196+
sprintf(tmp, "%s %s", POSTGRESDRIVERVERSION, conn->pg_version);
197+
p = tmp;
199198
break;
200199

201200
case SQL_DEFAULT_TXN_ISOLATION: /* ODBC 1.0 */
@@ -255,7 +254,7 @@ RETCODE result;
255254

256255
case SQL_IDENTIFIER_QUOTE_CHAR: /* ODBC 1.0 */
257256
/* the character used to quote "identifiers" */
258-
p = PROTOCOL_62(ci) ? " " : "\"";
257+
p = PG_VERSION_LE(conn, 6.2) ? " " : "\"";
259258
break;
260259

261260
case SQL_KEYWORDS: /* ODBC 2.0 */
@@ -341,7 +340,7 @@ RETCODE result;
341340

342341
case SQL_MAX_ROW_SIZE: /* ODBC 2.0 */
343342
len = 4;
344-
if (conn->pg_version_number >= (float) 7.1) { /* Large Rowa in 7.1+ */
343+
if (PG_VERSION_GE(conn, 7.1)) { /* Large Rowa in 7.1+ */
345344
value = MAX_ROW_SIZE;
346345
} else { /* Without the Toaster we're limited to the blocksize */
347346
value = BLCKSZ;
@@ -358,11 +357,13 @@ RETCODE result;
358357
case SQL_MAX_STATEMENT_LEN: /* ODBC 2.0 */
359358
/* maybe this should be 0? */
360359
len = 4;
361-
if (conn->pg_version_number >= (float) 7.0) { /* Long Queries in 7.0+ */
360+
if (PG_VERSION_GE(conn, 7.0)) { /* Long Queries in 7.0+ */
362361
value = MAX_STATEMENT_LEN;
363-
} else { /* Prior to 7.0 we used 2*BLCKSZ */
362+
} else if (PG_VERSION_GE(conn, 6.5)) /* Prior to 7.0 we used 2*BLCKSZ */
364363
value = (2*BLCKSZ);
365-
}
364+
else /* Prior to 6.5 we used BLCKSZ */
365+
value = BLCKSZ;
366+
366367
break;
367368

368369
case SQL_MAX_TABLE_NAME_LEN: /* ODBC 1.0 */
@@ -431,7 +432,7 @@ RETCODE result;
431432

432433
case SQL_OJ_CAPABILITIES: /* ODBC 2.01 */
433434
len = 4;
434-
if (conn->pg_version_number >= (float) 7.1) { /* OJs in 7.1+ */
435+
if (PG_VERSION_GE(conn, 7.1)) { /* OJs in 7.1+ */
435436
value = (SQL_OJ_LEFT |
436437
SQL_OJ_RIGHT |
437438
SQL_OJ_FULL |
@@ -445,11 +446,11 @@ RETCODE result;
445446
break;
446447

447448
case SQL_ORDER_BY_COLUMNS_IN_SELECT: /* ODBC 2.0 */
448-
p = (PROTOCOL_62(ci) || PROTOCOL_63(ci)) ? "Y" : "N";
449+
p = (PG_VERSION_LE(conn, 6.3)) ? "Y" : "N";
449450
break;
450451

451452
case SQL_OUTER_JOINS: /* ODBC 1.0 */
452-
if (conn->pg_version_number >= (float) 7.1) { /* OJs in 7.1+ */
453+
if (PG_VERSION_GE(conn, 7.1)) { /* OJs in 7.1+ */
453454
p = "Y";
454455
} else { /* OJs not in <7.1 */
455456
p = "N";
@@ -937,7 +938,8 @@ HSTMT htbl_stmt;
937938
RETCODE result;
938939
char *tableType;
939940
char tables_query[STD_STATEMENT_LEN];
940-
char table_name[MAX_INFO_STRING], table_owner[MAX_INFO_STRING], relhasrules[MAX_INFO_STRING];
941+
char table_name[MAX_INFO_STRING], table_owner[MAX_INFO_STRING], relkind_or_hasrules[MAX_INFO_STRING];
942+
ConnectionClass *conn;
941943
ConnInfo *ci;
942944
char *prefix[32], prefixes[MEDIUM_REGISTRY_LEN];
943945
char *table_type[32], table_types[MAX_INFO_STRING];
@@ -955,6 +957,7 @@ mylog("%s: entering...stmt=%u\n", func, stmt);
955957
stmt->manual_result = TRUE;
956958
stmt->errormsg_created = TRUE;
957959

960+
conn = (ConnectionClass *) (stmt->hdbc);
958961
ci = &stmt->hdbc->connInfo;
959962

960963
result = SQLAllocStmt( stmt->hdbc, &htbl_stmt);
@@ -970,8 +973,14 @@ mylog("%s: entering...stmt=%u\n", func, stmt);
970973
/* Create the query to find out the tables */
971974
/* ********************************************************************** */
972975

973-
strcpy(tables_query, "select relname, usename, relhasrules from pg_class, pg_user");
974-
strcat(tables_query, " where relkind = 'r'");
976+
if (PG_VERSION_GE(conn, 7.1)) { /* view is represented by its relkind since 7.1 */
977+
strcpy(tables_query, "select relname, usename, relkind from pg_class, pg_user");
978+
strcat(tables_query, " where relkind in ('r', 'v')");
979+
}
980+
else {
981+
strcpy(tables_query, "select relname, usename, relhasrules from pg_class, pg_user");
982+
strcat(tables_query, " where relkind = 'r'");
983+
}
975984

976985
my_strcat(tables_query, " and usename like '%.*s'", szTableOwner, cbTableOwner);
977986
my_strcat(tables_query, " and relname like '%.*s'", szTableName, cbTableName);
@@ -1039,6 +1048,9 @@ mylog("%s: entering...stmt=%u\n", func, stmt);
10391048

10401049

10411050
/* match users */
1051+
if (PG_VERSION_LT(conn, 7.1)) /* filter out large objects in older versions */
1052+
strcat(tables_query, " and relname !~ '^xinv[0-9]+'");
1053+
10421054
strcat(tables_query, " and usesysid = relowner");
10431055
strcat(tables_query, " order by relname");
10441056

@@ -1073,7 +1085,7 @@ mylog("%s: entering...stmt=%u\n", func, stmt);
10731085
return SQL_ERROR;
10741086
}
10751087
result = SQLBindCol(htbl_stmt, 3, SQL_C_CHAR,
1076-
relhasrules, MAX_INFO_STRING, NULL);
1088+
relkind_or_hasrules, MAX_INFO_STRING, NULL);
10771089
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
10781090
stmt->errormsg = tbl_stmt->errormsg;
10791091
stmt->errornumber = tbl_stmt->errornumber;
@@ -1131,7 +1143,10 @@ mylog("%s: entering...stmt=%u\n", func, stmt);
11311143
}
11321144

11331145
/* Determine if the table name is a view */
1134-
view = (relhasrules[0] == '1');
1146+
if (PG_VERSION_GE(conn, 7.1)) /* view is represented by its relkind since 7.1 */
1147+
view = (relkind_or_hasrules[0] == 'v');
1148+
else
1149+
view = (relkind_or_hasrules[0] == '1');
11351150

11361151
/* It must be a regular table */
11371152
regular_table = ( ! systable && ! view);
@@ -1214,6 +1229,7 @@ Int4 field_type, the_type, field_length, mod_length, precision;
12141229
char useStaticPrecision;
12151230
char not_null[MAX_INFO_STRING], relhasrules[MAX_INFO_STRING];
12161231
ConnInfo *ci;
1232+
ConnectionClass *conn;
12171233

12181234

12191235
mylog("%s: entering...stmt=%u\n", func, stmt);
@@ -1226,6 +1242,7 @@ ConnInfo *ci;
12261242
stmt->manual_result = TRUE;
12271243
stmt->errormsg_created = TRUE;
12281244

1245+
conn = (ConnectionClass *) (stmt->hdbc);
12291246
ci = &stmt->hdbc->connInfo;
12301247

12311248
/* ********************************************************************** */
@@ -1236,7 +1253,7 @@ ConnInfo *ci;
12361253
" from pg_user u, pg_class c, pg_attribute a, pg_type t"
12371254
" where u.usesysid = c.relowner"
12381255
" and c.oid= a.attrelid and a.atttypid = t.oid and (a.attnum > 0)",
1239-
PROTOCOL_62(ci) ? "a.attlen" : "a.atttypmod");
1256+
PG_VERSION_LE(conn, 6.2) ? "a.attlen" : "a.atttypmod");
12401257

12411258
my_strcat(columns_query, " and c.relname like '%.*s'", szTableName, cbTableName);
12421259
my_strcat(columns_query, " and u.usename like '%.*s'", szTableOwner, cbTableOwner);
@@ -2315,7 +2332,6 @@ Int2 result_cols;
23152332
stmt->errormsg = "Couldn't allocate memory for SQLForeignKeys result.";
23162333
stmt->errornumber = STMT_NO_MEMORY_ERROR;
23172334
SC_log_error(func, "", stmt);
2318-
SQLFreeStmt(htbl_stmt, SQL_DROP);
23192335
return SQL_ERROR;
23202336
}
23212337

src/interfaces/odbc/psqlodbc.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* Comments: See "notice.txt" for copyright and license information.
88
*
9-
* $Id: psqlodbc.h,v 1.29 2001/01/26 22:41:59 momjian Exp $
9+
* $Id: psqlodbc.h,v 1.30 2001/02/06 02:21:12 inoue Exp $
1010
*/
1111

1212
#ifndef __PSQLODBC_H__
@@ -41,7 +41,7 @@ typedef UInt4 Oid;
4141
#define DRIVERNAME "PostgreSQL ODBC"
4242
#define DBMS_NAME "PostgreSQL"
4343

44-
#define POSTGRESDRIVERVERSION "07.01.0001"
44+
#define POSTGRESDRIVERVERSION "07.01.0002"
4545

4646
#ifdef WIN32
4747
#define DRIVER_FILE_NAME "PSQLODBC.DLL"

src/interfaces/odbc/psqlodbc.rc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ END
204204
//
205205

206206
VS_VERSION_INFO VERSIONINFO
207-
FILEVERSION 7,1,0,1
208-
PRODUCTVERSION 7,1,0,1
207+
FILEVERSION 7,1,0,2
208+
PRODUCTVERSION 7,1,0,2
209209
FILEFLAGSMASK 0x3L
210210
#ifdef _DEBUG
211211
FILEFLAGS 0x1L
@@ -223,14 +223,14 @@ BEGIN
223223
VALUE "Comments", "PostgreSQL ODBC driver\0"
224224
VALUE "CompanyName", "Insight Distribution Systems\0"
225225
VALUE "FileDescription", "PostgreSQL Driver\0"
226-
VALUE "FileVersion", " 07.01.0001\0"
226+
VALUE "FileVersion", " 07.01.0002\0"
227227
VALUE "InternalName", "psqlodbc\0"
228228
VALUE "LegalCopyright", "\0"
229229
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"
230230
VALUE "OriginalFilename", "psqlodbc.dll\0"
231231
VALUE "PrivateBuild", "\0"
232232
VALUE "ProductName", "Microsoft Open Database Connectivity\0"
233-
VALUE "ProductVersion", " 07.01.0001\0"
233+
VALUE "ProductVersion", " 07.01.0002\0"
234234
VALUE "SpecialBuild", "\0"
235235
END
236236
END

0 commit comments

Comments
 (0)