From 87225ca31d1212008c47f5085f5fd4d77431cb69 Mon Sep 17 00:00:00 2001 From: Byron Nikolaidis Date: Wed, 11 Nov 1998 21:54:01 +0000 Subject: [PATCH] Update for version 06-40-0001 --- src/interfaces/odbc/columninfo.c | 32 +++++++-- src/interfaces/odbc/columninfo.h | 6 +- src/interfaces/odbc/connection.c | 60 +++++++++++++---- src/interfaces/odbc/connection.h | 12 ++-- src/interfaces/odbc/convert.c | 4 +- src/interfaces/odbc/dlg_specific.c | 27 ++++++-- src/interfaces/odbc/dlg_specific.h | 2 + src/interfaces/odbc/execute.c | 2 +- src/interfaces/odbc/misc.c | 2 +- src/interfaces/odbc/misc.h | 46 ++++++------- src/interfaces/odbc/pgtypes.c | 3 + src/interfaces/odbc/psqlodbc.h | 8 ++- src/interfaces/odbc/psqlodbc.rc | 105 ++++++++++++++--------------- src/interfaces/odbc/qresult.c | 10 +-- src/interfaces/odbc/qresult.h | 3 +- src/interfaces/odbc/resource.h | 8 +-- src/interfaces/odbc/results.c | 2 +- src/interfaces/odbc/socket.h | 7 -- src/interfaces/odbc/statement.h | 3 +- 19 files changed, 210 insertions(+), 132 deletions(-) diff --git a/src/interfaces/odbc/columninfo.c b/src/interfaces/odbc/columninfo.c index 41e6e74635..fed86d5dcd 100644 --- a/src/interfaces/odbc/columninfo.c +++ b/src/interfaces/odbc/columninfo.c @@ -13,6 +13,7 @@ */ #include "columninfo.h" +#include "connection.h" #include "socket.h" #include #include @@ -31,6 +32,7 @@ ColumnInfoClass *rv; rv->adtid = NULL; rv->adtsize = NULL; rv->display_size = NULL; + rv->atttypmod = NULL; } return rv; @@ -49,14 +51,19 @@ CI_Destructor(ColumnInfoClass *self) If self is null, then just read, don't store. */ char -CI_read_fields(ColumnInfoClass *self, SocketClass *sock) +CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn) { Int2 lf; int new_num_fields; Oid new_adtid; Int2 new_adtsize; +Int4 new_atttypmod = -1; char new_field_name[MAX_MESSAGE_LEN+1]; +SocketClass *sock; +ConnInfo *ci; + sock = CC_get_socket(conn); + ci = &conn->connInfo; /* at first read in the number of fields that are in the query */ new_num_fields = (Int2) SOCK_get_int(sock, sizeof(Int2)); @@ -74,10 +81,23 @@ char new_field_name[MAX_MESSAGE_LEN+1]; new_adtid = (Oid) SOCK_get_int(sock, 4); new_adtsize = (Int2) SOCK_get_int(sock, 2); - mylog("CI_read_fields: fieldname='%s', adtid=%d, adtsize=%d\n", new_field_name, new_adtid, new_adtsize); + /* If 6.4 protocol, then read the atttypmod field */ + if ( ! PROTOCOL_63(ci) && ! PROTOCOL_62(ci)) { + + mylog("READING ATTTYPMOD\n"); + new_atttypmod = (Int4) SOCK_get_int(sock, 4); + + /* Subtract the header length */ + new_atttypmod -= 4; + if (new_atttypmod < 0) + new_atttypmod = -1; + + } + + mylog("CI_read_fields: fieldname='%s', adtid=%d, adtsize=%d, atttypmod=%d\n", new_field_name, new_adtid, new_adtsize, new_atttypmod); if (self) - CI_set_field_info(self, lf, new_field_name, new_adtid, new_adtsize); + CI_set_field_info(self, lf, new_field_name, new_adtid, new_adtsize, new_atttypmod); } return (SOCK_get_errcode(sock) == 0); @@ -101,6 +121,8 @@ int num_fields = self->num_fields; free(self->adtid); free(self->adtsize); free(self->display_size); + + free(self->atttypmod); } void @@ -114,11 +136,12 @@ CI_set_num_fields(ColumnInfoClass *self, int new_num_fields) self->adtid = (Oid *) malloc (sizeof(Oid) * self->num_fields); self->adtsize = (Int2 *) malloc (sizeof(Int2) * self->num_fields); self->display_size = (Int2 *) malloc(sizeof(Int2) * self->num_fields); + self->atttypmod = (Int4 *) malloc(sizeof(Int4) * self->num_fields); } void CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name, - Oid new_adtid, Int2 new_adtsize) + Oid new_adtid, Int2 new_adtsize, Int4 new_atttypmod) { // check bounds @@ -130,6 +153,7 @@ CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name, self->name[field_num] = strdup(new_name); self->adtid[field_num] = new_adtid; self->adtsize[field_num] = new_adtsize; + self->atttypmod[field_num] = new_atttypmod; self->display_size[field_num] = 0; } diff --git a/src/interfaces/odbc/columninfo.h b/src/interfaces/odbc/columninfo.h index 01c654da84..3ec1cc92d5 100644 --- a/src/interfaces/odbc/columninfo.h +++ b/src/interfaces/odbc/columninfo.h @@ -18,6 +18,7 @@ struct ColumnInfoClass_ { Oid *adtid; /* list of type ids */ Int2 *adtsize; /* list type sizes */ Int2 *display_size; /* the display size (longest row) */ + Int4 *atttypmod; /* the length of bpchar/varchar */ }; #define CI_get_num_fields(self) (self->num_fields) @@ -25,17 +26,18 @@ struct ColumnInfoClass_ { #define CI_get_fieldname(self, col) (self->name[col]) #define CI_get_fieldsize(self, col) (self->adtsize[col]) #define CI_get_display_size(self, col) (self->display_size[col]) +#define CI_get_atttypmod(self, col) (self->atttypmod[col]) ColumnInfoClass *CI_Constructor(void); void CI_Destructor(ColumnInfoClass *self); void CI_free_memory(ColumnInfoClass *self); -char CI_read_fields(ColumnInfoClass *self, SocketClass *sock); +char CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn); /* functions for setting up the fields from within the program, */ /* without reading from a socket */ void CI_set_num_fields(ColumnInfoClass *self, int new_num_fields); void CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name, - Oid new_adtid, Int2 new_adtsize); + Oid new_adtid, Int2 new_adtsize, Int4 atttypmod); #endif diff --git a/src/interfaces/odbc/connection.c b/src/interfaces/odbc/connection.c index 3857f73d70..c07b051070 100644 --- a/src/interfaces/odbc/connection.c +++ b/src/interfaces/odbc/connection.c @@ -472,8 +472,9 @@ static char *func="CC_connect"; globals.unknown_sizes, globals.max_varchar_size, globals.max_longvarchar_size); - qlog(" disable_optimizer=%d, unique_index=%d, use_declarefetch=%d\n", + qlog(" disable_optimizer=%d, ksqo=%d, unique_index=%d, use_declarefetch=%d\n", globals.disable_optimizer, + globals.ksqo, globals.unique_index, globals.use_declarefetch); qlog(" text_as_longvarchar=%d, unknowns_as_longvarchar=%d, bools_as_char=%d\n", @@ -542,7 +543,11 @@ static char *func="CC_connect"; // Send length of Authentication Block SOCK_put_int(sock, 4+sizeof(StartupPacket), 4); - sp.protoVersion = (ProtocolVersion) htonl(PG_PROTOCOL_LATEST); + if ( PROTOCOL_63(ci)) + sp.protoVersion = (ProtocolVersion) htonl(PG_PROTOCOL_63); + else + sp.protoVersion = (ProtocolVersion) htonl(PG_PROTOCOL_LATEST); + strncpy(sp.database, ci->database, SM_DATABASE); strncpy(sp.user, ci->username, SM_USER); @@ -913,22 +918,41 @@ char cmdbuffer[MAX_MESSAGE_LEN+1]; // QR_set_command() dups this string so dont SOCK_put_string(sock, "Q "); SOCK_flush_output(sock); - while(!clear) { - SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); - mylog("send_query: read command '%s'\n", cmdbuffer); - clear = (cmdbuffer[0] == 'I'); - if (cmdbuffer[0] == 'N') - qlog("NOTICE from backend during send_query: '%s'\n", &cmdbuffer[1]); - else if (cmdbuffer[0] == 'E') - qlog("ERROR from backend during send_query: '%s'\n", &cmdbuffer[1]); - else if (cmdbuffer[0] == 'C') - qlog("Command response: '%s'\n", &cmdbuffer[1]); + while( ! clear) { + id = SOCK_get_char(sock); + switch(id) { + case 'I': + (void) SOCK_get_char(sock); + clear = TRUE; + break; + case 'Z': + break; + case 'C': + SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); + qlog("Command response: '%s'\n", cmdbuffer); + break; + case 'N': + SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); + qlog("NOTICE from backend during clear: '%s'\n", cmdbuffer); + break; + case 'E': + SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); + qlog("ERROR from backend during clear: '%s'\n", cmdbuffer); + break; + } } - + mylog("send_query: returning res = %u\n", res); return res; } + case 'K': /* Secret key (6.4 protocol) */ + (void)SOCK_get_int(sock, 4); /* pid */ + (void)SOCK_get_int(sock, 4); /* key */ + + break; + case 'Z': /* Backend is ready for new query (6.4) */ + break; case 'N' : /* NOTICE: */ SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); @@ -1209,6 +1233,16 @@ static char *func="CC_send_settings"; } + /* KSQO */ + if (globals.ksqo) { + result = SQLExecDirect(hstmt, "set ksqo to 'ON'", SQL_NTS); + if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + status = FALSE; + + mylog("%s: result %d, status %d from set ksqo\n", func, result, status); + + } + /* Global settings */ if (globals.conn_settings[0] != '\0') { cs = strdup(globals.conn_settings); diff --git a/src/interfaces/odbc/connection.h b/src/interfaces/odbc/connection.h index 895e4ce826..3340e15cbe 100644 --- a/src/interfaces/odbc/connection.h +++ b/src/interfaces/odbc/connection.h @@ -14,6 +14,8 @@ #include "config.h" #endif +#include "psqlodbc.h" + #ifndef WIN32 #include "iodbc.h" #include "isql.h" @@ -24,7 +26,6 @@ #include #endif -#include "psqlodbc.h" typedef enum { CONN_NOT_CONNECTED, /* Connection has not been established */ @@ -100,10 +101,11 @@ typedef enum { typedef unsigned int ProtocolVersion; #define PG_PROTOCOL(major, minor) (((major) << 16) | (minor)) -#define PG_PROTOCOL_LATEST PG_PROTOCOL(1, 0) -#define PG_PROTOCOL_EARLIEST PG_PROTOCOL(0, 0) +#define PG_PROTOCOL_LATEST PG_PROTOCOL(2, 0) +#define PG_PROTOCOL_63 PG_PROTOCOL(1, 0) +#define PG_PROTOCOL_62 PG_PROTOCOL(0, 0) -/* This startup packet is to support latest Postgres protocol (6.3) */ +/* This startup packet is to support latest Postgres protocol (6.4, 6.3) */ typedef struct _StartupPacket { ProtocolVersion protoVersion; @@ -154,6 +156,8 @@ typedef struct { /* Macro to determine is the connection using 6.2 protocol? */ #define PROTOCOL_62(conninfo_) (strncmp((conninfo_)->protocol, PG62, strlen(PG62)) == 0) +/* Macro to determine is the connection using 6.3 protocol? */ +#define PROTOCOL_63(conninfo_) (strncmp((conninfo_)->protocol, PG63, strlen(PG63)) == 0) /* This is used to store cached table information in the connection */ diff --git a/src/interfaces/odbc/convert.c b/src/interfaces/odbc/convert.c index 1389c7ca3a..a5b3cbfd3f 100644 --- a/src/interfaces/odbc/convert.c +++ b/src/interfaces/odbc/convert.c @@ -24,6 +24,8 @@ #include #include +#include "psqlodbc.h" + #ifndef WIN32 #include "iodbc.h" #include "isql.h" @@ -120,7 +122,7 @@ struct tm *tim; st.d = tim->tm_mday; st.y = tim->tm_year + 1900; - mylog("copy_and_convert: field_type = %d, fctype = %d, value = '%s', cbValueMax=%d\n", field_type, fCType, (value==NULL)?"":value, cbValueMax); + mylog("copy_and_convert: field_type = %d, fctype = %d, value = '%s', cbValueMax=%d\n", field_type, fCType, value, cbValueMax); if ( ! value) { /* handle a null just by returning SQL_NULL_DATA in pcbValue, */ diff --git a/src/interfaces/odbc/dlg_specific.c b/src/interfaces/odbc/dlg_specific.c index 82e7e5a2b8..371b2d7ad8 100644 --- a/src/interfaces/odbc/dlg_specific.c +++ b/src/interfaces/odbc/dlg_specific.c @@ -87,6 +87,7 @@ int CALLBACK driver_optionsProc(HWND hdlg, CheckDlgButton(hdlg, DRV_COMMLOG, globals.commlog); CheckDlgButton(hdlg, DRV_OPTIMIZER, globals.disable_optimizer); + CheckDlgButton(hdlg, DRV_KSQO, globals.ksqo); CheckDlgButton(hdlg, DRV_UNIQUEINDEX, globals.unique_index); CheckDlgButton(hdlg, DRV_READONLY, globals.readonly); CheckDlgButton(hdlg, DRV_USEDECLAREFETCH, globals.use_declarefetch); @@ -128,6 +129,7 @@ int CALLBACK driver_optionsProc(HWND hdlg, globals.commlog = IsDlgButtonChecked(hdlg, DRV_COMMLOG); globals.disable_optimizer = IsDlgButtonChecked(hdlg, DRV_OPTIMIZER); + globals.ksqo = IsDlgButtonChecked(hdlg, DRV_KSQO); globals.unique_index = IsDlgButtonChecked(hdlg, DRV_UNIQUEINDEX); globals.readonly = IsDlgButtonChecked(hdlg, DRV_READONLY); globals.use_declarefetch = IsDlgButtonChecked(hdlg, DRV_USEDECLAREFETCH); @@ -168,6 +170,7 @@ int CALLBACK driver_optionsProc(HWND hdlg, case IDDEFAULTS: CheckDlgButton(hdlg, DRV_COMMLOG, DEFAULT_COMMLOG); CheckDlgButton(hdlg, DRV_OPTIMIZER, DEFAULT_OPTIMIZER); + CheckDlgButton(hdlg, DRV_KSQO, DEFAULT_KSQO); CheckDlgButton(hdlg, DRV_UNIQUEINDEX, DEFAULT_UNIQUEINDEX); CheckDlgButton(hdlg, DRV_READONLY, DEFAULT_READONLY); CheckDlgButton(hdlg, DRV_USEDECLAREFETCH, DEFAULT_USEDECLAREFETCH); @@ -238,8 +241,11 @@ char buf[128]; /* Protocol */ if (strncmp(ci->protocol, PG62, strlen(PG62)) == 0) CheckDlgButton(hdlg, DS_PG62, 1); - else - CheckDlgButton(hdlg, DS_PG62, 0); + else if (strncmp(ci->protocol, PG63, strlen(PG63)) == 0) + CheckDlgButton(hdlg, DS_PG63, 1); + else + CheckDlgButton(hdlg, DS_PG64, 1); + CheckDlgButton(hdlg, DS_SHOWOIDCOLUMN, atoi(ci->show_oid_column)); @@ -273,11 +279,11 @@ char buf[128]; /* Protocol */ if ( IsDlgButtonChecked(hdlg, DS_PG62)) strcpy(ci->protocol, PG62); - else + else if ( IsDlgButtonChecked(hdlg, DS_PG63)) + strcpy(ci->protocol, PG63); + else ci->protocol[0] = '\0'; - - sprintf(ci->show_system_tables, "%d", IsDlgButtonChecked(hdlg, DS_SHOWSYSTEMTABLES)); sprintf(ci->row_versioning, "%d", IsDlgButtonChecked(hdlg, DS_ROWVERSIONING)); @@ -634,6 +640,13 @@ char temp[256]; else if ( ! override) globals.disable_optimizer = DEFAULT_OPTIMIZER; + // KSQO is stored in the driver section only + SQLGetPrivateProfileString(section, INI_KSQO, "", + temp, sizeof(temp), filename); + if ( temp[0] ) + globals.ksqo = atoi(temp); + else if ( ! override) + globals.ksqo = DEFAULT_KSQO; // Recognize Unique Index is stored in the driver section only SQLGetPrivateProfileString(section, INI_UNIQUEINDEX, "", @@ -769,6 +782,10 @@ char tmp[128]; SQLWritePrivateProfileString(DBMS_NAME, INI_OPTIMIZER, tmp, ODBCINST_INI); + sprintf(tmp, "%d", globals.ksqo); + SQLWritePrivateProfileString(DBMS_NAME, + INI_KSQO, tmp, ODBCINST_INI); + sprintf(tmp, "%d", globals.unique_index); SQLWritePrivateProfileString(DBMS_NAME, INI_UNIQUEINDEX, tmp, ODBCINST_INI); diff --git a/src/interfaces/odbc/dlg_specific.h b/src/interfaces/odbc/dlg_specific.h index b4e5ef05f1..829c9aeab7 100644 --- a/src/interfaces/odbc/dlg_specific.h +++ b/src/interfaces/odbc/dlg_specific.h @@ -59,6 +59,7 @@ #define INI_COMMLOG "CommLog" /* Communication to backend logging */ #define INI_PROTOCOL "Protocol" /* What protocol (6.2) */ #define INI_OPTIMIZER "Optimizer" /* Use backend genetic optimizer */ +#define INI_KSQO "Ksqo" /* Keyset query optimization */ #define INI_CONNSETTINGS "ConnSettings" /* Anything to send to backend on successful connection */ #define INI_UNIQUEINDEX "UniqueIndex" /* Recognize unique indexes */ #define INI_UNKNOWNSIZES "UnknownSizes" /* How to handle unknown result set sizes */ @@ -93,6 +94,7 @@ #define DEFAULT_UNKNOWNSASLONGVARCHAR 0 #define DEFAULT_BOOLSASCHAR 1 #define DEFAULT_OPTIMIZER 1 // disable +#define DEFAULT_KSQO 1 // on #define DEFAULT_UNIQUEINDEX 0 // dont recognize #define DEFAULT_COMMLOG 0 // dont log #define DEFAULT_DEBUG 0 diff --git a/src/interfaces/odbc/execute.c b/src/interfaces/odbc/execute.c index 1baaaffc71..d87859c9fc 100644 --- a/src/interfaces/odbc/execute.c +++ b/src/interfaces/odbc/execute.c @@ -129,7 +129,7 @@ RETCODE SQL_API SQLExecDirect( SDWORD cbSqlStr) { StatementClass *stmt = (StatementClass *) hstmt; -RETCODE SQL_API result; +RETCODE result; static char *func = "SQLExecDirect"; mylog( "%s: entering...\n", func); diff --git a/src/interfaces/odbc/misc.c b/src/interfaces/odbc/misc.c index 94a116299b..7e1501842c 100644 --- a/src/interfaces/odbc/misc.c +++ b/src/interfaces/odbc/misc.c @@ -44,7 +44,7 @@ generate_filename(char* dirname,char* prefix,char* filename) return; strcpy(filename,dirname); - strcat(filename,DIRSEPARATOR); + strcat(filename,DIRSEPERATOR); if(prefix != 0) strcat(filename,prefix); #ifndef WIN32 diff --git a/src/interfaces/odbc/misc.h b/src/interfaces/odbc/misc.h index 10cb5114d1..194a08161c 100644 --- a/src/interfaces/odbc/misc.h +++ b/src/interfaces/odbc/misc.h @@ -26,7 +26,7 @@ portion of the registry. You may have to manually add this key. This logfile is intended for development use, not for an end user! */ -#define MY_LOG +// #define MY_LOG /* Uncomment Q_LOG to compile in the qlog() statements (Communications log, i.e. CommLog). @@ -39,41 +39,33 @@ #ifdef MY_LOG - #define MYLOGFILE "mylog_" - #ifndef WIN32 - #define MYLOGDIR "/tmp" - #else - #define MYLOGDIR "c:" - #endif - void mylog(); /* prototype */ +#define MYLOGFILE "mylog_" +#ifndef WIN32 +#define MYLOGDIR "/tmp" #else - #ifndef WIN32 - #define mylog(args...) /* GNU convention for variable arguments */ - #else - #define mylog // mylog - #endif +#define MYLOGDIR "c:" +#endif +void mylog(); /* prototype */ +#else +#define mylog // mylog #endif #ifdef Q_LOG - #define QLOGFILE "psqlodbc_" - #ifndef WIN32 - #define QLOGDIR "/tmp" - #else - #define QLOGDIR "c:" - #endif - void qlog(); /* prototype */ +#define QLOGFILE "psqlodbc_" +#ifndef WIN32 +#define QLOGDIR "/tmp" #else - #ifndef WIN32 - #define qlog(args...) /* GNU convention for variable arguments */ - #else - #define qlog // qlog - #endif +#define QLOGDIR "c:" +#endif +void qlog(); /* prototype */ +#else +#define qlog // qlog #endif #ifndef WIN32 -#define DIRSEPARATOR "/" +#define DIRSEPERATOR "/" #else -#define DIRSEPARATOR "\\" +#define DIRSEPERATOR "\\" #endif void remove_newlines(char *string); diff --git a/src/interfaces/odbc/pgtypes.c b/src/interfaces/odbc/pgtypes.c index 24ef584374..cdd9fc2654 100644 --- a/src/interfaces/odbc/pgtypes.c +++ b/src/interfaces/odbc/pgtypes.c @@ -242,6 +242,9 @@ mylog("getCharPrecision: type=%d, col=%d, unknown = %d\n", type,col,handle_unkno } /* Size is unknown -- handle according to parameter */ + if (QR_get_atttypmod(result, col) > -1) + return QR_get_atttypmod(result, col); + if (type == PG_TYPE_BPCHAR || handle_unknown_size_as == UNKNOWNS_AS_LONGEST) { p = QR_get_display_size(result, col); mylog("getCharPrecision: LONGEST: p = %d\n", p); diff --git a/src/interfaces/odbc/psqlodbc.h b/src/interfaces/odbc/psqlodbc.h index 05b3ee3018..d00c67dd82 100644 --- a/src/interfaces/odbc/psqlodbc.h +++ b/src/interfaces/odbc/psqlodbc.h @@ -33,6 +33,7 @@ typedef double SDOUBLE; typedef UInt4 Oid; +# define ODBCVER 0x0200 /* Limits */ #define MAX_MESSAGE_LEN 8192 @@ -69,8 +70,8 @@ typedef UInt4 Oid; /* Driver stuff */ #define DRIVERNAME "PostgreSQL ODBC" #define DBMS_NAME "PostgreSQL" -#define DBMS_VERSION "06.30.0250 PostgreSQL 6.3" -#define POSTGRESDRIVERVERSION "06.30.0250" +#define DBMS_VERSION "06.40.0001 PostgreSQL 6.4" +#define POSTGRESDRIVERVERSION "06.40.0001" #ifdef WIN32 #define DRIVER_FILE_NAME "PSQLODBC.DLL" @@ -79,7 +80,7 @@ typedef UInt4 Oid; #endif #define PG62 "6.2" /* "Protocol" key setting to force Postgres 6.2 */ - +#define PG63 "6.3" /* "Protocol" key setting to force postgres 6.3 */ typedef struct ConnectionClass_ ConnectionClass; typedef struct StatementClass_ StatementClass; @@ -106,6 +107,7 @@ typedef struct GlobalValues_ char debug; char commlog; char disable_optimizer; + char ksqo; char unique_index; char readonly; char use_declarefetch; diff --git a/src/interfaces/odbc/psqlodbc.rc b/src/interfaces/odbc/psqlodbc.rc index 3e6cafded4..779e82fea6 100644 --- a/src/interfaces/odbc/psqlodbc.rc +++ b/src/interfaces/odbc/psqlodbc.rc @@ -88,78 +88,77 @@ CAPTION "Advanced Options (Driver)" FONT 8, "MS Sans Serif" BEGIN CONTROL "Disable Genetic &Optimizer",DRV_OPTIMIZER,"Button", - BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,15,10,97,10 + BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,15,5,97,10 CONTROL "Comm&Log (C:\\psqlodbc.log)",DRV_COMMLOG,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,140,10,113,10 - CONTROL "Recognize Unique &Indexes",DRV_UNIQUEINDEX,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,15,25,101,10 + BS_AUTOCHECKBOX | WS_TABSTOP,140,5,113,10 + CONTROL "&KSQO (Keyset Query Optimization)",DRV_KSQO,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,15,20,124,10 CONTROL "&ReadOnly (Default)",DRV_READONLY,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,140,25,80,10 - CONTROL "&Use Declare/Fetch",DRV_USEDECLAREFETCH,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,15,40,80,10 + BS_AUTOCHECKBOX | WS_TABSTOP,140,20,80,10 + CONTROL "Recognize Unique &Indexes",DRV_UNIQUEINDEX,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,15,35,101,10 CONTROL "P&arse Statements",DRV_PARSE,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,140,40,80,10 - GROUPBOX "Unknown Sizes",IDC_STATIC,10,55,175,25 + WS_TABSTOP,140,35,80,10 + CONTROL "&Use Declare/Fetch",DRV_USEDECLAREFETCH,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,15,50,80,10 + GROUPBOX "Unknown Sizes",IDC_STATIC,10,65,175,25 CONTROL "Maximum",DRV_UNKNOWN_MAX,"Button",BS_AUTORADIOBUTTON | - WS_GROUP | WS_TABSTOP,15,65,45,10 + WS_GROUP | WS_TABSTOP,15,76,45,10 CONTROL "Don't Know",DRV_UNKNOWN_DONTKNOW,"Button", - BS_AUTORADIOBUTTON | WS_TABSTOP,70,65,53,10 + BS_AUTORADIOBUTTON | WS_TABSTOP,70,76,53,10 CONTROL "Longest",DRV_UNKNOWN_LONGEST,"Button", - BS_AUTORADIOBUTTON | WS_TABSTOP,130,65,50,10 - GROUPBOX "Data Type Options",IDC_STATIC,10,85,270,25 + BS_AUTORADIOBUTTON | WS_TABSTOP,130,76,50,10 + GROUPBOX "Data Type Options",IDC_STATIC,10,95,270,25 CONTROL "Text as LongVarChar",DRV_TEXT_LONGVARCHAR,"Button", - BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,15,95,80,10 + BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,15,105,80,10 CONTROL "Unknowns as LongVarChar",DRV_UNKNOWNS_LONGVARCHAR, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,105,95,100,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,105,105,100,10 CONTROL "Bools as Char",DRV_BOOLS_CHAR,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,215,95,60,10 - LTEXT "&Cache Size:",IDC_STATIC,10,120,40,10 - EDITTEXT DRV_CACHE_SIZE,50,120,35,12,ES_AUTOHSCROLL - LTEXT "Max &Varchar:",IDC_STATIC,90,120,45,10 - EDITTEXT DRV_VARCHAR_SIZE,135,120,35,12,ES_AUTOHSCROLL - LTEXT "Max Lon&gVarChar:",IDC_STATIC,180,120,60,10 - EDITTEXT DRV_LONGVARCHAR_SIZE,240,120,35,12,ES_AUTOHSCROLL - LTEXT "SysTable &Prefixes:",IDC_STATIC,15,135,35,20 - EDITTEXT DRV_EXTRASYSTABLEPREFIXES,50,140,75,12,ES_AUTOHSCROLL - RTEXT "Connect &Settings:",IDC_STATIC,10,165,35,25 - EDITTEXT DRV_CONNSETTINGS,50,160,225,35,ES_MULTILINE | + WS_TABSTOP,215,105,60,10 + LTEXT "&Cache Size:",IDC_STATIC,10,130,40,10 + EDITTEXT DRV_CACHE_SIZE,50,130,35,12,ES_AUTOHSCROLL + LTEXT "Max &Varchar:",IDC_STATIC,90,130,45,10 + EDITTEXT DRV_VARCHAR_SIZE,135,130,35,12,ES_AUTOHSCROLL + LTEXT "Max Lon&gVarChar:",IDC_STATIC,180,130,60,10 + EDITTEXT DRV_LONGVARCHAR_SIZE,240,130,35,12,ES_AUTOHSCROLL + LTEXT "SysTable &Prefixes:",IDC_STATIC,15,145,35,20 + EDITTEXT DRV_EXTRASYSTABLEPREFIXES,50,151,75,12,ES_AUTOHSCROLL + RTEXT "Connect &Settings:",IDC_STATIC,10,170,35,20 + EDITTEXT DRV_CONNSETTINGS,50,170,225,25,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN DEFPUSHBUTTON "OK",IDOK,45,205,50,14,WS_GROUP PUSHBUTTON "Cancel",IDCANCEL,115,205,50,14 PUSHBUTTON "Defaults",IDDEFAULTS,185,205,50,15 END -DLG_OPTIONS_DS DIALOG DISCARDABLE 0, 0, 267, 170 +DLG_OPTIONS_DS DIALOG DISCARDABLE 0, 0, 267, 161 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Advanced Options (DataSource)" FONT 8, "MS Sans Serif" BEGIN CONTROL "&ReadOnly",DS_READONLY,"Button",BS_AUTOCHECKBOX | - WS_GROUP | WS_TABSTOP,25,10,45,15 - CONTROL "&6.2 Protocol",DS_PG62,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,130,10,60,14 - CONTROL "Show System &Tables",DS_SHOWSYSTEMTABLES,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,25,30,85,10 + WS_GROUP | WS_TABSTOP,25,10,53,10 CONTROL "Row &Versioning",DS_ROWVERSIONING,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,130,30,85,10 - GROUPBOX "OID Options",IDC_STATIC,15,50,180,25 + BS_AUTOCHECKBOX | WS_TABSTOP,130,10,85,10 + CONTROL "Show System &Tables",DS_SHOWSYSTEMTABLES,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,25,25,85,10 + GROUPBOX "Protocol",IDC_STATIC,15,40,180,25 + CONTROL "6.4",DS_PG64,"Button",BS_AUTORADIOBUTTON | WS_GROUP,25, + 50,26,10 + CONTROL "6.3",DS_PG63,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP, + 75,50,26,10 + CONTROL "6.2",DS_PG62,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP, + 130,50,26,10 + GROUPBOX "OID Options",IDC_STATIC,15,70,180,25 CONTROL "Show &Column",DS_SHOWOIDCOLUMN,"Button",BS_AUTOCHECKBOX | - WS_GROUP | WS_TABSTOP,25,60,59,10 + WS_GROUP | WS_TABSTOP,25,81,59,10 CONTROL "Fake &Index",DS_FAKEOIDINDEX,"Button",BS_AUTOCHECKBOX | - WS_GROUP | WS_TABSTOP,115,60,51,10 - RTEXT "Connect &Settings:",IDC_STATIC,10,90,35,25 - EDITTEXT DS_CONNSETTINGS,50,85,200,35,ES_MULTILINE | + WS_GROUP | WS_TABSTOP,115,81,51,10 + RTEXT "Connect &Settings:",IDC_STATIC,10,105,35,25 + EDITTEXT DS_CONNSETTINGS,50,105,200,20,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN - DEFPUSHBUTTON "OK",IDOK,65,130,50,14,WS_GROUP - PUSHBUTTON "Cancel",IDCANCEL,140,130,50,14 - GROUPBOX "Unknown Sizes",IDC_STATIC,10,145,175,25,NOT WS_VISIBLE - CONTROL "Maximum",DS_UNKNOWN_MAX,"Button",BS_AUTORADIOBUTTON | - NOT WS_VISIBLE | WS_GROUP | WS_TABSTOP,15,155,45,10 - CONTROL "Don't Know",DS_UNKNOWN_DONTKNOW,"Button", - BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_TABSTOP,70,155, - 53,10 - CONTROL "Longest",DS_UNKNOWN_LONGEST,"Button",BS_AUTORADIOBUTTON | - NOT WS_VISIBLE | WS_TABSTOP,130,155,50,10 + DEFPUSHBUTTON "OK",IDOK,71,135,50,14,WS_GROUP + PUSHBUTTON "Cancel",IDCANCEL,146,135,50,14 END @@ -190,7 +189,7 @@ BEGIN RIGHTMARGIN, 260 VERTGUIDE, 55 TOPMARGIN, 7 - BOTTOMMARGIN, 163 + BOTTOMMARGIN, 154 END END #endif // APSTUDIO_INVOKED @@ -203,8 +202,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 6,30,2,50 - PRODUCTVERSION 6,30,2,50 + FILEVERSION 6,40,0,1 + PRODUCTVERSION 6,40,0,1 FILEFLAGSMASK 0x3L #ifdef _DEBUG FILEFLAGS 0x1L @@ -222,12 +221,12 @@ BEGIN VALUE "Comments", "PostgreSQL ODBC driver for Windows 95\0" VALUE "CompanyName", "Insight Distribution Systems\0" VALUE "FileDescription", "PostgreSQL Driver\0" - VALUE "FileVersion", " 6.30.0250\0" + VALUE "FileVersion", " 6.40.0001\0" VALUE "InternalName", "psqlodbc\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 "ProductName", "Microsoft Open Database Connectivity\0" - VALUE "ProductVersion", " 6.30.0250\0" + VALUE "ProductVersion", " 6.40.0001\0" END END BLOCK "VarFileInfo" diff --git a/src/interfaces/odbc/qresult.c b/src/interfaces/odbc/qresult.c index cae730d8ae..d5ee8407c8 100644 --- a/src/interfaces/odbc/qresult.c +++ b/src/interfaces/odbc/qresult.c @@ -186,8 +186,7 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor) if (conn != NULL) { self->conn = conn; - mylog("QR_fetch_tuples: cursor = '%s', self->cursor=%u\n", - (cursor==NULL)?"":cursor, self->cursor); + mylog("QR_fetch_tuples: cursor = '%s', self->cursor=%u\n", cursor, self->cursor); if (self->cursor) free(self->cursor); @@ -203,7 +202,7 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor) // Read the field attributes. // $$$$ Should do some error control HERE! $$$$ - if ( CI_read_fields(self->fields, CC_get_socket(self->conn))) { + if ( CI_read_fields(self->fields, self->conn)) { self->status = PGRES_FIELDS_OK; self->num_fields = CI_get_num_fields(self->fields); } @@ -236,7 +235,7 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor) // Always have to read the field attributes. // But we dont have to reallocate memory for them! - if ( ! CI_read_fields(NULL, CC_get_socket(self->conn))) { + if ( ! CI_read_fields(NULL, self->conn)) { self->status = PGRES_BAD_RESPONSE; QR_set_message(self, "Error reading field information"); return FALSE; @@ -369,6 +368,7 @@ char cmdbuffer[MAX_MESSAGE_LEN+1]; // QR_set_command() dups this string so dont for ( ; ;) { id = SOCK_get_char(sock); + switch (id) { case 'T': /* Tuples within tuples cannot be handled */ self->status = PGRES_BAD_RESPONSE; @@ -441,6 +441,8 @@ char cmdbuffer[MAX_MESSAGE_LEN+1]; // QR_set_command() dups this string so dont continue; default: /* this should only happen if the backend dumped core */ + mylog("QR_next_tuple: Unexpected result from backend: id = '%c' (%d)\n", id, id); + qlog("QR_next_tuple: Unexpected result from backend: id = '%c' (%d)\n", id, id); QR_set_message(self, "Unexpected result from backend. It probably crashed"); self->status = PGRES_FATAL_ERROR; CC_set_no_trans(self->conn); diff --git a/src/interfaces/odbc/qresult.h b/src/interfaces/odbc/qresult.h index f05830d6d4..7cc2303173 100644 --- a/src/interfaces/odbc/qresult.h +++ b/src/interfaces/odbc/qresult.h @@ -72,12 +72,13 @@ struct QResultClass_ { #define QR_get_fieldname(self, fieldno_) (CI_get_fieldname(self->fields, fieldno_)) #define QR_get_fieldsize(self, fieldno_) (CI_get_fieldsize(self->fields, fieldno_)) #define QR_get_display_size(self, fieldno_) (CI_get_display_size(self->fields, fieldno_)) +#define QR_get_atttypmod(self, fieldno_) (CI_get_atttypmod(self->fields, fieldno_)) #define QR_get_field_type(self, fieldno_) (CI_get_oid(self->fields, fieldno_)) /* These functions are used only for manual result sets */ #define QR_get_num_tuples(self) (self->manual_tuples ? TL_get_num_tuples(self->manual_tuples) : self->fcount) #define QR_add_tuple(self, new_tuple) (TL_add_tuple(self->manual_tuples, new_tuple)) -#define QR_set_field_info(self, field_num, name, adtid, adtsize) (CI_set_field_info(self->fields, field_num, name, adtid, adtsize)) +#define QR_set_field_info(self, field_num, name, adtid, adtsize) (CI_set_field_info(self->fields, field_num, name, adtid, adtsize, -1)) /* status macros */ #define QR_command_successful(self) ( !(self->status == PGRES_BAD_RESPONSE || self->status == PGRES_NONFATAL_ERROR || self->status == PGRES_FATAL_ERROR)) diff --git a/src/interfaces/odbc/resource.h b/src/interfaces/odbc/resource.h index c69953fe8d..16db18bbd2 100644 --- a/src/interfaces/odbc/resource.h +++ b/src/interfaces/odbc/resource.h @@ -24,8 +24,6 @@ #define DRV_OPTIMIZER 1019 #define DS_CONNSETTINGS 1020 #define IDC_DRIVER 1021 -#define DS_UNKNOWN_MAX 1023 -#define DS_UNKNOWN_DONTKNOW 1024 #define DRV_CONNSETTINGS 1031 #define DRV_UNIQUEINDEX 1032 #define DRV_UNKNOWN_MAX 1035 @@ -34,7 +32,6 @@ #define IDC_DESCTEXT 1039 #define DRV_MSG_LABEL 1040 #define DRV_UNKNOWN_LONGEST 1041 -#define DS_UNKNOWN_LONGEST 1042 #define DRV_TEXT_LONGVARCHAR 1043 #define DRV_UNKNOWNS_LONGVARCHAR 1044 #define DRV_CACHE_SIZE 1045 @@ -48,6 +45,9 @@ #define DS_ROWVERSIONING 1052 #define DRV_PARSE 1052 #define IDC_OPTIONS 1054 +#define DRV_KSQO 1055 +#define DS_PG64 1057 +#define DS_PG63 1058 // Next default values for new objects // @@ -55,7 +55,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 104 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1055 +#define _APS_NEXT_CONTROL_VALUE 1060 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/src/interfaces/odbc/results.c b/src/interfaces/odbc/results.c index 6bac9d0ede..5d9dfc30fb 100644 --- a/src/interfaces/odbc/results.c +++ b/src/interfaces/odbc/results.c @@ -855,7 +855,7 @@ mylog("SQLFetch: stmt = %u, stmt->result= %u\n", stmt, stmt->result); value = QR_get_value_backend_row(res, stmt->currTuple, lf); } - mylog("value = '%s'\n", (value==NULL)?"":value); + mylog("value = '%s'\n", value); retval = copy_and_convert_field_bindinfo(stmt, type, value, lf); diff --git a/src/interfaces/odbc/socket.h b/src/interfaces/odbc/socket.h index 50418f9942..d57d012a48 100644 --- a/src/interfaces/odbc/socket.h +++ b/src/interfaces/odbc/socket.h @@ -23,13 +23,6 @@ #include #define closesocket(xxx) close(xxx) #define SOCKETFD int -#ifndef INADDR_NONE -#ifndef _IN_ADDR_T -#define _IN_ADDR_T -typedef unsigned int in_addr_t; -#endif -#define INADDR_NONE ((in_addr_t)-1) -#endif #else #include #define SOCKETFD SOCKET diff --git a/src/interfaces/odbc/statement.h b/src/interfaces/odbc/statement.h index 52b64278c1..e9661ad83a 100644 --- a/src/interfaces/odbc/statement.h +++ b/src/interfaces/odbc/statement.h @@ -14,6 +14,8 @@ #include "config.h" #endif +#include "psqlodbc.h" + #ifndef WIN32 #include "iodbc.h" #include "isql.h" @@ -22,7 +24,6 @@ #include #endif -#include "psqlodbc.h" #ifndef FALSE #define FALSE (BOOL)0