<listitem>
<para>
Abort any statement that takes over the specified number of
- milliseconds. A value of zero (the default) turns off the limitation.
+ milliseconds. If <varname>log_min_error_statement</> is set to
+ <literal>ERROR</> or lower, the statement that timed out will also be
+ logged. A value of zero (the default) turns off the
+ limitation.
</para>
</listitem>
</varlistentry>
/* 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;
Assert(!deadlock_timeout_active);
statement_fin_time = fin_time;
statement_timeout_active = true;
+ cancel_from_timeout = false;
}
else if (statement_timeout_active)
{
MemSet(&timeval, 0, sizeof(struct itimerval));
if (setitimer(ITIMER_REAL, &timeval, NULL))
{
- statement_timeout_active = deadlock_timeout_active = false;
+ 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 = deadlock_timeout_active = false;
+ statement_timeout_active = false;
+ cancel_from_timeout = false;
+ deadlock_timeout_active = false;
return false;
}
#endif
/* Cancel or reschedule statement timeout */
if (is_statement_timeout)
+ {
statement_timeout_active = false;
+ cancel_from_timeout = false;
+ }
else if (statement_timeout_active)
{
if (!CheckStatementTimeout())
{
/* Time to die */
statement_timeout_active = false;
+ cancel_from_timeout = true;
kill(MyProcPid, SIGINT);
}
else
/* Set statement timeout running, if any */
if (StatementTimeout > 0)
enable_sig_alarm(StatementTimeout, true);
-
+ else
+ cancel_from_timeout = false;
+
xact_started = true;
}
}
ImmediateInterruptOK = false; /* not idle anymore */
DisableNotifyInterrupt();
DisableCatchupInterrupt();
- ereport(ERROR,
- (errcode(ERRCODE_QUERY_CANCELED),
- errmsg("canceling query due to user request or statement timeout")));
+ 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) */
}
extern int DeadlockTimeout;
extern int StatementTimeout;
+extern volatile bool cancel_from_timeout;
+
/*
* Function Prototypes
-- 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
+ERROR: canceling statement due to statement timeout
reset statement_timeout;
-- Disconnect, we will continue testing in a different backend
\c -
-- 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
+ERROR: canceling statement due to statement timeout
reset statement_timeout;
-- Commit table creation
COMMIT PREPARED 'regress-one';