Index: doc/src/sgml/config.sgml =================================================================== RCS file: /cvsroot/pgsql/doc/src/sgml/config.sgml,v retrieving revision 1.17 diff -c -c -r1.17 config.sgml *** doc/src/sgml/config.sgml 13 Sep 2005 15:24:56 -0000 1.17 --- doc/src/sgml/config.sgml 19 Sep 2005 16:58:53 -0000 *************** *** 3232,3238 **** Abort any statement that takes over the specified number of ! milliseconds. A value of zero (the default) turns off the limitation. --- 3232,3241 ---- Abort any statement that takes over the specified number of ! milliseconds. If log_min_error_statement is set to ! ERROR or lower, the statement that timed out will also be ! logged. A value of zero (the default) turns off the ! limitation. Index: src/backend/storage/lmgr/proc.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v retrieving revision 1.163 diff -c -c -r1.163 proc.c *** src/backend/storage/lmgr/proc.c 20 Aug 2005 23:26:24 -0000 1.163 --- src/backend/storage/lmgr/proc.c 19 Sep 2005 16:58:55 -0000 *************** *** 78,83 **** --- 78,84 ---- /* Mark these volatile because they can be changed by signal handler */ static volatile bool statement_timeout_active = false; static volatile bool deadlock_timeout_active = false; + volatile bool cancel_from_timeout = false; /* statement_fin_time is valid only if statement_timeout_active is true */ static struct timeval statement_fin_time; *************** *** 1058,1063 **** --- 1059,1065 ---- Assert(!deadlock_timeout_active); statement_fin_time = fin_time; statement_timeout_active = true; + cancel_from_timeout = false; } else if (statement_timeout_active) { *************** *** 1128,1141 **** MemSet(&timeval, 0, sizeof(struct itimerval)); if (setitimer(ITIMER_REAL, &timeval, NULL)) { ! statement_timeout_active = deadlock_timeout_active = false; return false; } #else /* BeOS doesn't have setitimer, but has set_alarm */ if (set_alarm(B_INFINITE_TIMEOUT, B_PERIODIC_ALARM) < 0) { ! statement_timeout_active = deadlock_timeout_active = false; return false; } #endif --- 1130,1147 ---- MemSet(&timeval, 0, sizeof(struct itimerval)); if (setitimer(ITIMER_REAL, &timeval, NULL)) { ! statement_timeout_active = false; ! cancel_from_timeout = false; ! deadlock_timeout_active = false; return false; } #else /* BeOS doesn't have setitimer, but has set_alarm */ if (set_alarm(B_INFINITE_TIMEOUT, B_PERIODIC_ALARM) < 0) { ! statement_timeout_active = false; ! cancel_from_timeout = false; ! deadlock_timeout_active = false; return false; } #endif *************** *** 1146,1152 **** --- 1152,1161 ---- /* Cancel or reschedule statement timeout */ if (is_statement_timeout) + { statement_timeout_active = false; + cancel_from_timeout = false; + } else if (statement_timeout_active) { if (!CheckStatementTimeout()) *************** *** 1179,1184 **** --- 1188,1194 ---- { /* Time to die */ statement_timeout_active = false; + cancel_from_timeout = true; kill(MyProcPid, SIGINT); } else Index: src/backend/tcop/postgres.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/tcop/postgres.c,v retrieving revision 1.459 diff -c -c -r1.459 postgres.c *** src/backend/tcop/postgres.c 16 Sep 2005 19:31:04 -0000 1.459 --- src/backend/tcop/postgres.c 19 Sep 2005 16:58:58 -0000 *************** *** 1979,1985 **** /* Set statement timeout running, if any */ if (StatementTimeout > 0) enable_sig_alarm(StatementTimeout, true); ! xact_started = true; } } --- 1979,1987 ---- /* Set statement timeout running, if any */ if (StatementTimeout > 0) enable_sig_alarm(StatementTimeout, true); ! else ! cancel_from_timeout = false; ! xact_started = true; } } *************** *** 2203,2211 **** ImmediateInterruptOK = false; /* not idle anymore */ DisableNotifyInterrupt(); DisableCatchupInterrupt(); ! ereport(ERROR, ! (errcode(ERRCODE_QUERY_CANCELED), ! errmsg("canceling query due to user request or statement timeout"))); } /* If we get here, do nothing (probably, QueryCancelPending was reset) */ } --- 2205,2218 ---- ImmediateInterruptOK = false; /* not idle anymore */ DisableNotifyInterrupt(); DisableCatchupInterrupt(); ! if (cancel_from_timeout) ! ereport(ERROR, ! (errcode(ERRCODE_QUERY_CANCELED), ! errmsg("canceling statement due to statement timeout"))); ! else ! ereport(ERROR, ! (errcode(ERRCODE_QUERY_CANCELED), ! errmsg("canceling statement due to user request"))); } /* If we get here, do nothing (probably, QueryCancelPending was reset) */ } Index: src/include/storage/proc.h =================================================================== RCS file: /cvsroot/pgsql/src/include/storage/proc.h,v retrieving revision 1.81 diff -c -c -r1.81 proc.h *** src/include/storage/proc.h 20 Aug 2005 23:26:34 -0000 1.81 --- src/include/storage/proc.h 19 Sep 2005 16:58:59 -0000 *************** *** 117,122 **** --- 117,124 ---- extern int DeadlockTimeout; extern int StatementTimeout; + extern volatile bool cancel_from_timeout; + /* * Function Prototypes Index: src/test/regress/expected/prepared_xacts.out =================================================================== RCS file: /cvsroot/pgsql/src/test/regress/expected/prepared_xacts.out,v retrieving revision 1.2 diff -c -c -r1.2 prepared_xacts.out *** src/test/regress/expected/prepared_xacts.out 16 Sep 2005 19:39:02 -0000 1.2 --- src/test/regress/expected/prepared_xacts.out 19 Sep 2005 16:59:00 -0000 *************** *** 159,165 **** -- pxtest3 should be locked because of the pending DROP set statement_timeout to 1000; SELECT * FROM pxtest3; ! ERROR: canceling query due to user request or statement timeout reset statement_timeout; -- Disconnect, we will continue testing in a different backend \c - --- 159,165 ---- -- pxtest3 should be locked because of the pending DROP set statement_timeout to 1000; SELECT * FROM pxtest3; ! ERROR: canceling statement due to statement timeout reset statement_timeout; -- Disconnect, we will continue testing in a different backend \c - *************** *** 174,180 **** -- pxtest3 should still be locked because of the pending DROP set statement_timeout to 1000; SELECT * FROM pxtest3; ! ERROR: canceling query due to user request or statement timeout reset statement_timeout; -- Commit table creation COMMIT PREPARED 'regress-one'; --- 174,180 ---- -- pxtest3 should still be locked because of the pending DROP set statement_timeout to 1000; SELECT * FROM pxtest3; ! ERROR: canceling statement due to statement timeout reset statement_timeout; -- Commit table creation COMMIT PREPARED 'regress-one';