-----BEGIN PGP SIGNED MESSAGE-----
> * I think you should use PSQLexec instead of using PQexec directly. PSQLexec
> is used by all \-commands and prints out queries with -E, which is very
> helpful for debugging.
But these are not backslash commands, but almost directly analogous to the
BEGINs emitted by psql when in AutoCommit mode. On the other hand, it might
be neat to see all the savepoints psql will automagically create for you, so
I could go either way.
> * You do not check for the server version before activating \reseterror.
> -> use PQserverVersion() to check for >= 80000
Thanks, it was in an earlier version, promise. This should be in command.c:
if (pset.sversion < 80000)
fprintf(stderr, _("The server version (%d) does not support savepoints.\n"),
> * Perhaps the name should be \reseterrors (plural)? Just my personal
> opinion though.
Nah, less errors from people typing the wrong thing if we keep it shorter.
> * You have not yet implemented a way to savely put \reseterror in .psqlrc. I
> previously suggested an AUTO setting (additional to ON/OFF) that disables
> \reseterror when reading from a non-tty. So putting \reseterror AUTO in
> ..psqlrc would be save.
Hmm...I suppose we could do that. Do we have anything else that does something
similar? I guess I'm not convinced that we need to change a switch's behavior
based on the tty status.
> * If I read the code correctly, you now don't destroy user savepoints
> anymore, but on the other hand, you do not release the psql savepoint after
> a user-defined savepoint is released. In other words, each time a user
> creates a savepoint, one psql savepoint is left on the subxact stack. I
> don't know if this is a real problem, though.
Correct. More detail: we release our own temporary savepoint, unless the user
has successfully implemented their own savepoint. We need to do this so that we
do not clobber the user's savepoint. The larger problem is that "our" savepoints
and the user's savepoints tend to clobber each other. The normal flow of things
is to issue our savepoint, then the user's command, and then check to see if the
command succcessfully completed, and if we are still in a transaction. If we are
no longer in a transaction, we do nothing, as it means that our savepoint has
destroyed, so we don't need to worry about it. Otherwise, if the command failed,
we issue a rollback of our savepoint, which is guaranteed to be there because
user cannot have removed it, because their command did not succeed. Now the
part: If the transaction is still active, and the command succeeded, and the
was not SAVEPOINT, ROLLBACK TO, or RELEASE, we issue a release of our savepoint,
which is not strictly necessary, but is a good idea so we don't build up a large
chunk of old savepoints. Aside: we check if the command they issued was a
manipulating one by not parsing the SQL (yuck) but by simply checking the
string. Although there is no way to tell "RELEASE" from "RELEASE TO" from this
we know it cannot be the former because we are still in a transaction. :) If it
one of those three commands, we do not issue a release. If they issued a
release or rollback, then it just clobbered our savepoint, which now no longer
If it was a savepoint, we cannot release, or we will clobber their savepoint,
was created after ours. We could theoretically try and figure out beforehand if
they are issuing a savepoint command, but we must wrap it anyway in case it
we can rollback and not have it end the outer transaction. Thus, we create one
savepoint every time the user issues a savepoint. Until they rollback or
course, in which case they also remove an equal number of our savepoints as
savepoints. So it doubles the number of savepoints a user currently has, but
is the price we pay for having the feature.
Greg Sabino Mullane [EMAIL PROTECTED]
PGP Key: 0x14964AC8 200503070028
-----BEGIN PGP SIGNATURE-----
-----END PGP SIGNATURE-----
---------------------------(end of broadcast)---------------------------
TIP 5: Have you checked our extensive FAQ?