timeout implementation issues

Started by Jessica Perry Hekmanalmost 24 years ago157 messages
#1Jessica Perry Hekman
jphekman@dynamicdiagrams.com

I have been talking with Bruce Momjian about implementing query
timeouts in the JDBC driver. As things stand, you can call
setQueryTimeout() or getQueryTimeout(), but a slow query will never
actually timeout, even if a timeout is set. The result of a timeout
should be a SQLException.

Bruce feels that this should be implemented in the backend: set an
alarm() in the backend on transaction start, then call the query
cancel() code if the alarm() goes off, and reset the alam if the query
finishes before the timeout.

I am concerned that this method does not provide a means of triggering
the SQLException in the driver. For an example, look at how cancel is
implemented (org.postgresql.Connection::cancelQuery()): we create a
new PG_Stream and send some integers to it which represent the cancel
request. Then we close the PG_Stream. There is no point at which we
receive any notification from the backend that the query has been
cancelled.

I looked in postmaster.c, processCancelRequest() to see what the
backend does. A SIGINT is sent to the backend when the cancel request
is successfully fulfilled, but nothing seems to be sent to the
interface.

One possibility is that the driver might just notice that the connection
has closed, and throw an Exception then. javax.sql.PooledConnection has an
addConnectionEventListener() method; we could add a
ConnectionEventListener there which would throw an Exception when the
connection closes.

In practice, this may or may not be a good idea. The place to get hold
of a PooledConnection seems to be in XAConnectionImpl (I am not sure
how the driver would actually request the relevant XAConnectionImpl
object, but I am sure I could figure that out). The thing is that this
class only allows one ConnectionEventListener to be set, so if we set
it, the user would be out of luck if he wanted to add his own
listener.

My proposal, then, is that the Java driver should submit the
transaction request; wait for the timeout; if it goes off, submit a
cancel request; and then throw a SQLException. We would not handle
this in the backend at all.

Bruce agreed that this was a good point to ask what the rest of the
hackers list thought. Any input?

Thanks,
Jessica

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jessica Perry Hekman (#1)
Re: timeout implementation issues

Jessica Perry Hekman <jphekman@dynamicdiagrams.com> writes:

[snip]
My proposal, then, is that the Java driver should submit the
transaction request; wait for the timeout; if it goes off, submit a
cancel request; and then throw a SQLException. We would not handle
this in the backend at all.

Bruce agreed that this was a good point to ask what the rest of the
hackers list thought. Any input?

I guess the $64 question is whether any frontends other than JDBC want
this behavior. If it's JDBC-only then I'd certainly vote for making
JDBC handle it ... but as soon as we see several different frontends
implementing similar behavior, I'd say it makes sense to implement it
once in the backend.

So, what's the market?

regards, tom lane

#3Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Tom Lane (#2)
Re: timeout implementation issues

Tom Lane wrote:

Jessica Perry Hekman <jphekman@dynamicdiagrams.com> writes:

[snip]
My proposal, then, is that the Java driver should submit the
transaction request; wait for the timeout; if it goes off, submit a
cancel request; and then throw a SQLException. We would not handle
this in the backend at all.

Bruce agreed that this was a good point to ask what the rest of the
hackers list thought. Any input?

I guess the $64 question is whether any frontends other than JDBC want
this behavior. If it's JDBC-only then I'd certainly vote for making
JDBC handle it ... but as soon as we see several different frontends
implementing similar behavior, I'd say it makes sense to implement it
once in the backend.

So, what's the market?

There is clearly interest from all interfaces. This item has been
requested quite often, usually related to client apps or web apps.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#4Jessica Perry Hekman
jphekman@dynamicdiagrams.com
In reply to: Bruce Momjian (#3)
Re: timeout implementation issues

On Sat, 30 Mar 2002, Bruce Momjian wrote:

There is clearly interest from all interfaces. This item has been
requested quite often, usually related to client apps or web apps.

I definitely agree that implementing it in the backend would be the best
plan, if it's feasible. I just can't figure out how to pass information
back to the driver that the request has been cancelled (and that, in
JDBC's case, a SQLException should be thrown). Any thoughts about that?

j

#5Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jessica Perry Hekman (#4)
Re: timeout implementation issues

Jessica Perry Hekman <jphekman@dynamicdiagrams.com> writes:

I definitely agree that implementing it in the backend would be the best
plan, if it's feasible. I just can't figure out how to pass information
back to the driver that the request has been cancelled (and that, in
JDBC's case, a SQLException should be thrown). Any thoughts about that?

Why would this be any different from a cancel-signal-instigated abort?
You'd be reporting elog(ERROR) in any case.

regards, tom lane

#6Jessica Perry Hekman
jphekman@dynamicdiagrams.com
In reply to: Tom Lane (#5)
Re: timeout implementation issues

On Sat, 30 Mar 2002, Tom Lane wrote:

Why would this be any different from a cancel-signal-instigated abort?
You'd be reporting elog(ERROR) in any case.

If I understand the code correctly, in the case of a cancel signal, the
driver sends the signal and then assumes that the backend has accepted it
and cancelled; the back end does not report back. In this case, the driver
would not be sending a signal, so it would not know that the process had
reached the timeout and stopped (and it needs to know that). What we
*could* do is have *both* the driver and the backend run timers and both
stop when the timeout is reached. This seems like a solution just begging
to produce ugly bugs, though -- and if we have to implement such a wait in
the driver, we may as well implement the whole thing in the driver and
just have it send a cancel signal when it times out.

Or am I misunderstanding the situation?

j

#7Jessica Perry Hekman
jphekman@dynamicdiagrams.com
In reply to: Jessica Perry Hekman (#6)
Re: timeout implementation issues

On Sat, 30 Mar 2002, Tom Lane wrote:

Au contraire, it is not assuming anything. It is sending off a cancel
request and then waiting to see what happens. Maybe the query will be
canceled, or maybe it will complete normally, or maybe it will fail
because of some error unrelated to the cancel request. In any case the
backend *will* eventually report completion/error status, and the
frontend does not assume anything until it gets that report.

Ah, okay; this was not my understanding. I'll look at the code again.

Why does it need to know that? When it gets the error report back, it
can notice that the error says "Query aborted by timeout" (or however we
phrase it) ... but I'm not seeing why it should care.

I just meant it needed to know that the process had stopped prematurely; I
didn't mean it needed to know why.

I'll get back to you after doing a little more research.

j

#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jessica Perry Hekman (#6)
Re: timeout implementation issues

Jessica Perry Hekman <jphekman@dynamicdiagrams.com> writes:

If I understand the code correctly, in the case of a cancel signal, the
driver sends the signal and then assumes that the backend has accepted it
and cancelled; the back end does not report back.

Au contraire, it is not assuming anything. It is sending off a cancel
request and then waiting to see what happens. Maybe the query will be
canceled, or maybe it will complete normally, or maybe it will fail
because of some error unrelated to the cancel request. In any case the
backend *will* eventually report completion/error status, and the
frontend does not assume anything until it gets that report.

In this case, the driver
would not be sending a signal, so it would not know that the process had
reached the timeout and stopped (and it needs to know that).

Why does it need to know that? When it gets the error report back, it
can notice that the error says "Query aborted by timeout" (or however we
phrase it) ... but I'm not seeing why it should care.

regards, tom lane

#9Jessica Perry Hekman
jphekman@dynamicdiagrams.com
In reply to: Jessica Perry Hekman (#7)
Re: timeout implementation issues

On Sat, 30 Mar 2002, Tom Lane wrote:

Au contraire, it is not assuming anything. It is sending off a cancel
request and then waiting to see what happens. Maybe the query will be

Okay, I see now: when processCancelRequest() is called, a return of 127 is
sent. That would indeed work; thanks for walking me through it.

My other question was how to send the timeout value to the backend. Bruce
said at one point:

Timeout can be part of BEGIN, or a SET value, which would work from
jdbc.

I'm not sure how this would work. The timeout value would be sent as part
of a SQL query?

j

#10Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Jessica Perry Hekman (#9)
Re: timeout implementation issues

Jessica Perry Hekman wrote:

On Sat, 30 Mar 2002, Tom Lane wrote:

Au contraire, it is not assuming anything. It is sending off a cancel
request and then waiting to see what happens. Maybe the query will be

Okay, I see now: when processCancelRequest() is called, a return of 127 is
sent. That would indeed work; thanks for walking me through it.

My other question was how to send the timeout value to the backend. Bruce
said at one point:

Timeout can be part of BEGIN, or a SET value, which would work from
jdbc.

I'm not sure how this would work. The timeout value would be sent as part
of a SQL query?

I think there are two ways of making this capability visible to users.
First, you could do:

SET query_timeout = 5;

and all queries after that would time out at 5 seconds. Another option
is:

BEGIN WORK TIMEOUT 5;
...
COMMIT;

which would make the transaction timeout after 5 seconds. We never
decided which one we wanted, or both.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#11Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jessica Perry Hekman (#9)
Re: timeout implementation issues

Jessica Perry Hekman <jphekman@dynamicdiagrams.com> writes:

My other question was how to send the timeout value to the backend.

I would imagine that the most convenient way to handle it would be as
a SET variable:

SET query_timeout = n;

Establishes a time limit on subsequent queries (n expressed in
milliseconds, perhaps).

SET query_timeout = 0;

Disables query time limit.

This assumes that the query timeout should apply to each subsequent
query, individually, until explicitly canceled. If you want a timeout
that applies to only one query and is then forgotten, then maybe this
wouldn't be the most convenient definition. What semantics are you
trying to obtain, exactly?

regards, tom lane

#12Jessica Perry Hekman
jphekman@dynamicdiagrams.com
In reply to: Tom Lane (#11)
Re: timeout implementation issues

On Mon, 1 Apr 2002, Tom Lane wrote:

This assumes that the query timeout should apply to each subsequent
query, individually, until explicitly canceled. If you want a timeout
that applies to only one query and is then forgotten, then maybe this
wouldn't be the most convenient definition. What semantics are you
trying to obtain, exactly?

The semantices of the JDBC API:

"Transaction::setQueryTimeout(): Sets the number of seconds the driver
will wait for a Statement to execute to the given number of seconds.
If the limit is exceeded, a SQLException is thrown."

So it should apply to all queries on a given transaction. I think that the
above implemenation suggestion (and Bruce's) would apply to all queries,
regardless of which transaction they were associated with. If each
transaction has some kind of unique ID, maybe that could be added to the
SET statement?

Does anyone know how someone else did this (mSQL, mySQL, etc)? It seems
like there ought to already exist some sort of standard. I'll poke around
and see if I can find anything.

j

#13Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Jessica Perry Hekman (#12)
Re: timeout implementation issues

Peter Eisentraut wrote:

Bruce Momjian writes:

I think there are two ways of making this capability visible to users.
First, you could do:

SET query_timeout = 5;

and all queries after that would time out at 5 seconds. Another option
is:

BEGIN WORK TIMEOUT 5;
...
COMMIT;

which would make the transaction timeout after 5 seconds. We never
decided which one we wanted, or both.

Note that the first is a statement-level timeout and the second is a
transaction-level timeout. Be sure to clarify which one we want.

Oh, wow, that is an interesting distinction. If there is a multi-query
transaction, do we time each query separately or the entire transaction?
I don't know which people want, and maybe this is why we need both GUC
and BEGIN WORK timeouts. I don't remember this distinction in previous
discussions but it may be significant. Of course, the GUC could behave
at a transaction level as well. It will be tricky to manage multiple
alarms in a single process, but it can be done by creating an alarm
queue.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#14Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#13)
Re: timeout implementation issues

Bruce Momjian <pgman@candle.pha.pa.us> writes:

... It will be tricky to manage multiple
alarms in a single process, but it can be done by creating an alarm
queue.

I would argue that we should only support *one* kind of timeout, either
transaction-level or statement-level, so as to avoid that complexity.
I don't want to see us gilding the lily in the first implementation of
something that IMHO is of dubious usefulness in the first place.
We can think about extending the facility later, when and if it proves
sufficiently useful to justify more complexity.

I don't have a very strong feeling about whether transaction-level or
statement-level is more useful; am willing to do whichever one the
JDBC spec wants.

regards, tom lane

#15Jessica Perry Hekman
jphekman@dynamicdiagrams.com
In reply to: Bruce Momjian (#13)
Re: timeout implementation issues

On Mon, 1 Apr 2002, Bruce Momjian wrote:

I don't know which people want, and maybe this is why we need both GUC
and BEGIN WORK timeouts. I don't remember this distinction in previous
discussions but it may be significant. Of course, the GUC could behave
at a transaction level as well. It will be tricky to manage multiple
alarms in a single process, but it can be done by creating an alarm
queue.

I think we should do just BEGIN WORK (transaction-level) timeouts; that is
all that the JDBC spec asks for. Does that sound good to people?

So the work that would need to be done is asking the driver to request the
timeout via "BEGIN WORK TIMEOUT 5"; getting the backend to parse that
request and set the alarm on each query in that transaction; getting the
backend to send a cancel request if the alarm goes off. I am right now in
the process of finding the place where BEGIN-level queries are parsed. Any
pointers to the right files to read would be appreciated.

j

#16Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Tom Lane (#14)
Re: timeout implementation issues

Tom Lane wrote:

Bruce Momjian <pgman@candle.pha.pa.us> writes:

... It will be tricky to manage multiple
alarms in a single process, but it can be done by creating an alarm
queue.

I would argue that we should only support *one* kind of timeout, either
transaction-level or statement-level, so as to avoid that complexity.
I don't want to see us gilding the lily in the first implementation of
something that IMHO is of dubious usefulness in the first place.
We can think about extending the facility later, when and if it proves
sufficiently useful to justify more complexity.

I don't have a very strong feeling about whether transaction-level or
statement-level is more useful; am willing to do whichever one the
JDBC spec wants.

Agreed, only one timeout. I just considered the statement/transaction
level quite interesting. We could easily do GUC for query level, and
allow BEGIN WORK to override that for transaction level. That would
give us the best of both worlds, if we want it. I am not sure what
people are going to use this timeout for. My guess is that only
transaction level is the way to go.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#17Jan Wieck
janwieck@yahoo.com
In reply to: Tom Lane (#11)
Re: timeout implementation issues

Tom Lane wrote:

Jessica Perry Hekman <jphekman@dynamicdiagrams.com> writes:

My other question was how to send the timeout value to the backend.

I would imagine that the most convenient way to handle it would be as
a SET variable:

SET query_timeout = n;

Establishes a time limit on subsequent queries (n expressed in
milliseconds, perhaps).

SET query_timeout = 0;

Disables query time limit.

This assumes that the query timeout should apply to each subsequent
query, individually, until explicitly canceled. If you want a timeout
that applies to only one query and is then forgotten, then maybe this
wouldn't be the most convenient definition. What semantics are you
trying to obtain, exactly?

Why don't we use two separate GUC variables and leave the
BEGIN syntax as is completely?

SET transaction_timeout = m;
SET statement_timeout = n;

The alarm is set to the smaller of (what's left for) the
transaction or statement.

If you want to go sub-second, I suggest making it
microseconds. That's what struct timeval (used in struct
itimerval) uses. But I strongly suggest not doing so at all,
because the usage of itimers disables the ability to profile
with gprof completely. Compute the time spent so far in a
transaction exactly, but round UP to full seconds for the
alarm allways.

And before someone asks, no, I don't think that a
connection_timeout is a good thing.

Jan

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me. #
#================================================== JanWieck@Yahoo.com #

_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com

#18Barry Lind
barry@xythos.com
In reply to: Jessica Perry Hekman (#15)
Re: timeout implementation issues

Jessica,

My reading of the JDBC spec would indicate that this is a statement
level property (aka query level) since the method to enable this is on
the Statement object and is named setQueryTimeout(). There is nothing I
can find that would indicate that this would apply to the transaction in
my reading of the jdbc spec.

thanks,
--Barry

Jessica Perry Hekman wrote:

Show quoted text

On Mon, 1 Apr 2002, Bruce Momjian wrote:

I don't know which people want, and maybe this is why we need both GUC
and BEGIN WORK timeouts. I don't remember this distinction in previous
discussions but it may be significant. Of course, the GUC could behave
at a transaction level as well. It will be tricky to manage multiple
alarms in a single process, but it can be done by creating an alarm
queue.

I think we should do just BEGIN WORK (transaction-level) timeouts; that is
all that the JDBC spec asks for. Does that sound good to people?

So the work that would need to be done is asking the driver to request the
timeout via "BEGIN WORK TIMEOUT 5"; getting the backend to parse that
request and set the alarm on each query in that transaction; getting the
backend to send a cancel request if the alarm goes off. I am right now in
the process of finding the place where BEGIN-level queries are parsed. Any
pointers to the right files to read would be appreciated.

j

---------------------------(end of broadcast)---------------------------
TIP 2: you can get off all lists at once with the unregister command
(send "unregister YourEmailAddressHere" to majordomo@postgresql.org)

#19Jessica Perry Hekman
jphekman@dynamicdiagrams.com
In reply to: Jan Wieck (#17)
Re: timeout implementation issues

On Mon, 1 Apr 2002, Jan Wieck wrote:

Why don't we use two separate GUC variables and leave the
BEGIN syntax as is completely?

SET transaction_timeout = m;
SET statement_timeout = n;

What's a GUC variable? Would this apply to all subsequent statements? I
think it needs to apply to just the specified statement.

I'm sorry about the confusion earlier when I said that
setQueryTimeout() was transaction-level; Barry Lind correctly pointed out
that it is statement-level. We mostly seem to feel that we don't want to
do both, so is statement-only okay? Jan, do you feel strongly that you
want to see both implemented?

If you want to go sub-second, I suggest making it
microseconds. That's what struct timeval (used in struct

I don't think that's necessary. JDBC only wants it specified in seconds.

j

#20Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jessica Perry Hekman (#19)
Re: timeout implementation issues

Jessica Perry Hekman <jphekman@dynamicdiagrams.com> writes:

What's a GUC variable?

A parameter that you can set with SET.

Would this apply to all subsequent statements? I
think it needs to apply to just the specified statement.

Yes, if the JDBC spec expects this to be applied to just a single
statement, then a SET variable doesn't fit very nicely with that.
You'd have to have logic on the application side to reset the variable
to "no limit" after the statement --- and this could be rather
difficult. (For example, if you are inside a transaction block and
the statement errors out, you won't be able to simply issue a new SET;
so you'd have to remember that you needed a SET until after you exit
the transaction block. Ugh.)

On the other hand, we do not have anything in the backend now that
applies to just one statement and then automatically resets afterwards;
and I'm not eager to add a parameter with that behavior just for JDBC's
convenience. It seems like it'd be a big wart.

regards, tom lane

#21Peter Eisentraut
peter_e@gmx.net
In reply to: Barry Lind (#18)
Re: timeout implementation issues

Barry Lind writes:

My reading of the JDBC spec would indicate that this is a statement
level property (aka query level) since the method to enable this is on
the Statement object and is named setQueryTimeout(). There is nothing I
can find that would indicate that this would apply to the transaction in
my reading of the jdbc spec.

Does it time out only queries or any kind of statement?

--
Peter Eisentraut peter_e@gmx.net

#22Jessica Perry Hekman
jphekman@dynamicdiagrams.com
In reply to: Peter Eisentraut (#21)
Re: timeout implementation issues

On Mon, 1 Apr 2002, Peter Eisentraut wrote:

Does it time out only queries or any kind of statement?

Any kind, I believe.

FWIW, I took a look at the recommended JDBC driver for MySQL, hoping for
ideas; it does not implement query timeouts at all. I'll take a look at
mSQL next.

j

#23Barry Lind
barry@xythos.com
In reply to: Peter Eisentraut (#21)
Re: timeout implementation issues

The spec isn't clear on that point, but my interpretation is that it
would apply to all types of statements not just queries.

--Barry

Peter Eisentraut wrote:

Show quoted text

Barry Lind writes:

My reading of the JDBC spec would indicate that this is a statement
level property (aka query level) since the method to enable this is on
the Statement object and is named setQueryTimeout(). There is nothing I
can find that would indicate that this would apply to the transaction in
my reading of the jdbc spec.

Does it time out only queries or any kind of statement?

#24Robert Schrem
robert.schrem@WiredMinds.de
In reply to: Bruce Momjian (#16)
Re: timeout implementation issues, lock timeouts

On Monday 01 April 2002 20:18, Bruce Momjian wrote:

Tom Lane wrote:>
Agreed, only one timeout.
...

We have (at least) two ortogonal reasons why we want
to abort a long running transaction:

- The long running transaction might compute a result
we are not interesed anymore (because it just takes
too long to wait for the result). We do NOT always
know in advance how patient we will be to wait for
the result. Therefore I think the client should tell
the server, when his client (user?) got impatinet
and aborted the whole transaction...

- The long running transaction might hold exclusive locks
and therefore decreases (or even nullifies) the overall
concurrency. We want to be able to disallow this by design.

I think a nice timout criteria would be a maximum lock time
for all resources aquired exclusivly within a transaction.
This would then affect transaction timeouts as well as statement
timeouts with the advantage, the get concurrency guaratees.

Robert

#25Zeugswetter Andreas SB SD
ZeugswetterA@spardat.at
In reply to: Barry Lind (#23)
Re: timeout implementation issues

So the work that would need to be done is asking the driver to request the
timeout via "BEGIN WORK TIMEOUT 5"; getting the backend to parse that
request and set the alarm on each query in that transaction; getting the

Well imho that interpretation would be completely unobvious.
My first guess would have been, that with this syntax the whole transaction
must commit or rollback within 5 seconds.

Thus I think we only need statement_timeout. ODBC, same as JDBC wants it at the
statement handle level. ODBC also provides for a default that applies to all
statement handles of this connection (They call the statement attr QUERY_TIMEOUT,
so imho there is room for interpretation whether it applies to selects only, which
I would find absurd).

Andreas

#26Jessica Perry Hekman
jphekman@dynamicdiagrams.com
In reply to: Tom Lane (#20)
Re: timeout implementation issues

On Mon, 1 Apr 2002, Tom Lane wrote:

On the other hand, we do not have anything in the backend now that
applies to just one statement and then automatically resets afterwards;
and I'm not eager to add a parameter with that behavior just for JDBC's
convenience. It seems like it'd be a big wart.

Does that leave us with implementing query timeouts in JDBC (timer in the
driver; then the driver sends a cancel request to the backend)?

j

#27Barry Lind
barry@xythos.com
In reply to: Jessica Perry Hekman (#26)
Re: timeout implementation issues

Since both the JDBC and ODBC specs have essentially the same symantics
for this, I would hope this is done in the backend instead of both
interfaces.

--Barry

Jessica Perry Hekman wrote:

Show quoted text

On Mon, 1 Apr 2002, Tom Lane wrote:

On the other hand, we do not have anything in the backend now that
applies to just one statement and then automatically resets afterwards;
and I'm not eager to add a parameter with that behavior just for JDBC's
convenience. It seems like it'd be a big wart.

Does that leave us with implementing query timeouts in JDBC (timer in the
driver; then the driver sends a cancel request to the backend)?

j

---------------------------(end of broadcast)---------------------------
TIP 2: you can get off all lists at once with the unregister command
(send "unregister YourEmailAddressHere" to majordomo@postgresql.org)

#28Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Jessica Perry Hekman (#26)
Re: timeout implementation issues

Jessica Perry Hekman wrote:

On Mon, 1 Apr 2002, Tom Lane wrote:

On the other hand, we do not have anything in the backend now that
applies to just one statement and then automatically resets afterwards;
and I'm not eager to add a parameter with that behavior just for JDBC's
convenience. It seems like it'd be a big wart.

Does that leave us with implementing query timeouts in JDBC (timer in the
driver; then the driver sends a cancel request to the backend)?

No, I think we have to find a way to do this in the backend; just not
sure how yet.

I see the problem Tom is pointing out, that SET is ignored if the
transaction has already aborted:

test=> begin;
BEGIN
test=> lkjasdf;
ERROR: parser: parse error at or near "lkjasdf"
test=> set server_min_messages = 'log';
WARNING: current transaction is aborted, queries ignored until end of
transaction block
*ABORT STATE*
test=>

so if the transaction aborted, the reset of the statement_timeout would
not happen. The only way the application could code this would be with
this:

BEGIN WORK;
query;
SET statement_timeout = 4;
query;
SET statement_timeout = 0;
query;
COMMIT;
SET statement_timeout = 0;

Basically, it does the reset twice, once assuming the transaction
doesn't abort, and another assuming it does abort. Is this something
that the JDBC and ODBC drivers can do automatically?

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#29Jessica Perry Hekman
jphekman@dynamicdiagrams.com
In reply to: Bruce Momjian (#28)
Re: timeout implementation issues

On Tue, 2 Apr 2002, Bruce Momjian wrote:

BEGIN WORK;
query;
SET statement_timeout = 4;
query;
SET statement_timeout = 0;
query;
COMMIT;
SET statement_timeout = 0;

Basically, it does the reset twice, once assuming the transaction
doesn't abort, and another assuming it does abort. Is this something
that the JDBC and ODBC drivers can do automatically?

I can't speak for ODBC. Seems like in JDBC, Connection::commit() would
call code clearing the timeout, and Statement::executeQuery() and
executeUpdate() would do the same.

j

#30Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Jessica Perry Hekman (#29)
Re: timeout implementation issues

Jessica Perry Hekman wrote:

On Tue, 2 Apr 2002, Bruce Momjian wrote:

BEGIN WORK;
query;
SET statement_timeout = 4;
query;
SET statement_timeout = 0;
query;
COMMIT;
SET statement_timeout = 0;

Basically, it does the reset twice, once assuming the transaction
doesn't abort, and another assuming it does abort. Is this something
that the JDBC and ODBC drivers can do automatically?

I can't speak for ODBC. Seems like in JDBC, Connection::commit() would
call code clearing the timeout, and Statement::executeQuery() and
executeUpdate() would do the same.

Well, then a SET variable would work fine for statement-level queries.
Just add the part for commit/abort transaction.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#31Jessica Perry Hekman
jphekman@dynamicdiagrams.com
In reply to: Barry Lind (#27)
Re: timeout implementation issues

On Tue, 2 Apr 2002, Barry Lind wrote:

Since both the JDBC and ODBC specs have essentially the same symantics
for this, I would hope this is done in the backend instead of both
interfaces.

The current plan seems to be to make changes in the backend and the JDBC
interface, the bulk of the implementation being in the backend.

j

#32Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Jessica Perry Hekman (#31)
Re: timeout implementation issues

Jessica Perry Hekman wrote:

On Tue, 2 Apr 2002, Barry Lind wrote:

Since both the JDBC and ODBC specs have essentially the same symantics
for this, I would hope this is done in the backend instead of both
interfaces.

The current plan seems to be to make changes in the backend and the JDBC
interface, the bulk of the implementation being in the backend.

Yes, ODBC and JDBC need this, and I am sure psql folks will use it too,
not counting libpq and all the others.

We just need a way to specify statement-level SET options inside a
transaction where the statement may fail and ignore the SET command that
resets the timeout. We don't have any mechanism to reset the timeout
parameter at the end of a transaction automatically, which would solve
our problem with failed transactions.

Does anyone know the ramifications of allowing SET to work in an aborted
transaction? It is my understanding that SET doesn't really have
transaction semantics anyway, e.g. a SET that is done in a transaction
that is later aborted is still valid:

test=> BEGIN;
BEGIN
test=> SET server_min_messages to 'debug5';
SET VARIABLE
test=> ABORT;
ROLLBACK
test=> SHOW server_min_messages;
INFO: server_min_messages is debug5
SHOW VARIABLE

Having shown this, it could be argued that SET should work in an
already-aborted transaction. Why should having the SET before or after
the transaction is canceled have any effect. This illustrates it a
little clearer:

test=> BEGIN;
BEGIN
test=> SET server_min_messages to 'debug3';
SET VARIABLE
test=> asdf;
ERROR: parser: parse error at or near "asdf"
test=> SET server_min_messages to 'debug1';
WARNING: current transaction is aborted, queries ignored until end of
transaction block
*ABORT STATE*
test=> COMMIT;
COMMIT
test=> SHOW server_min_messages;
INFO: server_min_messages is debug3
SHOW VARIABLE
test=>

Why should the 'debug3' be honored if the transaction aborted. And if
it is OK that is was honored, is it OK that the 'debug1' was not
honored?

Allowing SET to be valid after a transaction aborts would solve our SET
timeout problem.

There is also a feeling that people may want to set maximum counts for
transactions too because the transaction could be holding locks you want
released.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#33Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#32)
Re: timeout implementation issues

Bruce Momjian <pgman@candle.pha.pa.us> writes:

Does anyone know the ramifications of allowing SET to work in an aborted
transaction?

This is not an option.

The case that will definitely Not Work is SET variables whose setting
or checking requires database accesses. The new search_path variable
certainly works that way; not sure if there are any other cases at the
moment, but I'd not like to say that there can never be any such
variables.

regards, tom lane

#34Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#32)
Re: timeout implementation issues

Bruce Momjian wrote:

Jessica Perry Hekman wrote:

On Tue, 2 Apr 2002, Barry Lind wrote:

Since both the JDBC and ODBC specs have essentially the same symantics
for this, I would hope this is done in the backend instead of both
interfaces.

The current plan seems to be to make changes in the backend and the JDBC
interface, the bulk of the implementation being in the backend.

Yes, ODBC and JDBC need this, and I am sure psql folks will use it too,
not counting libpq and all the others.

I wasn't able to follow this thread sorry.
ODBC has QUERY_TIMEOUT and CONNECTION_TIMEOUT.

We just need a way to specify statement-level SET options inside a
transaction where the statement may fail and ignore the SET command that
resets the timeout. We don't have any mechanism to reset the timeout
parameter at the end of a transaction automatically,

Why should the timeout be reset automatically ?

regards,
Hiroshi Inoue

#35Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Hiroshi Inoue (#34)
1 attachment(s)
Re: timeout implementation issues

The current plan seems to be to make changes in the backend and the JDBC
interface, the bulk of the implementation being in the backend.

Yes, ODBC and JDBC need this, and I am sure psql folks will use it too,
not counting libpq and all the others.

I wasn't able to follow this thread sorry.
ODBC has QUERY_TIMEOUT and CONNECTION_TIMEOUT.

We just need a way to specify statement-level SET options inside a
transaction where the statement may fail and ignore the SET command that
resets the timeout. We don't have any mechanism to reset the timeout
parameter at the end of a transaction automatically,

Why should the timeout be reset automatically ?

It doesn't need to be reset automatically, but the problem is that if
you are doing a timeout for single statement in a transaction, and that
statement aborts the transaction, the SET command after it to reset the
timeout fails.

I am attaching the email that describes the issue.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026

Attachments:

/bjm/4text/plainDownload
#36Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#35)
Re: timeout implementation issues

Bruce Momjian wrote:

The current plan seems to be to make changes in the backend and the JDBC
interface, the bulk of the implementation being in the backend.

Yes, ODBC and JDBC need this, and I am sure psql folks will use it too,
not counting libpq and all the others.

I wasn't able to follow this thread sorry.
ODBC has QUERY_TIMEOUT and CONNECTION_TIMEOUT.

We just need a way to specify statement-level SET options inside a
transaction where the statement may fail and ignore the SET command that
resets the timeout. We don't have any mechanism to reset the timeout
parameter at the end of a transaction automatically,

Why should the timeout be reset automatically ?

It doesn't need to be reset automatically, but the problem is that if
you are doing a timeout for single statement in a transaction, and that
statement aborts the transaction, the SET command after it to reset the
timeout fails.

As for ODBC, there's no state that *abort* but still inside
a transaction currently.

regards,
Hiroshi Inoue

#37Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Hiroshi Inoue (#36)
Re: timeout implementation issues

Hiroshi Inoue wrote:

Why should the timeout be reset automatically ?

It doesn't need to be reset automatically, but the problem is that if
you are doing a timeout for single statement in a transaction, and that
statement aborts the transaction, the SET command after it to reset the
timeout fails.

As for ODBC, there's no state that *abort* but still inside
a transaction currently.

Yes, the strange thing is that SET inside a transaction _after_ the
transaction aborts is ignored, while SET before inside a transaction
before the transaction aborts is accepted.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#38Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#37)
Re: timeout implementation issues

Bruce Momjian wrote:

Hiroshi Inoue wrote:

Why should the timeout be reset automatically ?

It doesn't need to be reset automatically, but the problem is that if
you are doing a timeout for single statement in a transaction, and that
statement aborts the transaction, the SET command after it to reset the
timeout fails.

As for ODBC, there's no state that *abort* but still inside
a transaction currently.

Yes, the strange thing is that SET inside a transaction _after_ the
transaction aborts is ignored, while SET before inside a transaction
before the transaction aborts is accepted.

What I meant is there's no such problem with psqlodbc
at least currently because the driver issues ROLLBACK
automatically on abort inside a transaction.

regards,
Hiroshi Inoue

#39Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Hiroshi Inoue (#38)
Re: timeout implementation issues

Hiroshi Inoue wrote:

Bruce Momjian wrote:

Hiroshi Inoue wrote:

Why should the timeout be reset automatically ?

It doesn't need to be reset automatically, but the problem is that if
you are doing a timeout for single statement in a transaction, and that
statement aborts the transaction, the SET command after it to reset the
timeout fails.

As for ODBC, there's no state that *abort* but still inside
a transaction currently.

Yes, the strange thing is that SET inside a transaction _after_ the
transaction aborts is ignored, while SET before inside a transaction
before the transaction aborts is accepted.

What I meant is there's no such problem with psqlodbc
at least currently because the driver issues ROLLBACK
automatically on abort inside a transaction.

If it does that, what happens with the rest of the queries in a
transaction? Do they get executed in their own transactions, or are
they somehow ignored.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#40Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#39)
Re: timeout implementation issues

Bruce Momjian wrote:

Hiroshi Inoue wrote:

Bruce Momjian wrote:

Hiroshi Inoue wrote:

Why should the timeout be reset automatically ?

It doesn't need to be reset automatically, but the problem is that if
you are doing a timeout for single statement in a transaction, and that
statement aborts the transaction, the SET command after it to reset the
timeout fails.

As for ODBC, there's no state that *abort* but still inside
a transaction currently.

Yes, the strange thing is that SET inside a transaction _after_ the
transaction aborts is ignored, while SET before inside a transaction
before the transaction aborts is accepted.

What I meant is there's no such problem with psqlodbc
at least currently because the driver issues ROLLBACK
automatically on abort inside a transaction.

If it does that, what happens with the rest of the queries in a
transaction? Do they get executed in their own transactions, or are
they somehow ignored.

They would be executed in a new transaction. Queries shouldn't
be issued blindly(without error checking).

regards,
Hiroshi Inoue

#41Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Bruce Momjian (#32)
Re: timeout implementation issues

OK, I have a few ideas on this and I think one of them will have to be
implemented. Basically, we have this SET problem with all our
variables, e.g. if you SET explain_pretty_print or enable_seqscan in a
multi-statement transaction, and the transaction aborts after the
variable is turned on but before the variable is turned off, it will
remain on for the remainder of the session. See the attached email for
an example. It shows this problem with timeout, but all the SET
variables have this issue.

I think we have only a few options:

o Allow SET to execute even if the transaction is in ABORT
state (Tom says some SET variables need db access and will
fail.)
o If a SET is performed while in transaction ABORT state, queue
up the SET commands to run after the transaction completes
o Issue a RESET on transaction completion (commit or abort) for any
SET variable set in the transaction. (This will cause problems
for API's like ecpg which are always in a transaction.)
o Issue a variable RESET on transaction ABORT for any SET variable
modified by a transaction.

I think the last one is the most reasonable option.

---------------------------------------------------------------------------

Bruce Momjian wrote:

Jessica Perry Hekman wrote:

On Tue, 2 Apr 2002, Barry Lind wrote:

Since both the JDBC and ODBC specs have essentially the same symantics
for this, I would hope this is done in the backend instead of both
interfaces.

The current plan seems to be to make changes in the backend and the JDBC
interface, the bulk of the implementation being in the backend.

Yes, ODBC and JDBC need this, and I am sure psql folks will use it too,
not counting libpq and all the others.

We just need a way to specify statement-level SET options inside a
transaction where the statement may fail and ignore the SET command that
resets the timeout. We don't have any mechanism to reset the timeout
parameter at the end of a transaction automatically, which would solve
our problem with failed transactions.

Does anyone know the ramifications of allowing SET to work in an aborted
transaction? It is my understanding that SET doesn't really have
transaction semantics anyway, e.g. a SET that is done in a transaction
that is later aborted is still valid:

test=> BEGIN;
BEGIN
test=> SET server_min_messages to 'debug5';
SET VARIABLE
test=> ABORT;
ROLLBACK
test=> SHOW server_min_messages;
INFO: server_min_messages is debug5
SHOW VARIABLE

Having shown this, it could be argued that SET should work in an
already-aborted transaction. Why should having the SET before or after
the transaction is canceled have any effect. This illustrates it a
little clearer:

test=> BEGIN;
BEGIN
test=> SET server_min_messages to 'debug3';
SET VARIABLE
test=> asdf;
ERROR: parser: parse error at or near "asdf"
test=> SET server_min_messages to 'debug1';
WARNING: current transaction is aborted, queries ignored until end of
transaction block
*ABORT STATE*
test=> COMMIT;
COMMIT
test=> SHOW server_min_messages;
INFO: server_min_messages is debug3
SHOW VARIABLE
test=>

Why should the 'debug3' be honored if the transaction aborted. And if
it is OK that is was honored, is it OK that the 'debug1' was not
honored?

Allowing SET to be valid after a transaction aborts would solve our SET
timeout problem.

There is also a feeling that people may want to set maximum counts for
transactions too because the transaction could be holding locks you want
released.

-- 
Bruce Momjian                        |  http://candle.pha.pa.us
pgman@candle.pha.pa.us               |  (610) 853-3000
+  If your life is a hard drive,     |  830 Blythe Avenue
+  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026

---------------------------(end of broadcast)---------------------------
TIP 3: if posting/reading through Usenet, please send an appropriate
subscribe-nomail command to majordomo@postgresql.org so that your
message can get through to the mailing list cleanly

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#42Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#41)
Re: timeout implementation issues

Bruce Momjian <pgman@candle.pha.pa.us> writes:

I think we have only a few options:

You forgot

o Do nothing.

IMHO the current behavior is not broken, and does not need fixed.
All of the options you suggest are surely more broken than the current
behavior.

o Issue a RESET on transaction completion (commit or abort) for any
SET variable set in the transaction. (This will cause problems
for API's like ecpg which are always in a transaction.)

RESET would certainly not be a desirable behavior. If we want SET vars
to roll back on abort, then they should roll back --- ie, resume their
transaction-start-time values. But I doubt it's worth the trouble.
That behavior would do nothing to help JDBC implement timeouts, since
they'd still need to change the value again explicitly after successful
transaction completion.

regards, tom lane

#43Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Tom Lane (#42)
Re: timeout implementation issues

Tom Lane wrote:

Bruce Momjian <pgman@candle.pha.pa.us> writes:

I think we have only a few options:

You forgot

o Do nothing.

IMHO the current behavior is not broken, and does not need fixed.
All of the options you suggest are surely more broken than the current
behavior.

I think it is broken. What logic is there that SET before transaction
abort is performed, but after abort it is ignored? What if someone
wants a specific optimizer parameter for a statement in a transaction,
like geqo_* or enable_seqscan off, and they perform the SET before the
statement OK but if the statement fails, the SET after it is ignored.
That doesn't seem like very normal behavior to me.

We are seeing this in the timeout case, but in fact the other SET
commands when run in a transaction have the same problem.

o Issue a RESET on transaction completion (commit or abort) for any
SET variable set in the transaction. (This will cause problems
for API's like ecpg which are always in a transaction.)

RESET would certainly not be a desirable behavior. If we want SET vars
to roll back on abort, then they should roll back --- ie, resume their
transaction-start-time values. But I doubt it's worth the trouble.
That behavior would do nothing to help JDBC implement timeouts, since
they'd still need to change the value again explicitly after successful
transaction completion.

Yes, I now think that saving the SET commands that are ignored in a
transaction and running them _after_ the transaction completes may be
the best thing. They can be stored as C strings in a stable memory
context and just run on transaction completion.

If we don't somehow get this to work, how do we do timeouts, which we
all know we should have?

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#44Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#43)
Re: timeout implementation issues

Bruce Momjian <pgman@candle.pha.pa.us> writes:

Yes, I now think that saving the SET commands that are ignored in a
transaction and running them _after_ the transaction completes may be
the best thing.

No, that's just plain ridiculous. If you want to change the semantics
of SET, then make it work *correctly*, viz like an SQL statement: roll
it back on transaction abort. Otherwise leave it alone.

If we don't somehow get this to work, how do we do timeouts, which we
all know we should have?

This is utterly unrelated to timeouts. With or without any changes in
SET behavior, JDBC would need to issue a SET after completion of the
transaction if they wanted to revert a query_timeout variable to the
no-timeout state.

regards, tom lane

#45Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Tom Lane (#44)
Re: timeout implementation issues

Tom Lane wrote:

Bruce Momjian <pgman@candle.pha.pa.us> writes:

Yes, I now think that saving the SET commands that are ignored in a
transaction and running them _after_ the transaction completes may be
the best thing.

No, that's just plain ridiculous. If you want to change the semantics

No more ridiculous than what we have now.

of SET, then make it work *correctly*, viz like an SQL statement: roll
it back on transaction abort. Otherwise leave it alone.

I am not going to leave it alone based only on your say-so, Tom.

If we don't somehow get this to work, how do we do timeouts, which we
all know we should have?

This is utterly unrelated to timeouts. With or without any changes in
SET behavior, JDBC would need to issue a SET after completion of the
transaction if they wanted to revert a query_timeout variable to the
no-timeout state.

"Utterly unrelated?" No. If we can get SET to work properly in
transactions, jdbc can cleanly issue SET timeout=4, statement, SET
timeout=0. Without it, using SET for timeout is a problem. That's how
we got to this issue in the first place.

I am still looking for a constructive idea on how we can get this to
work, rather than calling my ideas "ridiculous".

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#46Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#45)
Re: timeout implementation issues

Bruce Momjian <pgman@candle.pha.pa.us> writes:

I am still looking for a constructive idea on how we can get this to
work, rather than calling my ideas "ridiculous".

We know very well how to make it work: JDBC can issue a SET timeout = 0
after exiting the transaction. You're proposing to change the semantics
of SET into something quite bizarre in order to allow JDBC to not have
to work as hard. I think that's a bad tradeoff.

regards, tom lane

#47Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#45)
Re: timeout implementation issues

Tom Lane wrote:

Bruce Momjian <pgman@candle.pha.pa.us> writes:

I am still looking for a constructive idea on how we can get this to
work, rather than calling my ideas "ridiculous".

We know very well how to make it work: JDBC can issue a SET timeout = 0
after exiting the transaction. You're proposing to change the semantics
of SET into something quite bizarre in order to allow JDBC to not have
to work as hard. I think that's a bad tradeoff.

Or we don't have to reset the timeout at all.
For example when we are about to issue a command, we
can check if the requested timeout is different from
the current server's timeout. We don't have to (re)set
the timeout unless they are different.

regards,
Hiroshi Inoue

#48Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Tom Lane (#46)
Re: timeout implementation issues

Tom Lane wrote:

Bruce Momjian <pgman@candle.pha.pa.us> writes:

I am still looking for a constructive idea on how we can get this to
work, rather than calling my ideas "ridiculous".

We know very well how to make it work: JDBC can issue a SET timeout = 0
after exiting the transaction. You're proposing to change the semantics
of SET into something quite bizarre in order to allow JDBC to not have
to work as hard. I think that's a bad tradeoff.

It that acceptable to the JDBC folks? It requires two "SET timeout = 0"
statements, one after the statement in the transaction, and another
after the transaction COMMIT WORK.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#49Jan Wieck
janwieck@yahoo.com
In reply to: Bruce Momjian (#45)
Re: timeout implementation issues

Bruce Momjian wrote:

Tom Lane wrote:

Bruce Momjian <pgman@candle.pha.pa.us> writes:

Yes, I now think that saving the SET commands that are ignored in a
transaction and running them _after_ the transaction completes may be
the best thing.

No, that's just plain ridiculous. If you want to change the semantics

No more ridiculous than what we have now.

of SET, then make it work *correctly*, viz like an SQL statement: roll
it back on transaction abort. Otherwise leave it alone.

I am not going to leave it alone based only on your say-so, Tom.

I have to agree with Tom here. It's not right to hack up SET
to be accepted in transaction abort state. Nor is it right to
queue up SET requests then. If those queued SET's lead to
errors, when do you report them? On ROLLBACK?

If at all, SET commands should behave like everything else.
If done inside a transaction, they have to rollback.

If we don't somehow get this to work, how do we do timeouts, which we
all know we should have?

This is utterly unrelated to timeouts. With or without any changes in
SET behavior, JDBC would need to issue a SET after completion of the
transaction if they wanted to revert a query_timeout variable to the
no-timeout state.

"Utterly unrelated?" No. If we can get SET to work properly in
transactions, jdbc can cleanly issue SET timeout=4, statement, SET
timeout=0. Without it, using SET for timeout is a problem. That's how
we got to this issue in the first place.

Could we get out of this by defining that "timeout" is
automatically reset at next statement end? So that the entire
thing is

SET timeout=4;
SELECT ...;
-- We're back in no-timeout

And that it doesn't matter if we're in a transaction, if the
statement aborts, yadda yadda...

Jan

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me. #
#================================================== JanWieck@Yahoo.com #

#50Jessica Perry Hekman
jphekman@dynamicdiagrams.com
In reply to: Bruce Momjian (#48)
Re: timeout implementation issues

On Thu, 4 Apr 2002, Bruce Momjian wrote:

It that acceptable to the JDBC folks? It requires two "SET timeout = 0"
statements, one after the statement in the transaction, and another
after the transaction COMMIT WORK.

That's fine, though probably about as much work as just implementing the
whole thing in JDBC.

j

#51Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jan Wieck (#49)
Re: timeout implementation issues

Jan Wieck <janwieck@yahoo.com> writes:

Could we get out of this by defining that "timeout" is
automatically reset at next statement end?

I was hoping to avoid that, because it seems like a wart. OTOH,
it'd be less of a wart than the global changes of semantics that
Bruce is proposing :-(

How exactly would you make this happen? The simplest way I can think of
to do it (reset timeout in outer loop in postgres.c) would not work,
because it'd reset the timeout as soon as the SET statement completes.
How would you get the setting to survive for exactly one additional
statement?

regards, tom lane

#52Ross J. Reedstrom
reedstrm@rice.edu
In reply to: Tom Lane (#51)
Re: timeout implementation issues

On Fri, Apr 05, 2002 at 11:19:04AM -0500, Tom Lane wrote:

Jan Wieck <janwieck@yahoo.com> writes:

Could we get out of this by defining that "timeout" is
automatically reset at next statement end?

I was hoping to avoid that, because it seems like a wart. OTOH,
it'd be less of a wart than the global changes of semantics that
Bruce is proposing :-(

How exactly would you make this happen? The simplest way I can think of
to do it (reset timeout in outer loop in postgres.c) would not work,
because it'd reset the timeout as soon as the SET statement completes.
How would you get the setting to survive for exactly one additional
statement?

How about not messing with the SET, but adding it to the SELECT syntax
itself? a "WITH TIMEOUT" clause?

This is the first of the (proposed) SET variables that affects query
performance that is not a 'twiddle with the internals because something
is really wrong' hack (or debugging tool, if you will) Argueably,
those also suffer from the punching through the transaction problem:
I'd certainly hate (for example) to have sequential scans disabled for
an entire connection because one gnarly query that the optimizer guesses
wrong on died, and my reset got ignored. I'd hate it, but understand
that it's a crufty hack to get around a problem, and just deal with
resetting the transaction/connection.

Timeouts, on the other hand, are a much more respectable mainline sort
of extension, apparently required for certain standards (The JDBC people
started this discussion, right?). They should be fully supported by the
transactional machinery, however that is decided. If that means all
SETs become transactional, I don't really see a problem with that.

Or, as I suggested above, extend the SELECT (and other querys?) syntax
seems reasonable. More so than the non-standard 'use this index, really'
types of extensions that other RDBMSs provide, that we've rightly avoided.

Thoughts?

Ross

#53Jan Wieck
janwieck@yahoo.com
In reply to: Tom Lane (#51)
Re: timeout implementation issues

Tom Lane wrote:

Jan Wieck <janwieck@yahoo.com> writes:

Could we get out of this by defining that "timeout" is
automatically reset at next statement end?

I was hoping to avoid that, because it seems like a wart. OTOH,
it'd be less of a wart than the global changes of semantics that
Bruce is proposing :-(

How exactly would you make this happen? The simplest way I can think of
to do it (reset timeout in outer loop in postgres.c) would not work,
because it'd reset the timeout as soon as the SET statement completes.
How would you get the setting to survive for exactly one additional
statement?

I would vote for a general callback registering mechanism,
where you can specify an event, a function and an opaque
pointer. Possible events then would be end of statement, end
of transaction, commit, abort, regular end of session.

Sure, it looks like total overkill for this minor JDBC
problem. But I like general support structures to be in
place early.

Jan

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me. #
#================================================== JanWieck@Yahoo.com #

#54Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jan Wieck (#49)
Re: timeout implementation issues

Jan Wieck <janwieck@yahoo.com> writes:

If at all, SET commands should behave like everything else.
If done inside a transaction, they have to rollback.

I have thought of a scenario that may be sufficient to justify fixing
SETs to roll back on transaction abort. Consider

BEGIN;

CREATE SCHEMA foo;

SET search_path = 'foo, public';

ROLLBACK;

As the code stands, this will leave you with an invalid search path.
(What's worse, if you now execute CREATE TABLE, it will happily create
tables belonging to the vanished namespace foo. Everything will seem
to work fine ... until you try to find those tables again in a new
session ...)

It seems clear to me that SET *should* roll back on abort. Just a
matter of how important is it to fix.

regards, tom lane

#55Jan Wieck
janwieck@yahoo.com
In reply to: Ross J. Reedstrom (#52)
Re: timeout implementation issues

Ross J. Reedstrom wrote:

On Fri, Apr 05, 2002 at 11:19:04AM -0500, Tom Lane wrote:

Jan Wieck <janwieck@yahoo.com> writes:

Could we get out of this by defining that "timeout" is
automatically reset at next statement end?

I was hoping to avoid that, because it seems like a wart. OTOH,
it'd be less of a wart than the global changes of semantics that
Bruce is proposing :-(

How exactly would you make this happen? The simplest way I can think of
to do it (reset timeout in outer loop in postgres.c) would not work,
because it'd reset the timeout as soon as the SET statement completes.
How would you get the setting to survive for exactly one additional
statement?

How about not messing with the SET, but adding it to the SELECT syntax
itself? a "WITH TIMEOUT" clause?

Only SELECT? I thought all DML-statements should honour it.

Jan

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me. #
#================================================== JanWieck@Yahoo.com #

#56Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Ross J. Reedstrom (#52)
Re: timeout implementation issues

Or, as I suggested above, extend the SELECT (and other querys?) syntax
seems reasonable. More so than the non-standard 'use this index, really'
types of extensions that other RDBMSs provide, that we've rightly avoided.

I think we need timeout for all statement.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#57Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Tom Lane (#51)
Re: timeout implementation issues

Tom Lane wrote:

Jan Wieck <janwieck@yahoo.com> writes:

Could we get out of this by defining that "timeout" is
automatically reset at next statement end?

I was hoping to avoid that, because it seems like a wart. OTOH,
it'd be less of a wart than the global changes of semantics that
Bruce is proposing :-(

How exactly would you make this happen? The simplest way I can think of
to do it (reset timeout in outer loop in postgres.c) would not work,
because it'd reset the timeout as soon as the SET statement completes.
How would you get the setting to survive for exactly one additional
statement?

Sure, you could reset it, but there are going to be cases where you want
to do a timeout=6000 for the entire session. If it resets after the
first statement, this is hard to do.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#58Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Tom Lane (#54)
Re: timeout implementation issues

Tom Lane wrote:

Jan Wieck <janwieck@yahoo.com> writes:

If at all, SET commands should behave like everything else.
If done inside a transaction, they have to rollback.

I have thought of a scenario that may be sufficient to justify fixing
SETs to roll back on transaction abort. Consider

BEGIN;

CREATE SCHEMA foo;

SET search_path = 'foo, public';

ROLLBACK;

As the code stands, this will leave you with an invalid search path.
(What's worse, if you now execute CREATE TABLE, it will happily create
tables belonging to the vanished namespace foo. Everything will seem
to work fine ... until you try to find those tables again in a new
session ...)

It seems clear to me that SET *should* roll back on abort. Just a
matter of how important is it to fix.

That was my point, that having SET work pre-abort and ignored post-abort
is broken itself, whether we implement timeout or not. Before we had
tuple-reading SET variables, it probably didn't matter, but now with
schemas, I can see it is more of an issue.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#59Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Tom Lane (#51)
Re: timeout implementation issues

-----Original Message-----
From: Tom Lane

Jan Wieck <janwieck@yahoo.com> writes:

Could we get out of this by defining that "timeout" is
automatically reset at next statement end?

I was hoping to avoid that, because it seems like a wart. OTOH,
it'd be less of a wart than the global changes of semantics that
Bruce is proposing :-(

Probably I'm misunderstanding this thread.
Why must the query_timeout be reset particularly ?
What's wrong with simply issueing set query_timeout
command just before every query ?

regards,
Hiroshi Inoue

#60Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Hiroshi Inoue (#59)
Re: timeout implementation issues

Hiroshi Inoue wrote:

-----Original Message-----
From: Tom Lane

Jan Wieck <janwieck@yahoo.com> writes:

Could we get out of this by defining that "timeout" is
automatically reset at next statement end?

I was hoping to avoid that, because it seems like a wart. OTOH,
it'd be less of a wart than the global changes of semantics that
Bruce is proposing :-(

Probably I'm misunderstanding this thread.
Why must the query_timeout be reset particularly ?
What's wrong with simply issueing set query_timeout
command just before every query ?

You could do that, but we also imagine cases where people would want to
set a timeout for each query in an entire session.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#61Jessica Perry Hekman
jphekman@dynamicdiagrams.com
In reply to: Bruce Momjian (#60)
Re: timeout implementation issues

On Sat, 6 Apr 2002, Bruce Momjian wrote:

What's wrong with simply issueing set query_timeout
command just before every query ?

You could do that, but we also imagine cases where people would want to
set a timeout for each query in an entire session.

One approach might be for the interface to take care of setting the query
timeout before each query, and just ask the backend to handle timeouts
per-query. So from the user's perspective, session-level timeouts would
exist, but the backend would not have to worry about rolling back
timeouts.

j

#62Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Jessica Perry Hekman (#61)
Re: timeout implementation issues

Jessica Perry Hekman wrote:

On Sat, 6 Apr 2002, Bruce Momjian wrote:

What's wrong with simply issueing set query_timeout
command just before every query ?

You could do that, but we also imagine cases where people would want to
set a timeout for each query in an entire session.

One approach might be for the interface to take care of setting the query
timeout before each query, and just ask the backend to handle timeouts
per-query. So from the user's perspective, session-level timeouts would
exist, but the backend would not have to worry about rolling back
timeouts.

Yes, that would work, but libpq and psql would have trouble doing full
session timeouts.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#63Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#62)
Re: timeout implementation issues

Bruce Momjian <pgman@candle.pha.pa.us> writes:

One approach might be for the interface to take care of setting the query
timeout before each query, and just ask the backend to handle timeouts
per-query. So from the user's perspective, session-level timeouts would
exist, but the backend would not have to worry about rolling back
timeouts.

Yes, that would work, but libpq and psql would have trouble doing full
session timeouts.

From the backend's perspective it'd be a *lot* cleaner to support
persistent timeouts (good 'til canceled) than one-shots. If that's
the choice then let's let the frontend library worry about implementing
one-shots.

Note: I am now pretty well convinced that we *must* fix SET to roll back
to start-of-transaction settings on transaction abort. If we do that,
at least some of the difficulty disappears for JDBC to handle one-shot
timeouts by issuing SETs before and after the target query against a
query_timeout variable that otherwise acts like a good-til-canceled
setting. Can we all compromise on that?

regards, tom lane

#64Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Tom Lane (#63)
Re: timeout implementation issues

Tom Lane wrote:

Bruce Momjian <pgman@candle.pha.pa.us> writes:

One approach might be for the interface to take care of setting the query
timeout before each query, and just ask the backend to handle timeouts
per-query. So from the user's perspective, session-level timeouts would
exist, but the backend would not have to worry about rolling back
timeouts.

Yes, that would work, but libpq and psql would have trouble doing full
session timeouts.

From the backend's perspective it'd be a *lot* cleaner to support

persistent timeouts (good 'til canceled) than one-shots. If that's
the choice then let's let the frontend library worry about implementing
one-shots.

Note: I am now pretty well convinced that we *must* fix SET to roll back
to start-of-transaction settings on transaction abort. If we do that,
at least some of the difficulty disappears for JDBC to handle one-shot
timeouts by issuing SETs before and after the target query against a
query_timeout variable that otherwise acts like a good-til-canceled
setting. Can we all compromise on that?

Added to TODO:

* Abort SET changes made in aborted transactions

We do have on_shmem_exit and on_proc_exit function call queues. Seems
we will need SET to create a queue of function calls containing previous
values of variables SEt in multi-statement transactions. If we execute
the queue in last-in-first-out order, the variables will be restored
properly.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#65Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#64)
Re: timeout implementation issues

Bruce Momjian <pgman@candle.pha.pa.us> writes:

We do have on_shmem_exit and on_proc_exit function call queues. Seems
we will need SET to create a queue of function calls containing previous
values of variables SEt in multi-statement transactions. If we execute
the queue in last-in-first-out order, the variables will be restored
properly.

That's most certainly the hard way. I was planning to just make GUC
save a spare copy of the start-of-transaction value of each variable.

regards, tom lane

#66Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Tom Lane (#65)
Re: timeout implementation issues

Tom Lane wrote:

Bruce Momjian <pgman@candle.pha.pa.us> writes:

We do have on_shmem_exit and on_proc_exit function call queues. Seems
we will need SET to create a queue of function calls containing previous
values of variables SEt in multi-statement transactions. If we execute
the queue in last-in-first-out order, the variables will be restored
properly.

That's most certainly the hard way. I was planning to just make GUC
save a spare copy of the start-of-transaction value of each variable.

Ewe, I was hoping for something with zero overhead for the non-SET case.
Can we trigger the save for the first SET in the transaction?

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#67Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#66)
Re: timeout implementation issues

Bruce Momjian <pgman@candle.pha.pa.us> writes:

Ewe, I was hoping for something with zero overhead for the non-SET case.

Well, a function call and immediate return if no SET has been executed
in the current xact seems low enough overhead to me. We'll just keep
a flag showing whether there's anything to do.

regards, tom lane

#68Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Tom Lane (#67)
Re: timeout implementation issues

Tom Lane wrote:

Bruce Momjian <pgman@candle.pha.pa.us> writes:

Ewe, I was hoping for something with zero overhead for the non-SET case.

Well, a function call and immediate return if no SET has been executed
in the current xact seems low enough overhead to me. We'll just keep
a flag showing whether there's anything to do.

Oh, I thought you were going to save all the GUC variables on
transaction start. I now assume you are going to have one field per
variable for the pre-xact value. That is fine.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#69Barry Lind
barry@xythos.com
In reply to: Bruce Momjian (#62)
Re: timeout implementation issues

Tom Lane wrote:

Note: I am now pretty well convinced that we *must* fix SET to roll back
to start-of-transaction settings on transaction abort. If we do that,
at least some of the difficulty disappears for JDBC to handle one-shot
timeouts by issuing SETs before and after the target query against a
query_timeout variable that otherwise acts like a good-til-canceled
setting. Can we all compromise on that?

This plan should work well for JDBC. (It actually makes the code on the
jdbc side pretty easy).

thanks,
--Barry

#70Peter Eisentraut
peter_e@gmx.net
In reply to: Tom Lane (#63)
Re: timeout implementation issues

Tom Lane writes:

Note: I am now pretty well convinced that we *must* fix SET to roll back
to start-of-transaction settings on transaction abort. If we do that,
at least some of the difficulty disappears for JDBC to handle one-shot
timeouts by issuing SETs before and after the target query against a
query_timeout variable that otherwise acts like a good-til-canceled
setting. Can we all compromise on that?

No.

I agree that there may be some variables that must be rolled back, or
where automatic reset on transaction end may be desirable (note that these
are two different things), but for some variables it's completely
nonsensical. Those variables describe session characteristics, not
database state. For instance, time zone, default_transaction_isolation.
Or consider you're raising the debug level, but it gets reset during
commit so you can't debug the commit process. Or in the future we may
have some SQL-compatible always-in-transaction mode which would mean that
you could never set any variable to last.

If you want something that's transaction-specific, invent a new mechanism.
Hook in the set transaction isolation level command while you're at it.
But don't break everything that's worked so far.

--
Peter Eisentraut peter_e@gmx.net

#71Tom Lane
tgl@sss.pgh.pa.us
In reply to: Peter Eisentraut (#70)
Re: timeout implementation issues

Peter Eisentraut <peter_e@gmx.net> writes:

Can we all compromise on that?

No.

Oh dear...

I agree that there may be some variables that must be rolled back, or
where automatic reset on transaction end may be desirable (note that these
are two different things), but for some variables it's completely
nonsensical. Those variables describe session characteristics, not
database state. For instance, time zone, default_transaction_isolation.

Uh, why? I do not see why it's unreasonable for
BEGIN;
SET time_zone = whatever;
ROLLBACK;
to be a no-op. The fact that we haven't done that historically doesn't
count for much (unless your argument is "backwards compatibility" ...
but you didn't say that). Not long ago we couldn't roll back a DROP
TABLE command; but that didn't make it right.

Or consider you're raising the debug level, but it gets reset during
commit so you can't debug the commit process.

It wouldn't get reset during commit, so I assume you really meant you
wanted to debug an abort problem. But even there, what's the problem?
Set the variable *before* you enter the transaction that will abort.

Or in the future we may
have some SQL-compatible always-in-transaction mode which would mean that
you could never set any variable to last.

Only if this mode prevents you from ever committing anything. Somehow
I doubt that that's either SQL-compatible or useful.

If you want something that's transaction-specific, invent a new mechanism.

I didn't say "transaction specific". I said that if you do a SET inside
a transaction block, and then the transaction is aborted, the effects of
the SET ought to roll back along with everything else you did inside
that transaction block. I'm not seeing what the argument is against
this.

regards, tom lane

#72Peter Eisentraut
peter_e@gmx.net
In reply to: Tom Lane (#71)
Re: timeout implementation issues

Tom Lane writes:

I didn't say "transaction specific". I said that if you do a SET inside
a transaction block, and then the transaction is aborted, the effects of
the SET ought to roll back along with everything else you did inside
that transaction block. I'm not seeing what the argument is against
this.

I consider SET variables metadata that are not affected by transactions.
I should be able to change my mind about my session preferences in the
middle of a transaction, no matter what happens to the data in it. Say
somewhere in the middle of a long transaction I think, "I should really be
logging this stuff". I turn a knob to do so, and the next command fails.
Is the failure logged? In which order does the rollback happen? What if
I want to continue logging?

If anything were to change I would like to continue accepting SET commands
after an error. Of course, I would like to continue accepting any command
after an error, but that's a different debate.

I guess it's a matter of definition: Do you consider SET variables
database state or session metadata? I think some are this and some are
that. I'm not sure how to draw the line, but throwing everything from one
category into the other isn't my favorite solution.

--
Peter Eisentraut peter_e@gmx.net

#73Tom Lane
tgl@sss.pgh.pa.us
In reply to: Peter Eisentraut (#72)
Re: timeout implementation issues

Peter Eisentraut <peter_e@gmx.net> writes:

I consider SET variables metadata that are not affected by transactions.

Why? Again, the fact that historically they've not acted that way isn't
sufficient reason for me.

I should be able to change my mind about my session preferences in the
middle of a transaction, no matter what happens to the data in it. Say
somewhere in the middle of a long transaction I think, "I should really be
logging this stuff". I turn a knob to do so, and the next command fails.
Is the failure logged? In which order does the rollback happen? What if
I want to continue logging?

Hm. That's a slightly more interesting example than before ... but it
comes close to arguing that logging should be under transaction control.
Surely you'd not argue that a failed transaction should erase all its
entries from the postmaster log? Why would you expect changes in log
levels to be retroactive?

I guess it's a matter of definition: Do you consider SET variables
database state or session metadata? I think some are this and some are
that. I'm not sure how to draw the line, but throwing everything from one
category into the other isn't my favorite solution.

You seem to be suggesting that we should make a variable-by-variable
decision about whether SET variables roll back on ABORT or not. I think
that way madness lies; we could spend forever debating which vars are
which, and then who will remember without consulting the documentation?

I feel we should just do it. Yeah, there might be some corner cases
where it's not the ideal behavior; but you haven't convinced me that
there are more cases where it's bad than where it's good. You sure
haven't convinced me that it's worth making SET's behavior
nigh-unpredictable-without-a-manual, which is what per-variable behavior
would be.

regards, tom lane

#74Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Peter Eisentraut (#72)
Re: timeout implementation issues

-----Original Message-----
From: Peter Eisentraut [mailto:peter_e@gmx.net]

I guess it's a matter of definition: Do you consider SET variables
database state or session metadata?

Session metadata IMHO. If there are(would be) database state
variables we should introduce another command for them.
For example I don't think QUERY_TIMEOUT is such a variable.
As I mentioned many times we can set QUERY_TIMEOUT before
each query. If the overhead is an issue we can keep track of the
varaible and reduce the command calls to minimum easily.

regards,
Hiroshi Inoue

#75Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#60)
Re: timeout implementation issues

-----Original Message-----
From: Bruce Momjian [mailto:pgman@candle.pha.pa.us]

Hiroshi Inoue wrote:

-----Original Message-----
From: Tom Lane

Jan Wieck <janwieck@yahoo.com> writes:

Could we get out of this by defining that "timeout" is
automatically reset at next statement end?

I was hoping to avoid that, because it seems like a wart. OTOH,
it'd be less of a wart than the global changes of semantics that
Bruce is proposing :-(

Probably I'm misunderstanding this thread.
Why must the query_timeout be reset particularly ?
What's wrong with simply issueing set query_timeout
command just before every query ?

You could do that, but we also imagine cases where people would want to
set a timeout for each query in an entire session.

Sorry I couldn't understand your point.
It seems the simplest and the most certain way is to call
'SET QUERY_TIMEOUT per query. The way dosen't require
RESET at all. Is the overhead an issue ?

regards,
Hiroshi Inoue

#76Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Hiroshi Inoue (#75)
Re: timeout implementation issues

Probably I'm misunderstanding this thread.
Why must the query_timeout be reset particularly ?
What's wrong with simply issueing set query_timeout
command just before every query ?

You could do that, but we also imagine cases where people would want to
set a timeout for each query in an entire session.

Sorry I couldn't understand your point.
It seems the simplest and the most certain way is to call
'SET QUERY_TIMEOUT per query. The way dosen't require
RESET at all. Is the overhead an issue ?

What about psql and libpq. Doing a timeout before every query is a
pain. I realize it can be done easily in ODBC and JDBC, but we need a
general timeout mechanism.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#77Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Tom Lane (#73)
Re: timeout implementation issues

I guess it's a matter of definition: Do you consider SET variables
database state or session metadata? I think some are this and some are
that. I'm not sure how to draw the line, but throwing everything from one
category into the other isn't my favorite solution.

You seem to be suggesting that we should make a variable-by-variable
decision about whether SET variables roll back on ABORT or not. I think
that way madness lies; we could spend forever debating which vars are
which, and then who will remember without consulting the documentation?

I feel we should just do it. Yeah, there might be some corner cases
where it's not the ideal behavior; but you haven't convinced me that
there are more cases where it's bad than where it's good. You sure
haven't convinced me that it's worth making SET's behavior
nigh-unpredictable-without-a-manual, which is what per-variable behavior
would be.

I am with Tom on this one. (Nice to see he is now arguing on my side.)
Making different variables behave differently is clearly going to
confuse users. The argument that we should allow SET to work when the
transaction is in ABORT state seems very wierd to me because we ignore
every other command in that state. I think reversing out any SET's done
in an aborted transaction is the clear way to go. If users want their
SET to not be affected by the transaction abort, they should put their
SET's outside a transaction; seems pretty clear to me.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#78Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#76)
Re: timeout implementation issues

Bruce Momjian wrote:

Probably I'm misunderstanding this thread.
Why must the query_timeout be reset particularly ?
What's wrong with simply issueing set query_timeout
command just before every query ?

You could do that, but we also imagine cases where people would want to
set a timeout for each query in an entire session.

Sorry I couldn't understand your point.
It seems the simplest and the most certain way is to call
'SET QUERY_TIMEOUT per query. The way dosen't require
RESET at all. Is the overhead an issue ?

What about psql and libpq. Doing a timeout before every query is a
pain.

Psql and libpq would simply issue the query according to the
user's request as they currently do. What's pain with it ?

regards,
Hiroshi Inoue

#79Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Hiroshi Inoue (#78)
Re: timeout implementation issues

Sorry I couldn't understand your point.
It seems the simplest and the most certain way is to call
'SET QUERY_TIMEOUT per query. The way dosen't require
RESET at all. Is the overhead an issue ?

What about psql and libpq. Doing a timeout before every query is a
pain.

Psql and libpq would simply issue the query according to the
user's request as they currently do. What's pain with it ?

If they wanted to place a timeout on all queries in a session, they
would need a SET for every query, which seems like a pain.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#80Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#77)
Re: timeout implementation issues

Bruce Momjian wrote:

I guess it's a matter of definition: Do you consider SET variables
database state or session metadata? I think some are this and some are
that. I'm not sure how to draw the line, but throwing everything from one
category into the other isn't my favorite solution.

You seem to be suggesting that we should make a variable-by-variable
decision about whether SET variables roll back on ABORT or not. I think
that way madness lies; we could spend forever debating which vars are
which, and then who will remember without consulting the documentation?

I feel we should just do it. Yeah, there might be some corner cases
where it's not the ideal behavior; but you haven't convinced me that
there are more cases where it's bad than where it's good. You sure
haven't convinced me that it's worth making SET's behavior
nigh-unpredictable-without-a-manual, which is what per-variable behavior
would be.

I am with Tom on this one. (Nice to see he is now arguing on my side.)

I vote against you. If a variable is local to the session, you
can change it as you like without bothering any other user(session).
Automatic resetting of the varibales is rather confusing to me.

regards,
Hiroshi Inoue

#81Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#79)
Re: timeout implementation issues

Bruce Momjian wrote:

Sorry I couldn't understand your point.
It seems the simplest and the most certain way is to call
'SET QUERY_TIMEOUT per query. The way dosen't require
RESET at all. Is the overhead an issue ?

What about psql and libpq. Doing a timeout before every query is a
pain.

Psql and libpq would simply issue the query according to the
user's request as they currently do. What's pain with it ?

If they wanted to place a timeout on all queries in a session, they
would need a SET for every query, which seems like a pain.

Oh I see. You mean users' pain ?
If a user wants to place a timeout on all the query, he
would issue SET query_timeout command only once.

regards,
Hiroshi Inoue

#82Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Hiroshi Inoue (#80)
Re: timeout implementation issues

Hiroshi Inoue wrote:

Bruce Momjian wrote:

I guess it's a matter of definition: Do you consider SET variables
database state or session metadata? I think some are this and some are
that. I'm not sure how to draw the line, but throwing everything from one
category into the other isn't my favorite solution.

You seem to be suggesting that we should make a variable-by-variable
decision about whether SET variables roll back on ABORT or not. I think
that way madness lies; we could spend forever debating which vars are
which, and then who will remember without consulting the documentation?

I feel we should just do it. Yeah, there might be some corner cases
where it's not the ideal behavior; but you haven't convinced me that
there are more cases where it's bad than where it's good. You sure
haven't convinced me that it's worth making SET's behavior
nigh-unpredictable-without-a-manual, which is what per-variable behavior
would be.

I am with Tom on this one. (Nice to see he is now arguing on my side.)

I vote against you. If a variable is local to the session, you
can change it as you like without bothering any other user(session).
Automatic resetting of the varibales is rather confusing to me.

I don't see how this relates to other users. All SET commands that can
be changed in psql are per backend, as far as I remember.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#83Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Hiroshi Inoue (#81)
Re: timeout implementation issues

Hiroshi Inoue wrote:

Bruce Momjian wrote:

Sorry I couldn't understand your point.
It seems the simplest and the most certain way is to call
'SET QUERY_TIMEOUT per query. The way dosen't require
RESET at all. Is the overhead an issue ?

What about psql and libpq. Doing a timeout before every query is a
pain.

Psql and libpq would simply issue the query according to the
user's request as they currently do. What's pain with it ?

If they wanted to place a timeout on all queries in a session, they
would need a SET for every query, which seems like a pain.

Oh I see. You mean users' pain ?

Sorry I was unclear.

If a user wants to place a timeout on all the query, he
would issue SET query_timeout command only once.

I am confused. Above you state you want SET QUERY_TIMEOUT to be
per-query. I assume you mean that the timeout applies for only the next
query and is turned off after that. If you do that, it is hard to set a
maximum duration for all queries in your session, especially in psql or
libpq.

Also, I am not saying that the timeout is for the entire session, but
that the timeout makes sure that any query in the session that takes
longer than X milliseconds is automatically cancelled.

Please reply and let me know what you think. I am sure I am missing
something in your comments.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#84Thomas Swan
tswan@olemiss.edu
In reply to: Bruce Momjian (#82)
Re: timeout implementation issues

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
</head>
<body>
Bruce Momjian wrote:<br>
<blockquote type="cite"
cite="mid200204080317.g383Hj511314@candle.pha.pa.us">
<pre wrap="">Hiroshi Inoue wrote:<br></pre>
<blockquote type="cite">
<pre wrap="">Bruce Momjian wrote:<br></pre>
<blockquote type="cite">
<blockquote type="cite">
<blockquote type="cite">
<pre wrap="">I guess it's a matter of definition: Do you consider SET variables<br>database state or session metadata? I think some are this and some are<br>that. I'm not sure how to draw the line, but throwing everything from one<br>category into the other isn't my favorite solution.<br></pre>
</blockquote>
<pre wrap="">You seem to be suggesting that we should make a variable-by-variable<br>decision about whether SET variables roll back on ABORT or not. I think<br>that way madness lies; we could spend forever debating which vars are<br>which, and then who will remember without consulting the documentation?<br><br>I feel we should just do it. Yeah, there might be some corner cases<br>where it's not the ideal behavior; but you haven't convinced me that<br>there are more cases where it's bad than where it's good. You sure<br>haven't convinced me that it's worth making SET's behavior<br>nigh-unpredictable-without-a-manual, which is what per-variable behavior<br>would be.<br></pre>
</blockquote>
<pre wrap="">I am with Tom on this one. (Nice to see he is now arguing on my side.)<br></pre>
</blockquote>
<pre wrap="">I vote against you. If a variable is local to the session, you<br>can change it as you like without bothering any other user(session).<br>Automatic resetting of the varibales is rather confusing to me.<br></pre>
</blockquote>
<pre wrap=""><!----><br>I don't see how this relates to other users. All SET commands that can<br>be changed in psql are per backend, as far as I remember.</pre>
</blockquote>
Per backend or per session?<br>
<blockquote type="cite"
cite="mid200204080317.g383Hj511314@candle.pha.pa.us">
<pre wrap=""><br><br></pre>
</blockquote>
<br>
<br>
</body>
</html>

#85Karel Zak
zakkr@zf.jcu.cz
In reply to: Bruce Momjian (#56)
Re: timeout implementation issues

On Fri, Apr 05, 2002 at 08:32:47PM -0500, Bruce Momjian wrote:

Or, as I suggested above, extend the SELECT (and other querys?) syntax
seems reasonable. More so than the non-standard 'use this index, really'
types of extensions that other RDBMSs provide, that we've rightly avoided.

I think we need timeout for all statement.

The Oracle has:

CREATE PROFILE statement with for example following options:

CONNECT_TIME
IDLE_TIME

I think system resource control per user is more useful than simple
SET command. There is no problem add other limits like QUERY_TIMEOUT.

Karel

--
Karel Zak <zakkr@zf.jcu.cz>
http://home.zf.jcu.cz/~zakkr/

C, PostgreSQL, PHP, WWW, http://docs.linux.cz, http://mape.jcu.cz

#86Karel Zak
zakkr@zf.jcu.cz
In reply to: Tom Lane (#54)
Re: timeout implementation issues

On Fri, Apr 05, 2002 at 02:13:26PM -0500, Tom Lane wrote:

It seems clear to me that SET *should* roll back on abort. Just a
matter of how important is it to fix.

I want control on this :-)

SET valname = 'vatdata' ON ROLLBACK UNSET;

or

SET valname = 'vatdata';

Karel
--
Karel Zak <zakkr@zf.jcu.cz>
http://home.zf.jcu.cz/~zakkr/

C, PostgreSQL, PHP, WWW, http://docs.linux.cz, http://mape.jcu.cz

#87Karel Zak
zakkr@zf.jcu.cz
In reply to: Peter Eisentraut (#72)
Re: timeout implementation issues

On Sun, Apr 07, 2002 at 01:01:07AM -0500, Peter Eisentraut wrote:

Tom Lane writes:

I didn't say "transaction specific". I said that if you do a SET inside
a transaction block, and then the transaction is aborted, the effects of
the SET ought to roll back along with everything else you did inside
that transaction block. I'm not seeing what the argument is against
this.

I consider SET variables metadata that are not affected by transactions.
I should be able to change my mind about my session preferences in the
middle of a transaction, no matter what happens to the data in it. Say

I agree with Peter. For example I have multi-encoding client program
that changing client-encoding in the middle of transaction and this
change not depend on transaction. And the other thing: I have DB
driver in an program there is not possible do SQL query outsite
transaction.

Is there some problem implement "SET ... ON ROLLBACK UNSET" ?

Karel

--
Karel Zak <zakkr@zf.jcu.cz>
http://home.zf.jcu.cz/~zakkr/

C, PostgreSQL, PHP, WWW, http://docs.linux.cz, http://mape.jcu.cz

#88Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#83)
Re: timeout implementation issues

-----Original Message-----
From: Bruce Momjian [mailto:pgman@candle.pha.pa.us]

Hiroshi Inoue wrote:

Bruce Momjian wrote:

Sorry I couldn't understand your point.
It seems the simplest and the most certain way is to call
'SET QUERY_TIMEOUT per query. The way dosen't require
RESET at all. Is the overhead an issue ?

What about psql and libpq. Doing a timeout before every

query is a

pain.

Psql and libpq would simply issue the query according to the
user's request as they currently do. What's pain with it ?

If they wanted to place a timeout on all queries in a session, they
would need a SET for every query, which seems like a pain.

Oh I see. You mean users' pain ?

Sorry I was unclear.

If a user wants to place a timeout on all the query, he
would issue SET query_timeout command only once.

I am confused. Above you state you want SET QUERY_TIMEOUT to be
per-query. I assume you mean that the timeout applies for only the next
query and is turned off after that.

Hmm there seems a misunderstanding between you and I but I
don't see what it is. Does *SET QUERY_TIMEOUT* start a timer in
your scenario ? In my scenario *SET QUERY_TIMEOUT* only
registers the timeout value for subsequent queries.

regards,
Hiroshi inoue

#89Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Hiroshi Inoue (#88)
Re: timeout implementation issues

Hiroshi Inoue wrote:

I am confused. Above you state you want SET QUERY_TIMEOUT to be
per-query. I assume you mean that the timeout applies for only the next
query and is turned off after that.

Hmm there seems a misunderstanding between you and I but I
don't see what it is. Does *SET QUERY_TIMEOUT* start a timer in
your scenario ? In my scenario *SET QUERY_TIMEOUT* only
registers the timeout value for subsequent queries.

SET QUERY_TIMEOUT does not start a timer. It makes sure each query
after the SET is timed and automatically canceled if the single query
exceeds the timeout interval.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#90Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Karel Zak (#87)
Re: timeout implementation issues

Karel Zak wrote:

I agree with Peter. For example I have multi-encoding client program
that changing client-encoding in the middle of transaction and this
change not depend on transaction. And the other thing: I have DB
driver in an program there is not possible do SQL query outsite
transaction.

No problem executing a SET inside its own transaction. The rollback
happens only if the SET fails, which for a single SEt command, should be
fine.

Is there some problem implement "SET ... ON ROLLBACK UNSET" ?

Seems kind of strange. If anything, I can imagine a NO ROLLBACK
capability. However, because this can be easily done by executing the
SET in its own transaction, it seems like overengineering.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#91Tom Lane
tgl@sss.pgh.pa.us
In reply to: Karel Zak (#87)
Re: timeout implementation issues

Karel Zak <zakkr@zf.jcu.cz> writes:

Is there some problem implement "SET ... ON ROLLBACK UNSET" ?

Yes. See my previous example concerning search_path: that variable
MUST be rolled back at transaction abort, else we risk its value being
invalid. We cannot offer the user a choice.

So far I have not seen one single example against SET rollback that
I thought was at all compelling. In all cases you can simply issue
the SET in a separate transaction if you want to be sure that its
effects persist. And there seems to be no consideration of the
possibility that applications might find SET rollback to be useful.
ISTM that the example with JDBC and query_timeout generalizes to other
parameters that you might want to set on a per-statement basis, such
as enable_seqscan or transform_null_equals. Consider

BEGIN;
SET enable_seqscan = false;
some-queries-that-might-fail;
SET enable_seqscan = true;
END;

This does not work as intended if the initial SET doesn't roll back
upon transaction failure. Yeah, you can restructure it to

SET enable_seqscan = false;
BEGIN;
some-queries-that-might-fail;
END;
SET enable_seqscan = true;

but what was that argument about some apps/drivers finding it
inconvenient to issue commands outside a transaction block?

regards, tom lane

#92Jan Wieck
janwieck@yahoo.com
In reply to: Bruce Momjian (#79)
Re: timeout implementation issues

Bruce Momjian wrote:

Sorry I couldn't understand your point.
It seems the simplest and the most certain way is to call
'SET QUERY_TIMEOUT per query. The way dosen't require
RESET at all. Is the overhead an issue ?

What about psql and libpq. Doing a timeout before every query is a
pain.

Psql and libpq would simply issue the query according to the
user's request as they currently do. What's pain with it ?

If they wanted to place a timeout on all queries in a session, they
would need a SET for every query, which seems like a pain.

Er, how many "applications" have you implemented by simply
providing a schema and psql?

I mean, users normally don't use psql. And if you do, what's
wrong with controlling the timeout yourself and hitting ^C
when "you" time out? If you do it in a script, it's

yy... p p p p p.

Jan

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me. #
#================================================== JanWieck@Yahoo.com #

#93Jan Wieck
janwieck@yahoo.com
In reply to: Tom Lane (#91)
Re: timeout implementation issues

Tom Lane wrote:

Karel Zak <zakkr@zf.jcu.cz> writes:

Is there some problem implement "SET ... ON ROLLBACK UNSET" ?

Yes. See my previous example concerning search_path: that variable
MUST be rolled back at transaction abort, else we risk its value being
invalid. We cannot offer the user a choice.

Not really on topic, but I was wondering how you ensure that
you correct the search path in case someone drops the schema?

Is an invalid search path really that critical (read security
issue)?

Jan

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me. #
#================================================== JanWieck@Yahoo.com #

#94Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jan Wieck (#93)
Re: timeout implementation issues

Jan Wieck <janwieck@yahoo.com> writes:

Is an invalid search path really that critical (read security
issue)?

It's not a security issue (unless the OID counter wraps around soon
enough to let someone else get assigned the same OID for a namespace).
But it could be pretty annoying anyway, because the front element of
the search path is also the default creation target namespace. You
could create a bunch of tables and then be unable to access them later
for lack of a way to name them.

I'm not really excited about establishing positive interlocks across
backends to prevent DROPping a namespace that someone else has in their
search path ... but I do want to handle the simple local-effect cases,
like rollback of creation of a namespace.

regards, tom lane

#95Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Jan Wieck (#92)
Re: timeout implementation issues

Jan Wieck wrote:

Psql and libpq would simply issue the query according to the
user's request as they currently do. What's pain with it ?

If they wanted to place a timeout on all queries in a session, they
would need a SET for every query, which seems like a pain.

Er, how many "applications" have you implemented by simply
providing a schema and psql?

Actually, I would assume nightly batch jobs are configured this way.

I mean, users normally don't use psql. And if you do, what's
wrong with controlling the timeout yourself and hitting ^C
when "you" time out? If you do it in a script, it's

Yes, clearly meaningless for interactive use.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#96Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Tom Lane (#91)
Re: timeout implementation issues

Tom Lane wrote:

This does not work as intended if the initial SET doesn't roll back
upon transaction failure. Yeah, you can restructure it to

SET enable_seqscan = false;
BEGIN;
some-queries-that-might-fail;
END;
SET enable_seqscan = true;

but what was that argument about some apps/drivers finding it
inconvenient to issue commands outside a transaction block?

Yes, and if you want to place the SET on a single statement in a
multi-statement transaction, doing SET outside the transaction will not
work either because it will apply to all statements in the transaction.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#97Thomas Lockhart
lockhart@fourpalms.org
In reply to: Peter Eisentraut (#72)
Re: timeout implementation issues

I consider SET variables metadata that are not affected by transactions.

Why? Again, the fact that historically they've not acted that way isn't
sufficient reason for me.

Hmm. Historically, SET controls behaviors *out of band* with the normal
transaction mechanisms. There is strong precedent for this mechanism
*because it is a useful concept*, not simply because it has always been
done this way.

*If* some aspects of SET take on transactional behavior, then this
should be *in addition to* the current global scope for those commands.

What problem are we trying to solve with this? The topic came up in a
discussion on implementing timeouts for JDBC. afaik it has not come up
*in any context* for the last seven years, so maybe we should settle
down a bit and refocus on the problem at hand...

- Thomas

#98Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Thomas Lockhart (#97)
Re: timeout implementation issues

Thomas Lockhart wrote:

I consider SET variables metadata that are not affected by transactions.

Why? Again, the fact that historically they've not acted that way isn't
sufficient reason for me.

Hmm. Historically, SET controls behaviors *out of band* with the normal
transaction mechanisms. There is strong precedent for this mechanism
*because it is a useful concept*, not simply because it has always been
done this way.

OK, probably good time for summarization. First, consider this:

BEGIN WORK;
SET something;
query fails;
SET something else;
COMMIT WORK;

Under current behavior, the first SET is honored, while the second is
ignored because the transaction is in ABORT state. I can see no logical
reason for this behavior. We ignore normal queries during an ABORT
because the transaction can't possibly change any data because it is
aborted, and the previous non-SET statements in the transactions are
rolled back. However, the SET commands are not.

The jdbc timeout issue is this:

BEGIN WORK;
SET query_timeout=20;
query fails;
SET query_timeout=0;
COMMIT WORK;

In this case, with our current code, the first SET is done, but the
second is ignored. To make this work, you would need this:

BEGIN WORK;
SET query_timeout=20;
query fails;
SET query_timeout=0;
COMMIT WORK;
SET query_timeout=0;

which seems kind of strange. The last SET is needed because the query
may abort and the second SET ignored.

*If* some aspects of SET take on transactional behavior, then this
should be *in addition to* the current global scope for those commands.

My point is that SET already doesn't have session behavior because it is
ignored if the transaction has already aborted.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#99Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Bruce Momjian (#98)
Re: timeout implementation issues

Peter Eisentraut wrote:

Bruce Momjian writes:

OK, probably good time for summarization. First, consider this:

BEGIN WORK;
SET something;
query fails;
SET something else;
COMMIT WORK;

Under current behavior, the first SET is honored, while the second is
ignored because the transaction is in ABORT state. I can see no logical
reason for this behavior.

But that is not a shortcoming of the SET command. The problem is that the
system does not accept any commands after one command has failed in a
transaction even though it could usefully do so.

Uh, yes, we could allow the second SET to succeed even in an aborted
transaction, but Tom says his schema stuff will not work in an aborted
state, so Tom/I figured the only other option was rollback of the first
SET.

The jdbc timeout issue is this:

BEGIN WORK;
SET query_timeout=20;
query fails;
SET query_timeout=0;
COMMIT WORK;

In this case, with our current code, the first SET is done, but the
second is ignored.

Given appropriate functionality, you could rewrite this thus:

BEGIN WORK;
SET FOR THIS TRANSACTION ONLY query_timeout=20;
query;
COMMIT WORK;

Yes, but why bother with that when rollback of the first SET is cleaner
and more predictable?

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#100Peter Eisentraut
peter_e@gmx.net
In reply to: Bruce Momjian (#98)
Re: timeout implementation issues

Bruce Momjian writes:

OK, probably good time for summarization. First, consider this:

BEGIN WORK;
SET something;
query fails;
SET something else;
COMMIT WORK;

Under current behavior, the first SET is honored, while the second is
ignored because the transaction is in ABORT state. I can see no logical
reason for this behavior.

But that is not a shortcoming of the SET command. The problem is that the
system does not accept any commands after one command has failed in a
transaction even though it could usefully do so.

The jdbc timeout issue is this:

BEGIN WORK;
SET query_timeout=20;
query fails;
SET query_timeout=0;
COMMIT WORK;

In this case, with our current code, the first SET is done, but the
second is ignored.

Given appropriate functionality, you could rewrite this thus:

BEGIN WORK;
SET FOR THIS TRANSACTION ONLY query_timeout=20;
query;
COMMIT WORK;

--
Peter Eisentraut peter_e@gmx.net

#101Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#82)
Re: timeout implementation issues

-----Original Message-----
From: Bruce Momjian [mailto:pgman@candle.pha.pa.us]

Hiroshi Inoue wrote:

I feel we should just do it. Yeah, there might be some corner cases
where it's not the ideal behavior; but you haven't convinced me that
there are more cases where it's bad than where it's good. You sure
haven't convinced me that it's worth making SET's behavior
nigh-unpredictable-without-a-manual, which is what

per-variable behavior

would be.

I am with Tom on this one. (Nice to see he is now arguing on

my side.)

I vote against you. If a variable is local to the session, you
can change it as you like without bothering any other user(session).
Automatic resetting of the varibales is rather confusing to me.

I don't see how this relates to other users. All SET commands that can
be changed in psql are per backend, as far as I remember.

Sorry for my poor explanation. What I meant is that *Rollback*
is to cancel the changes made to SQL-data or schemas
not to put back the variables which are local to the session.

regards,
Hiroshi Inoue

#102Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Hiroshi Inoue (#101)
Re: timeout implementation issues

Hiroshi Inoue wrote:

I vote against you. If a variable is local to the session, you
can change it as you like without bothering any other user(session).
Automatic resetting of the varibales is rather confusing to me.

I don't see how this relates to other users. All SET commands that can
be changed in psql are per backend, as far as I remember.

Sorry for my poor explanation. What I meant is that *Rollback*
is to cancel the changes made to SQL-data or schemas
not to put back the variables which are local to the session.

OK, got it, so if someone makes a session change while in a transaction,
and the transaction aborts, should the SET be rolled back too? If not,
then we should honor the SET's that happen after the transaction aborts.
However, Tom's schema changes require a db connection, so it is hard to
honor the SET's once the transaction aborts. That is how we got to the
abort all SET's in an aborted transaction.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#103Jan Wieck
janwieck@yahoo.com
In reply to: Tom Lane (#94)
Re: timeout implementation issues

Tom Lane wrote:

Jan Wieck <janwieck@yahoo.com> writes:

Is an invalid search path really that critical (read security
issue)?

It's not a security issue (unless the OID counter wraps around soon
enough to let someone else get assigned the same OID for a namespace).
But it could be pretty annoying anyway, because the front element of
the search path is also the default creation target namespace. You
could create a bunch of tables and then be unable to access them later
for lack of a way to name them.

I'm not really excited about establishing positive interlocks across
backends to prevent DROPping a namespace that someone else has in their
search path ... but I do want to handle the simple local-effect cases,
like rollback of creation of a namespace.

How are namespaces different from any other objects? Can I
specify a foreign key reference to a table that was there at
some time in the past? Can I create a view using functions
that have been there last week? Sure, I can break those
objects once created by dropping the underlying stuff, but
that's another issue.

If namespace dropping allows for creation of objects that
cannot be dropped afterwards any more, I would call that a
bug or design flaw, which has to be fixed. Just preventing an
invalid search path resulting from a rollback operation like
in your example is totally insufficient.

Jan

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me. #
#================================================== JanWieck@Yahoo.com #

#104Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#99)
Re: timeout implementation issues

Bruce Momjian <pgman@candle.pha.pa.us> writes:

But that is not a shortcoming of the SET command. The problem is that the
system does not accept any commands after one command has failed in a
transaction even though it could usefully do so.

In a situation where the reason for failure was a syntax error, it seems
to me quite dangerous to try to execute any further commands; you may
not be executing what the user thought he typed. So I'm leery of any
proposals that we allow SETs to execute in transaction-abort state,
even if the implementation could support it.

Uh, yes, we could allow the second SET to succeed even in an aborted
transaction, but Tom says his schema stuff will not work in an aborted
state, so Tom/I figured the only other option was rollback of the first
SET.

The search_path case is the main reason why I'm intent on changing
the behavior of SET; without that, I'd just leave well enough alone.
Possibly some will suggest that search_path shouldn't be a SET variable
because it needs to be able to be rolled back on error. But what else
should it be? It's definitely per-session status, not persistent
database state. I don't much care for the notion of having SET act
differently for some variables than others, or requiring people to use
a different command for some variables than others.

regards, tom lane

#105Tom Lane
tgl@sss.pgh.pa.us
In reply to: Hiroshi Inoue (#101)
Re: timeout implementation issues

"Hiroshi Inoue" <Inoue@tpf.co.jp> writes:

Sorry for my poor explanation. What I meant is that *Rollback*
is to cancel the changes made to SQL-data or schemas
not to put back the variables which are local to the session.

Uh, why? Seems to me you are asserting as a given exactly the
point that is under debate. Let me give a counterexample:

BEGIN;
CREATE TEMP TABLE foo;
something-erroneous;
END;

The creation of the temp table will be rolled back on error, no?
Now the temp table is certainly session local --- ideally our
implementation would not let any other session see any trace of
it at all. (In practice it is visible if you know where to look,
but surely that's just an implementation artifact.)

If you argue that SETs should not roll back because they are
session-local, it seems to me that a logical consequence of that
position is that operations on temp tables should not roll back
either ... and that can hardly be deemed desirable.

regards, tom lane

#106Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jan Wieck (#103)
Re: timeout implementation issues

Jan Wieck <janwieck@yahoo.com> writes:

If namespace dropping allows for creation of objects that
cannot be dropped afterwards any more, I would call that a
bug or design flaw, which has to be fixed.

I will not require schema support to wait upon the existence of
dependency checking, if that's what you're suggesting.

This does suggest an interesting hole in our thoughts so far about
dependency checking. If someone is, say, trying to drop type T,
it's not really sufficient to verify that there are no existing
tables or functions referencing type T. What of created but as yet
uncommitted objects? Seems like a full defense would require being
able to obtain a lock on the object to be dropped, while creators
of references must obtain some conflicting lock that they hold until
they commit. Right now we only have locks on tables ... seems like
that's not sufficient.

regards, tom lane

#107Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#89)
Re: timeout implementation issues

-----Original Message-----
From: Bruce Momjian [mailto:pgman@candle.pha.pa.us]

Hiroshi Inoue wrote:

I am confused. Above you state you want SET QUERY_TIMEOUT to be
per-query. I assume you mean that the timeout applies for

only the next

query and is turned off after that.

Hmm there seems a misunderstanding between you and I but I
don't see what it is. Does *SET QUERY_TIMEOUT* start a timer in
your scenario ? In my scenario *SET QUERY_TIMEOUT* only
registers the timeout value for subsequent queries.

SET QUERY_TIMEOUT does not start a timer. It makes sure each query
after the SET is timed and automatically canceled if the single query
exceeds the timeout interval.

OK using your example, one by one

BEGIN WORK;
SET query_timeout=20;
query fails;
SET query_timeout=0;

For what the SET was issued ?
What command is issued if the query was successful ?

COMMIT WORK;

regards,
Hiroshi Inoue

#108Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Tom Lane (#105)
Re: timeout implementation issues

-----Original Message-----
From: Tom Lane [mailto:tgl@sss.pgh.pa.us]

"Hiroshi Inoue" <Inoue@tpf.co.jp> writes:

Sorry for my poor explanation. What I meant is that *Rollback*
is to

cancel the changes made to SQL-data or schemas

This line is a quote from SQL99 not my creation.

not to put back the variables which are local to the session.

Uh, why? Seems to me you are asserting as a given exactly the
point that is under debate. Let me give a counterexample:

BEGIN;
CREATE TEMP TABLE foo;
something-erroneous;
END;

The creation of the temp table will be rolled back on error, no?

??? TEMP TABLE is a SQL-data not a variable.
I don't think rolling back SETs makes things plain.

regards,
Hiroshi Inoue

#109Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Hiroshi Inoue (#107)
Re: timeout implementation issues

Hiroshi Inoue wrote:

-----Original Message-----
From: Bruce Momjian [mailto:pgman@candle.pha.pa.us]

Hiroshi Inoue wrote:

I am confused. Above you state you want SET QUERY_TIMEOUT to be
per-query. I assume you mean that the timeout applies for

only the next

query and is turned off after that.

Hmm there seems a misunderstanding between you and I but I
don't see what it is. Does *SET QUERY_TIMEOUT* start a timer in
your scenario ? In my scenario *SET QUERY_TIMEOUT* only
registers the timeout value for subsequent queries.

SET QUERY_TIMEOUT does not start a timer. It makes sure each query
after the SET is timed and automatically canceled if the single query
exceeds the timeout interval.

OK using your example, one by one

BEGIN WORK;
SET query_timeout=20;
query fails;
SET query_timeout=0;

For what the SET was issued ?
What command is issued if the query was successful ?

COMMIT WORK;

Here, SET should only to the query labeled "query fails". However,
right now, because the query failed, the second SET would not be seen,
and the timout would apply to all remaining queries in the session.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#110Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#109)
Re: timeout implementation issues

-----Original Message-----
From: Bruce Momjian [mailto:pgman@candle.pha.pa.us]

OK using your example, one by one

BEGIN WORK;
SET query_timeout=20;
query fails;
SET query_timeout=0;

For what the SET was issued ?
What command is issued if the query was successful ?

COMMIT WORK;

Here, SET should only to the query labeled "query fails".

Why should the SET query_timeout = 0 command be issued
only when the query failed ? Is it a JDBC driver's requirement
or some applications' requirements which uses the JDBC driver ?

regards,
Hiroshi Inoue

#111Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Hiroshi Inoue (#110)
Re: timeout implementation issues

Hiroshi Inoue wrote:

-----Original Message-----
From: Bruce Momjian [mailto:pgman@candle.pha.pa.us]

OK using your example, one by one

BEGIN WORK;
SET query_timeout=20;
query fails;
SET query_timeout=0;

For what the SET was issued ?
What command is issued if the query was successful ?

COMMIT WORK;

Here, SET should only to the query labeled "query fails".

Why should the SET query_timeout = 0 command be issued
only when the query failed ? Is it a JDBC driver's requirement
or some applications' requirements which uses the JDBC driver ?

They want the timeout for only the one statement, so they have to set it
to non-zero before the statement, and to zero after the statement. In
our current code, if the query fails, the setting to zero is ignored,
meaning all following queries have the timeout, even ones outside that
transaction.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#112Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#111)
Re: timeout implementation issues

Bruce Momjian wrote:

Hiroshi Inoue wrote:

-----Original Message-----
From: Bruce Momjian [mailto:pgman@candle.pha.pa.us]

OK using your example, one by one

BEGIN WORK;
SET query_timeout=20;
query fails;
SET query_timeout=0;

For what the SET was issued ?
What command is issued if the query was successful ?

COMMIT WORK;

Here, SET should only to the query labeled "query fails".

Why should the SET query_timeout = 0 command be issued
only when the query failed ? Is it a JDBC driver's requirement
or some applications' requirements which uses the JDBC driver ?

They want the timeout for only the one statement, so they have to set it
to non-zero before the statement, and to zero after the statement.

Does setQueryTimeout() issue a corresponding SET QUERY_TIMEOUT
command immediately in the scenario ?

regards,
Hiroshi Inoue

#113Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Hiroshi Inoue (#112)
Re: timeout implementation issues

Hiroshi Inoue wrote:

Why should the SET query_timeout = 0 command be issued
only when the query failed ? Is it a JDBC driver's requirement
or some applications' requirements which uses the JDBC driver ?

They want the timeout for only the one statement, so they have to set it
to non-zero before the statement, and to zero after the statement.

Does setQueryTimeout() issue a corresponding SET QUERY_TIMEOUT
command immediately in the scenario ?

Yes. If we don't make the SET rollback-able, we have to do all sorts of
tricks in jdbc so aborted transactions get the proper SET value.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#114Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#113)
Re: timeout implementation issues

Bruce Momjian wrote:

Hiroshi Inoue wrote:

Why should the SET query_timeout = 0 command be issued
only when the query failed ? Is it a JDBC driver's requirement
or some applications' requirements which uses the JDBC driver ?

They want the timeout for only the one statement, so they have to set it
to non-zero before the statement, and to zero after the statement.

Does setQueryTimeout() issue a corresponding SET QUERY_TIMEOUT
command immediately in the scenario ?

Yes. If we don't make the SET rollback-able, we have to do all sorts of
tricks in jdbc so aborted transactions get the proper SET value.

In my scenario, setQueryTimeout() only saves the timeout
value and issues the corrsponding SET QUERY_TIMEOUT command
immediately before each query if necessary.

regards,
Hiroshi Inoue

#115Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Hiroshi Inoue (#114)
Re: timeout implementation issues

Hiroshi Inoue wrote:

Bruce Momjian wrote:

Hiroshi Inoue wrote:

Why should the SET query_timeout = 0 command be issued
only when the query failed ? Is it a JDBC driver's requirement
or some applications' requirements which uses the JDBC driver ?

They want the timeout for only the one statement, so they have to set it
to non-zero before the statement, and to zero after the statement.

Does setQueryTimeout() issue a corresponding SET QUERY_TIMEOUT
command immediately in the scenario ?

Yes. If we don't make the SET rollback-able, we have to do all sorts of
tricks in jdbc so aborted transactions get the proper SET value.

In my scenario, setQueryTimeout() only saves the timeout
value and issues the corrsponding SET QUERY_TIMEOUT command
immediately before each query if necessary.

Yes, we can do that, but it requires an interface like odbc or jdbc. It
is hard to use for libpq or psql.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#116Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#115)
Re: timeout implementation issues

Bruce Momjian wrote:

Hiroshi Inoue wrote:

Bruce Momjian wrote:

They want the timeout for only the one statement, so they have to set it
to non-zero before the statement, and to zero after the statement.

Does setQueryTimeout() issue a corresponding SET QUERY_TIMEOUT
command immediately in the scenario ?

Yes. If we don't make the SET rollback-able, we have to do all sorts of
tricks in jdbc so aborted transactions get the proper SET value.

In my scenario, setQueryTimeout() only saves the timeout
value and issues the corrsponding SET QUERY_TIMEOUT command
immediately before each query if necessary.

Yes, we can do that,

Something like my scenario is needed because there could be
more than 1 statement objects with relatively different
query timeout at the same time in theory.

but it requires an interface like odbc or jdbc. It
is hard to use for libpq or psql.

We shouldn't expect too much on psql in the first place
because it isn't procedural. I don't expect too much on
libpq either because it's a low level interface. However
applications which use libpq could do like odbc or jdbc
does. Or libpq could also provide a function which encap-
sulates the query timeout handling if necessary.

regards,
Hiroshi Inoue

#117Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Hiroshi Inoue (#116)
Re: timeout implementation issues

Hiroshi Inoue wrote:

Bruce Momjian wrote:

Hiroshi Inoue wrote:

Bruce Momjian wrote:

They want the timeout for only the one statement, so they have to set it
to non-zero before the statement, and to zero after the statement.

Does setQueryTimeout() issue a corresponding SET QUERY_TIMEOUT
command immediately in the scenario ?

Yes. If we don't make the SET rollback-able, we have to do all sorts of
tricks in jdbc so aborted transactions get the proper SET value.

In my scenario, setQueryTimeout() only saves the timeout
value and issues the corrsponding SET QUERY_TIMEOUT command
immediately before each query if necessary.

Yes, we can do that,

Something like my scenario is needed because there could be
more than 1 statement objects with relatively different
query timeout at the same time in theory.

Yes, if you want multiple timeouts, you clearly could go in that
direction. Right now, we are considering only single-statement timing
and no one has asked for multiple timers.

but it requires an interface like odbc or jdbc. It
is hard to use for libpq or psql.

We shouldn't expect too much on psql in the first place
because it isn't procedural. I don't expect too much on
libpq either because it's a low level interface. However
applications which use libpq could do like odbc or jdbc
does. Or libpq could also provide a function which encap-
sulates the query timeout handling if necessary.

I certainly would like _something_ that works in psql/libpq, and the
simple SET QUERY_TIMEOUT does work for them. More sophisticated stuff
probably should be done in the application or interface.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#118Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#117)
Re: timeout implementation issues

Bruce Momjian wrote:

Hiroshi Inoue wrote:

Bruce Momjian wrote:

Hiroshi Inoue wrote:

Bruce Momjian wrote:

They want the timeout for only the one statement, so they have to set it
to non-zero before the statement, and to zero after the statement.

Does setQueryTimeout() issue a corresponding SET QUERY_TIMEOUT
command immediately in the scenario ?

Yes. If we don't make the SET rollback-able, we have to do all sorts of
tricks in jdbc so aborted transactions get the proper SET value.

In my scenario, setQueryTimeout() only saves the timeout
value and issues the corrsponding SET QUERY_TIMEOUT command
immediately before each query if necessary.

Yes, we can do that,

Something like my scenario is needed because there could be
more than 1 statement objects with relatively different
query timeout at the same time in theory.

Yes, if you want multiple timeouts, you clearly could go in that
direction. Right now, we are considering only single-statement timing
and no one has asked for multiple timers.

I don't ask multiple timers. ODBC driver would be able
to handle multiple timeouts without multiple timers in
my scenario.

but it requires an interface like odbc or jdbc. It
is hard to use for libpq or psql.

We shouldn't expect too much on psql in the first place
because it isn't procedural. I don't expect too much on
libpq either because it's a low level interface. However
applications which use libpq could do like odbc or jdbc
does. Or libpq could also provide a function which encap-
sulates the query timeout handling if necessary.

I certainly would like _something_ that works in psql/libpq,

Please don't make things complicated by sticking to such
low level interfaces.

regards,
Hiroshi Inoue

#119Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Hiroshi Inoue (#118)
Re: timeout implementation issues

Hiroshi Inoue wrote:

Yes, if you want multiple timeouts, you clearly could go in that
direction. Right now, we are considering only single-statement timing
and no one has asked for multiple timers.

I don't ask multiple timers. ODBC driver would be able
to handle multiple timeouts without multiple timers in
my scenario.

I understand.

but it requires an interface like odbc or jdbc. It
is hard to use for libpq or psql.

We shouldn't expect too much on psql in the first place
because it isn't procedural. I don't expect too much on
libpq either because it's a low level interface. However
applications which use libpq could do like odbc or jdbc
does. Or libpq could also provide a function which encap-
sulates the query timeout handling if necessary.

I certainly would like _something_ that works in psql/libpq,

Please don't make things complicated by sticking to such
low level interfaces.

OK, what is your proposal?

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#120Karel Zak
zakkr@zf.jcu.cz
In reply to: Peter Eisentraut (#100)
Re: timeout implementation issues

On Mon, Apr 08, 2002 at 12:28:18PM -0400, Peter Eisentraut wrote:

Bruce Momjian writes:

OK, probably good time for summarization. First, consider this:

BEGIN WORK;
SET something;
query fails;
SET something else;
COMMIT WORK;

Under current behavior, the first SET is honored, while the second is
ignored because the transaction is in ABORT state. I can see no logical
reason for this behavior.

But that is not a shortcoming of the SET command. The problem is that the
system does not accept any commands after one command has failed in a
transaction even though it could usefully do so.

The jdbc timeout issue is this:

BEGIN WORK;
SET query_timeout=20;
query fails;
SET query_timeout=0;
COMMIT WORK;

In this case, with our current code, the first SET is done, but the
second is ignored.

Given appropriate functionality, you could rewrite this thus:

BEGIN WORK;
SET FOR THIS TRANSACTION ONLY query_timeout=20;
query;
COMMIT WORK;

If I compare Peter's and Bruce's examples the Peter is still winner :-)

Sorry, but a code with "set-it-after-abort" seems ugly.

Karel

--
Karel Zak <zakkr@zf.jcu.cz>
http://home.zf.jcu.cz/~zakkr/

C, PostgreSQL, PHP, WWW, http://docs.linux.cz, http://mape.jcu.cz

#121Karel Zak
zakkr@zf.jcu.cz
In reply to: Tom Lane (#104)
Re: timeout implementation issues

On Mon, Apr 08, 2002 at 01:03:41PM -0400, Tom Lane wrote:

The search_path case is the main reason why I'm intent on changing
the behavior of SET; without that, I'd just leave well enough alone.

Is there more variables like "search_path"? If not, I unsure if one
item is good consideration for change others things.

Possibly some will suggest that search_path shouldn't be a SET variable
because it needs to be able to be rolled back on error. But what else
should it be? It's definitely per-session status, not persistent

It's good point. Why not make it more transparent? You want
encapsulate it to standard and current SET statement, but if it's
something different why not use for it different statement?

SET SESSION search_path TO 'something';

(...or something other)

Karel

--
Karel Zak <zakkr@zf.jcu.cz>
http://home.zf.jcu.cz/~zakkr/

C, PostgreSQL, PHP, WWW, http://docs.linux.cz, http://mape.jcu.cz

#122Michael Loftis
mloftis@wgops.com
In reply to: Bruce Momjian (#99)
Re: timeout implementation issues

Heh pardon me but...

I was under the impression that for a transaction either all commands
succeed or all commands fail, atleast according to everything I've ever
read. So followign that all SETs done within the scope of a
BEGIN/COMMIT pair should only take effect if the whole set finishes, if
not the system shoudl roll back to the way it was before the BEGIN.

I might be missing something though, I just got onto the list and there
might be other parts of the thread I missed....

Karel Zak wrote:

Show quoted text

On Mon, Apr 08, 2002 at 01:03:41PM -0400, Tom Lane wrote:

The search_path case is the main reason why I'm intent on changing
the behavior of SET; without that, I'd just leave well enough alone.

Is there more variables like "search_path"? If not, I unsure if one
item is good consideration for change others things.

Possibly some will suggest that search_path shouldn't be a SET variable
because it needs to be able to be rolled back on error. But what else
should it be? It's definitely per-session status, not persistent

It's good point. Why not make it more transparent? You want
encapsulate it to standard and current SET statement, but if it's
something different why not use for it different statement?

SET SESSION search_path TO 'something';

(...or something other)

Karel

#123Tom Lane
tgl@sss.pgh.pa.us
In reply to: Karel Zak (#121)
Re: timeout implementation issues

Karel Zak <zakkr@zf.jcu.cz> writes:

It's good point. Why not make it more transparent? You want
encapsulate it to standard and current SET statement, but if it's
something different why not use for it different statement?

SET SESSION search_path TO 'something';

But a plain SET is also setting the value for the session. What's
the difference? Why should a user remember that he must use this
syntax for search_path, and not for any other variables (or perhaps
only one or two other ones, further down the road)?

regards, tom lane

#124Peter Eisentraut
peter_e@gmx.net
In reply to: Michael Loftis (#122)
Re: timeout implementation issues

Michael Loftis writes:

I was under the impression that for a transaction either all commands
succeed or all commands fail, atleast according to everything I've ever
read.

That's an urban legend.

A transaction guarantees (among other things) that all modifications to
the database with the transaction are done atomicly (either all or done or
none). This does not extend to the commands that supposedly initiate such
modifications.

Take out a database other than PostgreSQL and do

BEGIN; -- or whatever they use; might be implicit
INSERT INTO existing_table ('legal value');
barf;
COMMIT;

The INSERT will most likely succeed. The reason is that "barf" does not
modify or access the data in the database, so it does not affect the
transactional integrity of the database.

We are trying to make the same argument for SET. SET does not modify the
database, so it doesn't have to fall under transaction control.

--
Peter Eisentraut peter_e@gmx.net

#125Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Peter Eisentraut (#124)
Re: timeout implementation issues

Peter Eisentraut wrote:

Michael Loftis writes:

I was under the impression that for a transaction either all commands
succeed or all commands fail, atleast according to everything I've ever
read.

That's an urban legend.

A transaction guarantees (among other things) that all modifications to
the database with the transaction are done atomicly (either all or done or
none). This does not extend to the commands that supposedly initiate such
modifications.

Take out a database other than PostgreSQL and do

BEGIN; -- or whatever they use; might be implicit
INSERT INTO existing_table ('legal value');
barf;
COMMIT;

The INSERT will most likely succeed. The reason is that "barf" does not
modify or access the data in the database, so it does not affect the
transactional integrity of the database.

Ewe, we do fail that test.

We are trying to make the same argument for SET. SET does not modify the
database, so it doesn't have to fall under transaction control.

OK, we have three possibilities:

o All SETs are honored in an aborted transaction
o No SETs are honored in an aborted transaction
o Some SETs are honored in an aborted transaction (current)

I think the problem is our current behavior. I don't think anyone can
say our it is correct (only honor SET before the transaction reaches
abort state). Whether we want the first or second is the issue, I think.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#126Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#125)
Re: timeout implementation issues

Bruce Momjian wrote:

OK, we have three possibilities:

o All SETs are honored in an aborted transaction
o No SETs are honored in an aborted transaction
o Some SETs are honored in an aborted transaction (current)

I think the problem is our current behavior. I don't think anyone can
say our it is correct (only honor SET before the transaction reaches
abort state). Whether we want the first or second is the issue, I think.

I think the current state is not that bad at least
is better than the first. I don't think it's a
*should be* kind of thing and we shouldn't stick
to it any longer.

regards,
Hiroshi Inoue

#127Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#99)
Re: timeout implementation issues

Tom Lane wrote:

Karel Zak <zakkr@zf.jcu.cz> writes:

It's good point. Why not make it more transparent? You want
encapsulate it to standard and current SET statement, but if it's
something different why not use for it different statement?

SET SESSION search_path TO 'something';

But a plain SET is also setting the value for the session. What's
the difference? Why should a user remember that he must use this
syntax for search_path, and not for any other variables (or perhaps
only one or two other ones, further down the road)?

ISTM what Karel meant is that if the search_path is a
much more significant variable than others you had better
express the difference using a different statement.
I agree with Karel though I don't know how siginificant
the varible is.

regards,
Hiroshi Inoue

#128Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#125)
Re: timeout implementation issues

Hiroshi Inoue wrote:

Bruce Momjian wrote:

OK, we have three possibilities:

o All SETs are honored in an aborted transaction
o No SETs are honored in an aborted transaction
o Some SETs are honored in an aborted transaction (current)

I think the problem is our current behavior. I don't think anyone can
say our it is correct (only honor SET before the transaction reaches
abort state). Whether we want the first or second is the issue, I think.

I think the current state is not that bad at least
is better than the first.

Oops does the first mean rolling back the variables on abort ?
If so I made a mistake. The current is better than the second.

regards,
Hiroshi Inoue

#129Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Hiroshi Inoue (#128)
Re: timeout implementation issues

Hiroshi Inoue wrote:

Hiroshi Inoue wrote:

Bruce Momjian wrote:

OK, we have three possibilities:

o All SETs are honored in an aborted transaction
o No SETs are honored in an aborted transaction
o Some SETs are honored in an aborted transaction (current)

I think the problem is our current behavior. I don't think anyone can
say our it is correct (only honor SET before the transaction reaches
abort state). Whether we want the first or second is the issue, I think.

I think the current state is not that bad at least
is better than the first.

Oops does the first mean rolling back the variables on abort ?
If so I made a mistake. The current is better than the second.

The second means all SET's are rolled back on abort.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#130Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#129)
Re: timeout implementation issues

Bruce Momjian wrote:

Hiroshi Inoue wrote:

Hiroshi Inoue wrote:

Bruce Momjian wrote:

OK, we have three possibilities:

o All SETs are honored in an aborted transaction
o No SETs are honored in an aborted transaction
o Some SETs are honored in an aborted transaction (current)

I think the problem is our current behavior. I don't think anyone can
say our it is correct (only honor SET before the transaction reaches
abort state). Whether we want the first or second is the issue, I think.

I think the current state is not that bad at least
is better than the first.

Oops does the first mean rolling back the variables on abort ?
If so I made a mistake. The current is better than the second.

The second means all SET's are rolled back on abort.

I see.
BTW what varibles are rolled back on abort currently ?

regards,
Hiroshi Inoue

#131Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Hiroshi Inoue (#130)
Re: timeout implementation issues

Hiroshi Inoue wrote:

Oops does the first mean rolling back the variables on abort ?
If so I made a mistake. The current is better than the second.

The second means all SET's are rolled back on abort.

I see.
BTW what varibles are rolled back on abort currently ?

Currently, none, though the SET commands after the query aborts are
ignored, which is effectively the same as rolling them back.

BEGIN WORK;
SET x=3;
failed query;
SET x=5;
COMMIT;

In this case, x=3 at end of query.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#132Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#131)
Re: timeout implementation issues

Bruce Momjian wrote:

Hiroshi Inoue wrote:

Oops does the first mean rolling back the variables on abort ?
If so I made a mistake. The current is better than the second.

The second means all SET's are rolled back on abort.

I see.
BTW what varibles are rolled back on abort currently ?

Currently, none,

??? What do you mean by
o Some SETs are honored in an aborted transaction (current)
?
Is the current state different from
o All SETs are honored in an aborted transaction
?

regards,
Hiroshi Inoue

#133Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Hiroshi Inoue (#132)
Re: timeout implementation issues

Hiroshi Inoue wrote:

Bruce Momjian wrote:

Hiroshi Inoue wrote:

Oops does the first mean rolling back the variables on abort ?
If so I made a mistake. The current is better than the second.

The second means all SET's are rolled back on abort.

I see.
BTW what varibles are rolled back on abort currently ?

Currently, none,

??? What do you mean by
o Some SETs are honored in an aborted transaction (current)
?
Is the current state different from
o All SETs are honored in an aborted transaction
?

In the case of:

BEGIN WORK;
SET x=1;
bad query that aborts transaction;
SET x=2;
COMMIT WORK;

Only the first SET is done, so at the end, x = 1. If all SET's were
honored, x = 2. If no SETs in an aborted transaction were honored, x
would equal whatever it was before the BEGIN WORK above.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#134Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#133)
Re: timeout implementation issues

Bruce Momjian wrote:

Hiroshi Inoue wrote:

Bruce Momjian wrote:

Hiroshi Inoue wrote:

Oops does the first mean rolling back the variables on abort ?
If so I made a mistake. The current is better than the second.

The second means all SET's are rolled back on abort.

I see.
BTW what varibles are rolled back on abort currently ?

Currently, none,

??? What do you mean by
o Some SETs are honored in an aborted transaction (current)
?
Is the current state different from
o All SETs are honored in an aborted transaction
?

In the case of:

BEGIN WORK;
SET x=1;
bad query that aborts transaction;
SET x=2;
COMMIT WORK;

Only the first SET is done, so at the end, x = 1. If all SET's were
honored, x = 2. If no SETs in an aborted transaction were honored, x
would equal whatever it was before the BEGIN WORK above.

IMHO
o No SETs are honored in an aborted transaction(current)

The first SET isn't done in an aborted transaction.

regards,
Hiroshi Inoue

#135Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Hiroshi Inoue (#134)
Re: timeout implementation issues

Hiroshi Inoue wrote:

??? What do you mean by
o Some SETs are honored in an aborted transaction (current)
?
Is the current state different from
o All SETs are honored in an aborted transaction
?

In the case of:

BEGIN WORK;
SET x=1;
bad query that aborts transaction;
SET x=2;
COMMIT WORK;

Only the first SET is done, so at the end, x = 1. If all SET's were
honored, x = 2. If no SETs in an aborted transaction were honored, x
would equal whatever it was before the BEGIN WORK above.

IMHO
o No SETs are honored in an aborted transaction(current)

The first SET isn't done in an aborted transaction.

Well, yes, when I say aborted transaction, I mean the entire
transaction, not just the part after the abort happens. All non-SET
commands in the transaction are rolled back already. I can't think of a
good argument for our current behavior.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#136Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Hiroshi Inoue (#134)
Re: timeout implementation issues

Hiroshi Inoue wrote:

??? What do you mean by
o Some SETs are honored in an aborted transaction (current)
?
Is the current state different from
o All SETs are honored in an aborted transaction
?

In the case of:

BEGIN WORK;
SET x=1;
bad query that aborts transaction;
SET x=2;
COMMIT WORK;

Only the first SET is done, so at the end, x = 1. If all SET's were
honored, x = 2. If no SETs in an aborted transaction were honored, x
would equal whatever it was before the BEGIN WORK above.

IMHO
o No SETs are honored in an aborted transaction(current)

The first SET isn't done in an aborted transaction.

I guess my point is that with our current code, there is a distinction
that SETs are executed before a transaction aborts, but are ignored
after a transaction aborts, even if the SETs are in the same
transaction.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#137Tom Lane
tgl@sss.pgh.pa.us
In reply to: Peter Eisentraut (#124)
Re: timeout implementation issues

Peter Eisentraut <peter_e@gmx.net> writes:

Take out a database other than PostgreSQL and do

BEGIN; -- or whatever they use; might be implicit
INSERT INTO existing_table ('legal value');
barf;
COMMIT;

The INSERT will most likely succeed. The reason is that "barf" does not
modify or access the data in the database, so it does not affect the
transactional integrity of the database.

No; this example is completely irrelevant to our discussion. The reason
that (some) other DBMSes will allow the INSERT to take effect in the
above case is that they have savepoints, and the failure of the "barf"
command only rolls back to the savepoint not to the start of the
transaction. It's a generally-acknowledged shortcoming that we don't
have savepoints ... but this has no relevance to the question of whether
SETs should be rolled back or not. If we did have savepoints then I'd
be saying that SETs should roll back to a savepoint just like everything
else.

Please note that even in those other databases, if one replaces the
COMMIT with ROLLBACK in the above scenario, the effects of the INSERT
*will* roll back. Transpose this into current Postgres, and replace
INSERT with SET, and the effects do *not* roll back. How is that a
good idea?

regards, tom lane

#138Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Tom Lane (#137)
Re: timeout implementation issues

Tom Lane wrote:

Peter Eisentraut <peter_e@gmx.net> writes:

Take out a database other than PostgreSQL and do

BEGIN; -- or whatever they use; might be implicit
INSERT INTO existing_table ('legal value');
barf;
COMMIT;

The INSERT will most likely succeed. The reason is that "barf" does not
modify or access the data in the database, so it does not affect the
transactional integrity of the database.

No; this example is completely irrelevant to our discussion. The reason

Actually, we could probably prevent transaction abort on syntax(yacc)
errors, but the other errors like mistyped table names would be hard to
prevent a rollback, so I guess we just roll back on any error.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#139Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#133)
Re: timeout implementation issues

Bruce Momjian <pgman@candle.pha.pa.us> writes:

In the case of:

BEGIN WORK;
SET x=1;
bad query that aborts transaction;
SET x=2;
COMMIT WORK;

Only the first SET is done, so at the end, x = 1.

Perhaps even more to the point:

SET x=0;
BEGIN;
SET x=1;
bad query;
SET x=2;
ROLLBACK;

Now x=1. How is this sensible?

regards, tom lane

#140Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#136)
Re: timeout implementation issues

Bruce Momjian wrote:

Hiroshi Inoue wrote:

??? What do you mean by
o Some SETs are honored in an aborted transaction (current)
?
Is the current state different from
o All SETs are honored in an aborted transaction
?

In the case of:

BEGIN WORK;
SET x=1;
bad query that aborts transaction;
SET x=2;
COMMIT WORK;

Only the first SET is done, so at the end, x = 1. If all SET's were
honored, x = 2. If no SETs in an aborted transaction were honored, x
would equal whatever it was before the BEGIN WORK above.

IMHO
o No SETs are honored in an aborted transaction(current)

The first SET isn't done in an aborted transaction.

I guess my point is that with our current code, there is a distinction
that SETs are executed before a transaction aborts, but are ignored
after a transaction aborts, even if the SETs are in the same
transaction.

Not only SET commands but also most commands are ignored
after a transaction aborts currently. SET commands are out
of transactional control but it doesn't mean they are never
ignore(rejecte)d.

regards,
Hiroshi Inoue

#141Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#138)
Re: timeout implementation issues

Bruce Momjian <pgman@candle.pha.pa.us> writes:

Actually, we could probably prevent transaction abort on syntax(yacc)
errors, but the other errors like mistyped table names would be hard to
prevent a rollback, so I guess we just roll back on any error.

I don't think that what we categorize as an error or not is very
relevant to the discussion, either. The real point is: should SET
have rollback behavior similar to other SQL commands, or not?
If we had savepoints, or ignorable syntax errors, or other frammishes
this question would still be the same.

regards, tom lane

#142Thomas Lockhart
lockhart@fourpalms.org
In reply to: Peter Eisentraut (#124)
Re: timeout implementation issues

...

Please note that even in those other databases, if one replaces the
COMMIT with ROLLBACK in the above scenario, the effects of the INSERT
*will* roll back. Transpose this into current Postgres, and replace
INSERT with SET, and the effects do *not* roll back. How is that a
good idea?

Well, as you should have concluded by now, "good" is not the same for
everyone ;)

Frankly, I've been happy with the current SET behavior, but would also
be willing to consider most of the alternatives which have been
suggested, including ones you have dismissed out of hand. Constraints
which seem to have been imposed include:

1) All commands starting with "SET" must have the same transactional
semantics. I'll agree that it might be nice for consistancy, but imho is
not absolutely required.

2) No commands which could be expected to start with "SET" will start
with some other keyword. If we do have "set class" commands which have
different transactional semantics, then we could explore alternative
syntax for specifying each category.

3) "SET" commands must respect transactions. I'm happy with the idea
that these commands are out of band and take effect immediately. And if
they take effect even in the middle of a failing/failed transaction,
that is OK too. The surrounding code would have reset the values anyway,
if necessary.

I do have a concern about how to implement some of the SET commands if
we *do* respect transactional semantics. For example, SET TIME ZONE
saves the current value of an environment variable (if available), and
would need *at least* a "before transaction" and "after transaction
started" pair of values. How would we propagate SET variables to
transaction-specific structures, clearing or resetting them later? Right
now these variables are pretty independent and can be accessed through
global storage; having transactional semantics means that the
interdependencies between different variable types in the SET handlers
may increase.

- Thomas

#143Tom Lane
tgl@sss.pgh.pa.us
In reply to: Thomas Lockhart (#142)
Re: timeout implementation issues

Thomas Lockhart <lockhart@fourpalms.org> writes:

I do have a concern about how to implement some of the SET commands if
we *do* respect transactional semantics. For example, SET TIME ZONE
saves the current value of an environment variable (if available), and
would need *at least* a "before transaction" and "after transaction
started" pair of values.

I intended for guc.c to manage this bookkeeping, thus freeing individual
modules from worrying about it. That would require us to transpose the
last few special-cased SET variables into generic GUC variables, but
I consider that a Good Thing anyway.

regards, tom lane

#144Peter Eisentraut
peter_e@gmx.net
In reply to: Thomas Lockhart (#142)
Re: timeout implementation issues

Thomas Lockhart writes:

1) All commands starting with "SET" must have the same transactional
semantics. I'll agree that it might be nice for consistancy, but imho is
not absolutely required.

This rule is already violated anyway. SET TRANSACTION ISOLATION, SET
CONSTRAINTS, SET SESSION AUTHORIZATION, and SET mostly_anything_else
already behave quite differently.

--
Peter Eisentraut peter_e@gmx.net

#145Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Tom Lane (#143)
Re: timeout implementation issues

I have added this to the TODO list, with a question mark. Hope this is
OK with everyone.

o Abort SET changes made in aborted transactions (?)

---------------------------------------------------------------------------

Tom Lane wrote:

Thomas Lockhart <lockhart@fourpalms.org> writes:

I do have a concern about how to implement some of the SET commands if
we *do* respect transactional semantics. For example, SET TIME ZONE
saves the current value of an environment variable (if available), and
would need *at least* a "before transaction" and "after transaction
started" pair of values.

I intended for guc.c to manage this bookkeeping, thus freeing individual
modules from worrying about it. That would require us to transpose the
last few special-cased SET variables into generic GUC variables, but
I consider that a Good Thing anyway.

regards, tom lane

---------------------------(end of broadcast)---------------------------
TIP 4: Don't 'kill -9' the postmaster

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#146Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#145)
Re: timeout implementation issues

Bruce Momjian <pgman@candle.pha.pa.us> writes:

I have added this to the TODO list, with a question mark. Hope this is
OK with everyone.

o Abort SET changes made in aborted transactions (?)

Actually, I was planning to make only search_path act that way, because
of all the push-back I'd gotten on applying it to other SET variables.
search_path really *has* to have it, but if there's anyone who agrees
with me about doing it for all SET vars, they didn't speak up :-(

regards, tom lane

#147Michael Loftis
mloftis@wgops.com
In reply to: Bruce Momjian (#145)
Re: timeout implementation issues

Tom Lane wrote:

Bruce Momjian <pgman@candle.pha.pa.us> writes:

I have added this to the TODO list, with a question mark. Hope this is
OK with everyone.

o Abort SET changes made in aborted transactions (?)

Actually, I was planning to make only search_path act that way, because
of all the push-back I'd gotten on applying it to other SET variables.
search_path really *has* to have it, but if there's anyone who agrees
with me about doing it for all SET vars, they didn't speak up :-(

I did and do, strongly. TRANSACTIONS are supposed to leave things as
they were before the BEGIN. It either all happens or it all doesnt'
happen. If you need soemthing inside of a transaction to go
irregardless then it shouldn't be within the transaction.

Show quoted text

regards, tom lane

#148Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#145)
Re: timeout implementation issues

Michael Loftis wrote:

Tom Lane wrote:

Bruce Momjian <pgman@candle.pha.pa.us> writes:

I have added this to the TODO list, with a question mark. Hope this is
OK with everyone.

o Abort SET changes made in aborted transactions (?)

Actually, I was planning to make only search_path act that way, because
of all the push-back I'd gotten on applying it to other SET variables.
search_path really *has* to have it, but if there's anyone who agrees
with me about doing it for all SET vars, they didn't speak up :-(

I did and do, strongly. TRANSACTIONS are supposed to leave things as
they were before the BEGIN. It either all happens or it all doesnt'
happen. If you need soemthing inside of a transaction to go
irregardless then it shouldn't be within the transaction.

Oops is this issue still living ?
I object to the TODO(why ????) strongly.
Please remove it from the TODO first and put it back
to the neutral position.

regards,
Hiroshi Inoue
http://w2422.nsk.ne.jp/~inoue/

#149Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Hiroshi Inoue (#148)
Re: timeout implementation issues

Hiroshi Inoue wrote:

Michael Loftis wrote:

Tom Lane wrote:

Bruce Momjian <pgman@candle.pha.pa.us> writes:

I have added this to the TODO list, with a question mark. Hope this is
OK with everyone.

o Abort SET changes made in aborted transactions (?)

Actually, I was planning to make only search_path act that way, because
of all the push-back I'd gotten on applying it to other SET variables.
search_path really *has* to have it, but if there's anyone who agrees
with me about doing it for all SET vars, they didn't speak up :-(

I did and do, strongly. TRANSACTIONS are supposed to leave things as
they were before the BEGIN. It either all happens or it all doesnt'
happen. If you need soemthing inside of a transaction to go
irregardless then it shouldn't be within the transaction.

Oops is this issue still living ?
I object to the TODO(why ????) strongly.
Please remove it from the TODO first and put it back
to the neutral position.

OK, how is this:

o Abort all or commit all SET changes made in an aborted transaction

Is this neutral? I don't think our current behavior is defended by anyone.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#150Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Tom Lane (#146)
Re: timeout implementation issues

Tom Lane wrote:

Bruce Momjian <pgman@candle.pha.pa.us> writes:

I have added this to the TODO list, with a question mark. Hope this is
OK with everyone.

o Abort SET changes made in aborted transactions (?)

Actually, I was planning to make only search_path act that way, because
of all the push-back I'd gotten on applying it to other SET variables.
search_path really *has* to have it, but if there's anyone who agrees
with me about doing it for all SET vars, they didn't speak up :-(

Woh, this all started because of timeout, which needs this fix too. We
certainly need something and I don't want to get into on of those "we
can't all decide, so we do nothing" situations.

I have updated the TODO to:

o Abort all or commit all SET changes made in an aborted transaction

I don't think our current behavior is defended by anyone. Is abort all
or commit all the only two choices? If so, we will take a vote and be
done with it.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#151Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#150)
Re: timeout implementation issues

Bruce Momjian <pgman@candle.pha.pa.us> writes:

I have updated the TODO to:
o Abort all or commit all SET changes made in an aborted transaction
I don't think our current behavior is defended by anyone.

Hiroshi seems to like it ...

However, "commit SETs even after an error" is most certainly NOT
acceptable. It's not even sensible --- what if the SETs themselves
throw errors, or are depending on the results of failed non-SET
commands; will you try to commit them anyway?

It seems to me that the choices we realistically have are

(a) leave the behavior the way it is

(b) cause all SETs in an aborted transaction to roll back.

regards, tom lane

#152Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Tom Lane (#151)
Re: timeout implementation issues

Tom Lane wrote:

Bruce Momjian <pgman@candle.pha.pa.us> writes:

I have updated the TODO to:
o Abort all or commit all SET changes made in an aborted transaction
I don't think our current behavior is defended by anyone.

Hiroshi seems to like it ...

However, "commit SETs even after an error" is most certainly NOT
acceptable. It's not even sensible --- what if the SETs themselves
throw errors, or are depending on the results of failed non-SET
commands; will you try to commit them anyway?

It seems to me that the choices we realistically have are

(a) leave the behavior the way it is

(b) cause all SETs in an aborted transaction to roll back.

I disagree. You commit all the SET's you can, even if in aborted
transactions. If they throw an error, or rely on a previous non-SET
that aborted, oh well. That is what some are asking for.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#153Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#150)
Re: timeout implementation issues

Tom Lane wrote:

Bruce Momjian <pgman@candle.pha.pa.us> writes:

I have updated the TODO to:
o Abort all or commit all SET changes made in an aborted transaction
I don't think our current behavior is defended by anyone.

Hiroshi seems to like it ...

Probably I don't love it. Honestly I don't understand
what the new TODO means exactly.
I don't think this is *all* *should be* or *all
or nothing* kind of thing. If a SET variable has
its reason, it would behave in its own right.

However, "commit SETs even after an error" is most certainly NOT
acceptable.

What I've meant is that SET commands are out of transactional
control and so the word *commit SETs even after* has no meaning
to me. Basically it's a user's responsisbilty to manage the
errors. He only knows what's to do with the errors.

regards,
Hiroshi Inoue
http://w2422.nsk.ne.jp/~inoue/

#154Tom Lane
tgl@sss.pgh.pa.us
In reply to: Hiroshi Inoue (#153)
Re: timeout implementation issues

Hiroshi Inoue <Inoue@tpf.co.jp> writes:

I don't think this is *all* *should be* or *all
or nothing* kind of thing. If a SET variable has
its reason, it would behave in its own right.

Well, we could provide some kind of escape hatch to let the behavior
vary from one variable to the next. But can you give any specific
examples? Which SET variables should not roll back on error?

regards, tom lane

#155Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#150)
Re: timeout implementation issues

Tom Lane wrote:

Hiroshi Inoue <Inoue@tpf.co.jp> writes:

I don't think this is *all* *should be* or *all
or nothing* kind of thing. If a SET variable has
its reason, it would behave in its own right.

Well, we could provide some kind of escape hatch to let the behavior
vary from one variable to the next. But can you give any specific
examples? Which SET variables should not roll back on error?

It seems veeery dangerous to conclude that SET *should*
roll back even if there's no *should not* roll back case.
There could be no *should not* roll back case because
a user could set the variable as he likes in the next
transaction.

Hiroshi Inoue
http://w2422.nsk.ne.jp/~inoue/

#156Michael Loftis
mloftis@wgops.com
In reply to: Bruce Momjian (#150)
Re: timeout implementation issues

Hiroshi Inoue wrote:

Tom Lane wrote:

Hiroshi Inoue <Inoue@tpf.co.jp> writes:

I don't think this is *all* *should be* or *all
or nothing* kind of thing. If a SET variable has
its reason, it would behave in its own right.

Well, we could provide some kind of escape hatch to let the behavior
vary from one variable to the next. But can you give any specific
examples? Which SET variables should not roll back on error?

It seems veeery dangerous to conclude that SET *should*
roll back even if there's no *should not* roll back case.
There could be no *should not* roll back case because
a user could set the variable as he likes in the next
transaction.

In whihc case, if I'm understanding you correctly Hiroshi-san, the
rollback is moot anyway...

IE

BEGIN transaction_1
...
SET SOMEVAR=SOMETHING
...
COMMIT

(transaction_1 fails and rolls back)

BEGIN transaction_2
...
SET SOMEVAR=SOMETHINGELSE
...
COMMIT

(transaction_2 succeeds)

SOMEVAR, in either case, assuming transaction_2 succeeds, would be
SOMETHINGELSE. If both succeed SOMEVAR is SOMETHINGELSE, if the first
succeeds and the second fails SOMEVAR will be SOMETHING. If neither
succeed SOMEVAR (for this short example) is whatever it was before the
two transactions.

Am I understanding you correctly in that this is the example you were
trying to point out?

Show quoted text

Hiroshi Inoue
http://w2422.nsk.ne.jp/~inoue/

#157Hiroshi Inoue
Inoue@tpf.co.jp
In reply to: Bruce Momjian (#150)
Re: timeout implementation issues

Michael Loftis wrote:

Hiroshi Inoue wrote:

Tom Lane wrote:

Hiroshi Inoue <Inoue@tpf.co.jp> writes:

I don't think this is *all* *should be* or *all
or nothing* kind of thing. If a SET variable has
its reason, it would behave in its own right.

Well, we could provide some kind of escape hatch to let the behavior
vary from one variable to the next. But can you give any specific
examples? Which SET variables should not roll back on error?

It seems veeery dangerous to conclude that SET *should*
roll back even if there's no *should not* roll back case.
There could be no *should not* roll back case because
a user could set the variable as he likes in the next
transaction.

In whihc case, if I'm understanding you correctly Hiroshi-san, the
rollback is moot anyway...

IE

BEGIN transaction_1
...
SET SOMEVAR=SOMETHING
...
COMMIT

(transaction_1 fails and rolls back)

Probably you are misunderstanding my point.
I don't think that SOMEVAR *should* be put back
on failure.
Users must know what value would be set to the
SOMEVAR after an error. In some cases it must
be put back, in some cases the current value
is OK, in other cases new SOMEVAR is needed.
Basically it's a user's resposibilty to set
the value.

regards,
Hiroshi Inoue
http://w2422.nsk.ne.jp/~inoue/