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

Commit 87225ca

Browse files
author
Byron Nikolaidis
committed
Update for version 06-40-0001
1 parent f03729c commit 87225ca

19 files changed

+211
-133
lines changed

src/interfaces/odbc/columninfo.c

+28-4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
*/
1414

1515
#include "columninfo.h"
16+
#include "connection.h"
1617
#include "socket.h"
1718
#include <stdlib.h>
1819
#include <malloc.h>
@@ -31,6 +32,7 @@ ColumnInfoClass *rv;
3132
rv->adtid = NULL;
3233
rv->adtsize = NULL;
3334
rv->display_size = NULL;
35+
rv->atttypmod = NULL;
3436
}
3537

3638
return rv;
@@ -49,14 +51,19 @@ CI_Destructor(ColumnInfoClass *self)
4951
If self is null, then just read, don't store.
5052
*/
5153
char
52-
CI_read_fields(ColumnInfoClass *self, SocketClass *sock)
54+
CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn)
5355
{
5456
Int2 lf;
5557
int new_num_fields;
5658
Oid new_adtid;
5759
Int2 new_adtsize;
60+
Int4 new_atttypmod = -1;
5861
char new_field_name[MAX_MESSAGE_LEN+1];
62+
SocketClass *sock;
63+
ConnInfo *ci;
5964

65+
sock = CC_get_socket(conn);
66+
ci = &conn->connInfo;
6067

6168
/* at first read in the number of fields that are in the query */
6269
new_num_fields = (Int2) SOCK_get_int(sock, sizeof(Int2));
@@ -74,10 +81,23 @@ char new_field_name[MAX_MESSAGE_LEN+1];
7481
new_adtid = (Oid) SOCK_get_int(sock, 4);
7582
new_adtsize = (Int2) SOCK_get_int(sock, 2);
7683

77-
mylog("CI_read_fields: fieldname='%s', adtid=%d, adtsize=%d\n", new_field_name, new_adtid, new_adtsize);
84+
/* If 6.4 protocol, then read the atttypmod field */
85+
if ( ! PROTOCOL_63(ci) && ! PROTOCOL_62(ci)) {
86+
87+
mylog("READING ATTTYPMOD\n");
88+
new_atttypmod = (Int4) SOCK_get_int(sock, 4);
89+
90+
/* Subtract the header length */
91+
new_atttypmod -= 4;
92+
if (new_atttypmod < 0)
93+
new_atttypmod = -1;
94+
95+
}
96+
97+
mylog("CI_read_fields: fieldname='%s', adtid=%d, adtsize=%d, atttypmod=%d\n", new_field_name, new_adtid, new_adtsize, new_atttypmod);
7898

7999
if (self)
80-
CI_set_field_info(self, lf, new_field_name, new_adtid, new_adtsize);
100+
CI_set_field_info(self, lf, new_field_name, new_adtid, new_adtsize, new_atttypmod);
81101
}
82102

83103
return (SOCK_get_errcode(sock) == 0);
@@ -101,6 +121,8 @@ int num_fields = self->num_fields;
101121
free(self->adtid);
102122
free(self->adtsize);
103123
free(self->display_size);
124+
125+
free(self->atttypmod);
104126
}
105127

106128
void
@@ -114,11 +136,12 @@ CI_set_num_fields(ColumnInfoClass *self, int new_num_fields)
114136
self->adtid = (Oid *) malloc (sizeof(Oid) * self->num_fields);
115137
self->adtsize = (Int2 *) malloc (sizeof(Int2) * self->num_fields);
116138
self->display_size = (Int2 *) malloc(sizeof(Int2) * self->num_fields);
139+
self->atttypmod = (Int4 *) malloc(sizeof(Int4) * self->num_fields);
117140
}
118141

119142
void
120143
CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name,
121-
Oid new_adtid, Int2 new_adtsize)
144+
Oid new_adtid, Int2 new_adtsize, Int4 new_atttypmod)
122145
{
123146

124147
// check bounds
@@ -130,6 +153,7 @@ CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name,
130153
self->name[field_num] = strdup(new_name);
131154
self->adtid[field_num] = new_adtid;
132155
self->adtsize[field_num] = new_adtsize;
156+
self->atttypmod[field_num] = new_atttypmod;
133157

134158
self->display_size[field_num] = 0;
135159
}

src/interfaces/odbc/columninfo.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,26 @@ struct ColumnInfoClass_ {
1818
Oid *adtid; /* list of type ids */
1919
Int2 *adtsize; /* list type sizes */
2020
Int2 *display_size; /* the display size (longest row) */
21+
Int4 *atttypmod; /* the length of bpchar/varchar */
2122
};
2223

2324
#define CI_get_num_fields(self) (self->num_fields)
2425
#define CI_get_oid(self, col) (self->adtid[col])
2526
#define CI_get_fieldname(self, col) (self->name[col])
2627
#define CI_get_fieldsize(self, col) (self->adtsize[col])
2728
#define CI_get_display_size(self, col) (self->display_size[col])
29+
#define CI_get_atttypmod(self, col) (self->atttypmod[col])
2830

2931
ColumnInfoClass *CI_Constructor(void);
3032
void CI_Destructor(ColumnInfoClass *self);
3133
void CI_free_memory(ColumnInfoClass *self);
32-
char CI_read_fields(ColumnInfoClass *self, SocketClass *sock);
34+
char CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn);
3335

3436
/* functions for setting up the fields from within the program, */
3537
/* without reading from a socket */
3638
void CI_set_num_fields(ColumnInfoClass *self, int new_num_fields);
3739
void CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name,
38-
Oid new_adtid, Int2 new_adtsize);
40+
Oid new_adtid, Int2 new_adtsize, Int4 atttypmod);
3941

4042

4143
#endif

src/interfaces/odbc/connection.c

+48-14
Original file line numberDiff line numberDiff line change
@@ -472,8 +472,9 @@ static char *func="CC_connect";
472472
globals.unknown_sizes,
473473
globals.max_varchar_size,
474474
globals.max_longvarchar_size);
475-
qlog(" disable_optimizer=%d, unique_index=%d, use_declarefetch=%d\n",
475+
qlog(" disable_optimizer=%d, ksqo=%d, unique_index=%d, use_declarefetch=%d\n",
476476
globals.disable_optimizer,
477+
globals.ksqo,
477478
globals.unique_index,
478479
globals.use_declarefetch);
479480
qlog(" text_as_longvarchar=%d, unknowns_as_longvarchar=%d, bools_as_char=%d\n",
@@ -542,7 +543,11 @@ static char *func="CC_connect";
542543
// Send length of Authentication Block
543544
SOCK_put_int(sock, 4+sizeof(StartupPacket), 4);
544545

545-
sp.protoVersion = (ProtocolVersion) htonl(PG_PROTOCOL_LATEST);
546+
if ( PROTOCOL_63(ci))
547+
sp.protoVersion = (ProtocolVersion) htonl(PG_PROTOCOL_63);
548+
else
549+
sp.protoVersion = (ProtocolVersion) htonl(PG_PROTOCOL_LATEST);
550+
546551
strncpy(sp.database, ci->database, SM_DATABASE);
547552
strncpy(sp.user, ci->username, SM_USER);
548553

@@ -913,22 +918,41 @@ char cmdbuffer[MAX_MESSAGE_LEN+1]; // QR_set_command() dups this string so dont
913918

914919
SOCK_put_string(sock, "Q ");
915920
SOCK_flush_output(sock);
916-
while(!clear) {
917-
SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
918-
mylog("send_query: read command '%s'\n", cmdbuffer);
919-
clear = (cmdbuffer[0] == 'I');
920-
921-
if (cmdbuffer[0] == 'N')
922-
qlog("NOTICE from backend during send_query: '%s'\n", &cmdbuffer[1]);
923-
else if (cmdbuffer[0] == 'E')
924-
qlog("ERROR from backend during send_query: '%s'\n", &cmdbuffer[1]);
925-
else if (cmdbuffer[0] == 'C')
926-
qlog("Command response: '%s'\n", &cmdbuffer[1]);
927-
}
928921

922+
while( ! clear) {
923+
id = SOCK_get_char(sock);
924+
switch(id) {
925+
case 'I':
926+
(void) SOCK_get_char(sock);
927+
clear = TRUE;
928+
break;
929+
case 'Z':
930+
break;
931+
case 'C':
932+
SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
933+
qlog("Command response: '%s'\n", cmdbuffer);
934+
break;
935+
case 'N':
936+
SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
937+
qlog("NOTICE from backend during clear: '%s'\n", cmdbuffer);
938+
break;
939+
case 'E':
940+
SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
941+
qlog("ERROR from backend during clear: '%s'\n", cmdbuffer);
942+
break;
943+
}
944+
}
945+
929946
mylog("send_query: returning res = %u\n", res);
930947
return res;
931948
}
949+
case 'K': /* Secret key (6.4 protocol) */
950+
(void)SOCK_get_int(sock, 4); /* pid */
951+
(void)SOCK_get_int(sock, 4); /* key */
952+
953+
break;
954+
case 'Z': /* Backend is ready for new query (6.4) */
955+
break;
932956
case 'N' : /* NOTICE: */
933957
SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
934958

@@ -1209,6 +1233,16 @@ static char *func="CC_send_settings";
12091233

12101234
}
12111235

1236+
/* KSQO */
1237+
if (globals.ksqo) {
1238+
result = SQLExecDirect(hstmt, "set ksqo to 'ON'", SQL_NTS);
1239+
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
1240+
status = FALSE;
1241+
1242+
mylog("%s: result %d, status %d from set ksqo\n", func, result, status);
1243+
1244+
}
1245+
12121246
/* Global settings */
12131247
if (globals.conn_settings[0] != '\0') {
12141248
cs = strdup(globals.conn_settings);

src/interfaces/odbc/connection.h

+8-4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include "config.h"
1515
#endif
1616

17+
#include "psqlodbc.h"
18+
1719
#ifndef WIN32
1820
#include "iodbc.h"
1921
#include "isql.h"
@@ -24,7 +26,6 @@
2426
#include <sqlext.h>
2527
#endif
2628

27-
#include "psqlodbc.h"
2829

2930
typedef enum {
3031
CONN_NOT_CONNECTED, /* Connection has not been established */
@@ -100,10 +101,11 @@ typedef enum {
100101
typedef unsigned int ProtocolVersion;
101102

102103
#define PG_PROTOCOL(major, minor) (((major) << 16) | (minor))
103-
#define PG_PROTOCOL_LATEST PG_PROTOCOL(1, 0)
104-
#define PG_PROTOCOL_EARLIEST PG_PROTOCOL(0, 0)
104+
#define PG_PROTOCOL_LATEST PG_PROTOCOL(2, 0)
105+
#define PG_PROTOCOL_63 PG_PROTOCOL(1, 0)
106+
#define PG_PROTOCOL_62 PG_PROTOCOL(0, 0)
105107

106-
/* This startup packet is to support latest Postgres protocol (6.3) */
108+
/* This startup packet is to support latest Postgres protocol (6.4, 6.3) */
107109
typedef struct _StartupPacket
108110
{
109111
ProtocolVersion protoVersion;
@@ -154,6 +156,8 @@ typedef struct {
154156
/* Macro to determine is the connection using 6.2 protocol? */
155157
#define PROTOCOL_62(conninfo_) (strncmp((conninfo_)->protocol, PG62, strlen(PG62)) == 0)
156158

159+
/* Macro to determine is the connection using 6.3 protocol? */
160+
#define PROTOCOL_63(conninfo_) (strncmp((conninfo_)->protocol, PG63, strlen(PG63)) == 0)
157161

158162

159163
/* This is used to store cached table information in the connection */

src/interfaces/odbc/convert.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include <string.h>
2525
#include <ctype.h>
2626

27+
#include "psqlodbc.h"
28+
2729
#ifndef WIN32
2830
#include "iodbc.h"
2931
#include "isql.h"
@@ -120,7 +122,7 @@ struct tm *tim;
120122
st.d = tim->tm_mday;
121123
st.y = tim->tm_year + 1900;
122124

123-
mylog("copy_and_convert: field_type = %d, fctype = %d, value = '%s', cbValueMax=%d\n", field_type, fCType, (value==NULL)?"<NULL>":value, cbValueMax);
125+
mylog("copy_and_convert: field_type = %d, fctype = %d, value = '%s', cbValueMax=%d\n", field_type, fCType, value, cbValueMax);
124126

125127
if ( ! value) {
126128
/* handle a null just by returning SQL_NULL_DATA in pcbValue, */

src/interfaces/odbc/dlg_specific.c

+22-5
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ int CALLBACK driver_optionsProc(HWND hdlg,
8787

8888
CheckDlgButton(hdlg, DRV_COMMLOG, globals.commlog);
8989
CheckDlgButton(hdlg, DRV_OPTIMIZER, globals.disable_optimizer);
90+
CheckDlgButton(hdlg, DRV_KSQO, globals.ksqo);
9091
CheckDlgButton(hdlg, DRV_UNIQUEINDEX, globals.unique_index);
9192
CheckDlgButton(hdlg, DRV_READONLY, globals.readonly);
9293
CheckDlgButton(hdlg, DRV_USEDECLAREFETCH, globals.use_declarefetch);
@@ -128,6 +129,7 @@ int CALLBACK driver_optionsProc(HWND hdlg,
128129

129130
globals.commlog = IsDlgButtonChecked(hdlg, DRV_COMMLOG);
130131
globals.disable_optimizer = IsDlgButtonChecked(hdlg, DRV_OPTIMIZER);
132+
globals.ksqo = IsDlgButtonChecked(hdlg, DRV_KSQO);
131133
globals.unique_index = IsDlgButtonChecked(hdlg, DRV_UNIQUEINDEX);
132134
globals.readonly = IsDlgButtonChecked(hdlg, DRV_READONLY);
133135
globals.use_declarefetch = IsDlgButtonChecked(hdlg, DRV_USEDECLAREFETCH);
@@ -168,6 +170,7 @@ int CALLBACK driver_optionsProc(HWND hdlg,
168170
case IDDEFAULTS:
169171
CheckDlgButton(hdlg, DRV_COMMLOG, DEFAULT_COMMLOG);
170172
CheckDlgButton(hdlg, DRV_OPTIMIZER, DEFAULT_OPTIMIZER);
173+
CheckDlgButton(hdlg, DRV_KSQO, DEFAULT_KSQO);
171174
CheckDlgButton(hdlg, DRV_UNIQUEINDEX, DEFAULT_UNIQUEINDEX);
172175
CheckDlgButton(hdlg, DRV_READONLY, DEFAULT_READONLY);
173176
CheckDlgButton(hdlg, DRV_USEDECLAREFETCH, DEFAULT_USEDECLAREFETCH);
@@ -238,8 +241,11 @@ char buf[128];
238241
/* Protocol */
239242
if (strncmp(ci->protocol, PG62, strlen(PG62)) == 0)
240243
CheckDlgButton(hdlg, DS_PG62, 1);
241-
else
242-
CheckDlgButton(hdlg, DS_PG62, 0);
244+
else if (strncmp(ci->protocol, PG63, strlen(PG63)) == 0)
245+
CheckDlgButton(hdlg, DS_PG63, 1);
246+
else
247+
CheckDlgButton(hdlg, DS_PG64, 1);
248+
243249

244250

245251
CheckDlgButton(hdlg, DS_SHOWOIDCOLUMN, atoi(ci->show_oid_column));
@@ -273,11 +279,11 @@ char buf[128];
273279
/* Protocol */
274280
if ( IsDlgButtonChecked(hdlg, DS_PG62))
275281
strcpy(ci->protocol, PG62);
276-
else
282+
else if ( IsDlgButtonChecked(hdlg, DS_PG63))
283+
strcpy(ci->protocol, PG63);
284+
else
277285
ci->protocol[0] = '\0';
278286

279-
280-
281287
sprintf(ci->show_system_tables, "%d", IsDlgButtonChecked(hdlg, DS_SHOWSYSTEMTABLES));
282288

283289
sprintf(ci->row_versioning, "%d", IsDlgButtonChecked(hdlg, DS_ROWVERSIONING));
@@ -634,6 +640,13 @@ char temp[256];
634640
else if ( ! override)
635641
globals.disable_optimizer = DEFAULT_OPTIMIZER;
636642

643+
// KSQO is stored in the driver section only
644+
SQLGetPrivateProfileString(section, INI_KSQO, "",
645+
temp, sizeof(temp), filename);
646+
if ( temp[0] )
647+
globals.ksqo = atoi(temp);
648+
else if ( ! override)
649+
globals.ksqo = DEFAULT_KSQO;
637650

638651
// Recognize Unique Index is stored in the driver section only
639652
SQLGetPrivateProfileString(section, INI_UNIQUEINDEX, "",
@@ -769,6 +782,10 @@ char tmp[128];
769782
SQLWritePrivateProfileString(DBMS_NAME,
770783
INI_OPTIMIZER, tmp, ODBCINST_INI);
771784

785+
sprintf(tmp, "%d", globals.ksqo);
786+
SQLWritePrivateProfileString(DBMS_NAME,
787+
INI_KSQO, tmp, ODBCINST_INI);
788+
772789
sprintf(tmp, "%d", globals.unique_index);
773790
SQLWritePrivateProfileString(DBMS_NAME,
774791
INI_UNIQUEINDEX, tmp, ODBCINST_INI);

src/interfaces/odbc/dlg_specific.h

+2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
#define INI_COMMLOG "CommLog" /* Communication to backend logging */
6060
#define INI_PROTOCOL "Protocol" /* What protocol (6.2) */
6161
#define INI_OPTIMIZER "Optimizer" /* Use backend genetic optimizer */
62+
#define INI_KSQO "Ksqo" /* Keyset query optimization */
6263
#define INI_CONNSETTINGS "ConnSettings" /* Anything to send to backend on successful connection */
6364
#define INI_UNIQUEINDEX "UniqueIndex" /* Recognize unique indexes */
6465
#define INI_UNKNOWNSIZES "UnknownSizes" /* How to handle unknown result set sizes */
@@ -93,6 +94,7 @@
9394
#define DEFAULT_UNKNOWNSASLONGVARCHAR 0
9495
#define DEFAULT_BOOLSASCHAR 1
9596
#define DEFAULT_OPTIMIZER 1 // disable
97+
#define DEFAULT_KSQO 1 // on
9698
#define DEFAULT_UNIQUEINDEX 0 // dont recognize
9799
#define DEFAULT_COMMLOG 0 // dont log
98100
#define DEFAULT_DEBUG 0

src/interfaces/odbc/execute.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ RETCODE SQL_API SQLExecDirect(
129129
SDWORD cbSqlStr)
130130
{
131131
StatementClass *stmt = (StatementClass *) hstmt;
132-
RETCODE SQL_API result;
132+
RETCODE result;
133133
static char *func = "SQLExecDirect";
134134

135135
mylog( "%s: entering...\n", func);

src/interfaces/odbc/misc.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ generate_filename(char* dirname,char* prefix,char* filename)
4444
return;
4545

4646
strcpy(filename,dirname);
47-
strcat(filename,DIRSEPARATOR);
47+
strcat(filename,DIRSEPERATOR);
4848
if(prefix != 0)
4949
strcat(filename,prefix);
5050
#ifndef WIN32

0 commit comments

Comments
 (0)