aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/odbc/connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interfaces/odbc/connection.c')
-rw-r--r--src/interfaces/odbc/connection.c71
1 files changed, 69 insertions, 2 deletions
diff --git a/src/interfaces/odbc/connection.c b/src/interfaces/odbc/connection.c
index d6b622a16d7..7cee671e2b6 100644
--- a/src/interfaces/odbc/connection.c
+++ b/src/interfaces/odbc/connection.c
@@ -19,6 +19,9 @@
#include <stdio.h>
#include <string.h>
#include <ctype.h>
+#ifndef WIN32
+#include <errno.h>
+#endif /* WIN32 */
#include "environ.h"
#include "socket.h"
@@ -289,6 +292,7 @@ CC_Constructor()
rv->ms_jet = 0;
rv->unicode = 0;
rv->result_uncommitted = 0;
+ rv->schema_support = 0;
#ifdef MULTIBYTE
rv->client_encoding = NULL;
rv->server_encoding = NULL;
@@ -882,8 +886,8 @@ another_version_retry:
}
break;
case 'K': /* Secret key (6.4 protocol) */
- (void) SOCK_get_int(sock, 4); /* pid */
- (void) SOCK_get_int(sock, 4); /* key */
+ self->be_pid = SOCK_get_int(sock, 4); /* pid */
+ self->be_key = SOCK_get_int(sock, 4); /* key */
break;
case 'Z': /* Backend is ready for new query (6.4) */
@@ -1960,6 +1964,8 @@ CC_lookup_pg_version(ConnectionClass *self)
self->pg_version_minor = minor;
}
self->pg_version_number = (float) atof(szVersion);
+ if (PG_VERSION_GE(self, 7.3))
+ self->schema_support = 1;
mylog("Got the PostgreSQL version string: '%s'\n", self->pg_version);
mylog("Extracted PostgreSQL version number: '%1.1f'\n", self->pg_version_number);
@@ -2019,3 +2025,64 @@ CC_get_max_query_len(const ConnectionClass *conn)
value = BLCKSZ;
return value;
}
+
+int
+CC_send_cancel_request(const ConnectionClass *conn)
+{
+#ifdef WIN32
+ int save_errno = (WSAGetLastError());
+#else
+ int save_errno = errno;
+#endif
+ int tmpsock = -1;
+ struct
+ {
+ uint32 packetlen;
+ CancelRequestPacket cp;
+ } crp;
+
+ /* Check we have an open connection */
+ if (!conn)
+ return FALSE;
+
+ if (conn->sock == NULL )
+ {
+ return FALSE;
+ }
+
+ /*
+ * We need to open a temporary connection to the postmaster. Use the
+ * information saved by connectDB to do this with only kernel calls.
+ */
+ if ((tmpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ return FALSE;
+ }
+ if (connect(tmpsock, (struct sockaddr *)&(conn->sock->sadr),
+ sizeof(conn->sock->sadr)) < 0)
+ {
+ return FALSE;
+ }
+
+ /*
+ * We needn't set nonblocking I/O or NODELAY options here.
+ */
+ crp.packetlen = htonl((uint32) sizeof(crp));
+ crp.cp.cancelRequestCode = (MsgType) htonl(CANCEL_REQUEST_CODE);
+ crp.cp.backendPID = htonl(conn->be_pid);
+ crp.cp.cancelAuthCode = htonl(conn->be_key);
+
+ if (send(tmpsock, (char *) &crp, sizeof(crp), 0) != (int) sizeof(crp))
+ {
+ return FALSE;
+ }
+
+ /* Sent it, done */
+ closesocket(tmpsock);
+#ifdef WIN32
+ WSASetLastError(save_errno);
+#else
+ errno = save_errno;
+#endif
+ return TRUE;
+}