Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf8da399

Browse files
author
Hiroshi Inoue
committed
[HACKERS] Proposed patch for ODBC driver w/ C-a-n-c-e-l
From: Bradley McLean <brad@bradm.net>Patch against 7,2 submitted for comment.This seems to work just fine; Now, when our users submit a 2 hourquery with four million row sorts by accident, then cancel it 30 secondslater, it doesn't bog down the server ...
1 parentc26a44d commitf8da399

File tree

12 files changed

+455
-107
lines changed

12 files changed

+455
-107
lines changed

‎src/interfaces/odbc/connection.c

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
#include<stdio.h>
2020
#include<string.h>
2121
#include<ctype.h>
22+
#ifndefWIN32
23+
#include<errno.h>
24+
#endif/* WIN32 */
2225

2326
#include"environ.h"
2427
#include"socket.h"
@@ -289,6 +292,7 @@ CC_Constructor()
289292
rv->ms_jet=0;
290293
rv->unicode=0;
291294
rv->result_uncommitted=0;
295+
rv->schema_support=0;
292296
#ifdefMULTIBYTE
293297
rv->client_encoding=NULL;
294298
rv->server_encoding=NULL;
@@ -882,8 +886,8 @@ CC_connect(ConnectionClass *self, char do_password)
882886
}
883887
break;
884888
case'K':/* Secret key (6.4 protocol) */
885-
(void)SOCK_get_int(sock,4);/* pid */
886-
(void)SOCK_get_int(sock,4);/* key */
889+
self->be_pid=SOCK_get_int(sock,4);/* pid */
890+
self->be_key=SOCK_get_int(sock,4);/* key */
887891

888892
break;
889893
case'Z':/* Backend is ready for new query (6.4) */
@@ -1960,6 +1964,8 @@ CC_lookup_pg_version(ConnectionClass *self)
19601964
self->pg_version_minor=minor;
19611965
}
19621966
self->pg_version_number= (float)atof(szVersion);
1967+
if (PG_VERSION_GE(self,7.3))
1968+
self->schema_support=1;
19631969

19641970
mylog("Got the PostgreSQL version string: '%s'\n",self->pg_version);
19651971
mylog("Extracted PostgreSQL version number: '%1.1f'\n",self->pg_version_number);
@@ -2019,3 +2025,64 @@ CC_get_max_query_len(const ConnectionClass *conn)
20192025
value=BLCKSZ;
20202026
returnvalue;
20212027
}
2028+
2029+
int
2030+
CC_send_cancel_request(constConnectionClass*conn)
2031+
{
2032+
#ifdefWIN32
2033+
intsave_errno= (WSAGetLastError());
2034+
#else
2035+
intsave_errno=errno;
2036+
#endif
2037+
inttmpsock=-1;
2038+
struct
2039+
{
2040+
uint32packetlen;
2041+
CancelRequestPacketcp;
2042+
}crp;
2043+
2044+
/* Check we have an open connection */
2045+
if (!conn)
2046+
return FALSE;
2047+
2048+
if (conn->sock==NULL )
2049+
{
2050+
return FALSE;
2051+
}
2052+
2053+
/*
2054+
* We need to open a temporary connection to the postmaster. Use the
2055+
* information saved by connectDB to do this with only kernel calls.
2056+
*/
2057+
if ((tmpsock=socket(AF_INET,SOCK_STREAM,0))<0)
2058+
{
2059+
return FALSE;
2060+
}
2061+
if (connect(tmpsock, (structsockaddr*)&(conn->sock->sadr),
2062+
sizeof(conn->sock->sadr))<0)
2063+
{
2064+
return FALSE;
2065+
}
2066+
2067+
/*
2068+
* We needn't set nonblocking I/O or NODELAY options here.
2069+
*/
2070+
crp.packetlen=htonl((uint32)sizeof(crp));
2071+
crp.cp.cancelRequestCode= (MsgType)htonl(CANCEL_REQUEST_CODE);
2072+
crp.cp.backendPID=htonl(conn->be_pid);
2073+
crp.cp.cancelAuthCode=htonl(conn->be_key);
2074+
2075+
if (send(tmpsock, (char*)&crp,sizeof(crp),0)!= (int)sizeof(crp))
2076+
{
2077+
return FALSE;
2078+
}
2079+
2080+
/* Sent it, done */
2081+
closesocket(tmpsock);
2082+
#ifdefWIN32
2083+
WSASetLastError(save_errno);
2084+
#else
2085+
errno=save_errno;
2086+
#endif
2087+
return TRUE;
2088+
}

‎src/interfaces/odbc/connection.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,21 @@ typedef struct _StartupPacket6_2
126126
chartty[PATH_SIZE];
127127
}StartupPacket6_2;
128128

129+
/* Transferred from pqcomm.h: */
130+
131+
132+
typedefProtocolVersionMsgType;
133+
134+
#definePG_PROTOCOL(m,n) (((m) << 16) | (n))
135+
#defineCANCEL_REQUEST_CODE PG_PROTOCOL(1234,5678)
136+
137+
typedefstructCancelRequestPacket
138+
{
139+
/* Note that each field is stored in network byte order! */
140+
MsgTypecancelRequestCode;/* code to identify a cancel request */
141+
unsignedintbackendPID;/* PID of client's backend */
142+
unsignedintcancelAuthCode;/* secret key to authorize cancel */
143+
}CancelRequestPacket;
129144

130145
/*Structure to hold all the connection attributes for a specific
131146
connection (used for both registry and file, DSN and DRIVER)
@@ -273,11 +288,14 @@ struct ConnectionClass_
273288
charms_jet;
274289
charunicode;
275290
charresult_uncommitted;
291+
charschema_support;
276292
#ifdefMULTIBYTE
277293
char*client_encoding;
278294
char*server_encoding;
279295
#endif/* MULTIBYTE */
280296
intccsc;
297+
intbe_pid;/* pid returned by backend */
298+
intbe_key;/* auth code needed to send cancel */
281299
};
282300

283301

@@ -319,6 +337,7 @@ voidCC_lookup_pg_version(ConnectionClass *conn);
319337
voidCC_initialize_pg_version(ConnectionClass*conn);
320338
voidCC_log_error(constchar*func,constchar*desc,constConnectionClass*self);
321339
intCC_get_max_query_len(constConnectionClass*self);
340+
intCC_send_cancel_request(constConnectionClass*conn);
322341
voidCC_on_commit(ConnectionClass*conn);
323342
voidCC_on_abort(ConnectionClass*conn,BOOLset_no_trans);
324343
voidProcessRollback(ConnectionClass*conn,BOOLundo);

‎src/interfaces/odbc/descriptor.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*
66
* Comments:See "notice.txt" for copyright and license information.
77
*
8-
* $Id: descriptor.h,v 1.2 2002/04/01 03:01:14 inoue Exp $
8+
* $Id: descriptor.h,v 1.3 2002/04/02 10:50:44 inoue Exp $
99
*
1010
*/
1111

@@ -17,6 +17,7 @@
1717
typedefstruct
1818
{
1919
COL_INFO*col_info;/* cached SQLColumns info for this table */
20+
charschema[MAX_TABLE_LEN+1];
2021
charname[MAX_TABLE_LEN+1];
2122
charalias[MAX_TABLE_LEN+1];
2223
}TABLE_INFO;

‎src/interfaces/odbc/execute.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,7 @@ PGAPI_Cancel(
573573
{
574574
staticchar*func="PGAPI_Cancel";
575575
StatementClass*stmt= (StatementClass*)hstmt;
576+
ConnectionClass*conn;
576577
RETCODEresult;
577578
ConnInfo*ci;
578579

@@ -589,14 +590,20 @@ PGAPI_Cancel(
589590
SC_log_error(func,"",NULL);
590591
returnSQL_INVALID_HANDLE;
591592
}
592-
ci=&(SC_get_conn(stmt)->connInfo);
593+
conn=SC_get_conn(stmt);
594+
ci=&(conn->connInfo);
593595

594596
/*
595597
* Not in the middle of SQLParamData/SQLPutData so cancel like a
596598
* close.
597599
*/
598600
if (stmt->data_at_exec<0)
599601
{
602+
/*
603+
* Tell the Backend that we're cancelling this request
604+
*/
605+
if (stmt->status==STMT_EXECUTING)
606+
CC_send_cancel_request(conn);
600607
/*
601608
* MAJOR HACK for Windows to reset the driver manager's cursor
602609
* state: Because of what seems like a bug in the Odbc driver

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp