-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 > * 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"), pset.sversion); } > * 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 been 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 the user cannot have removed it, because their command did not succeed. Now the tricky part: If the transaction is still active, and the command succeeded, and the command 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 savepoint- manipulating one by not parsing the SQL (yuck) but by simply checking the cmdResult string. Although there is no way to tell "RELEASE" from "RELEASE TO" from this check, we know it cannot be the former because we are still in a transaction. :) If it was one of those three commands, we do not issue a release. If they issued a successful release or rollback, then it just clobbered our savepoint, which now no longer exists. If it was a savepoint, we cannot release, or we will clobber their savepoint, which 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 fails so we can rollback and not have it end the outer transaction. Thus, we create one extra savepoint every time the user issues a savepoint. Until they rollback or release, of course, in which case they also remove an equal number of our savepoints as their savepoints. So it doubles the number of savepoints a user currently has, but this is the price we pay for having the feature. - -- Greg Sabino Mullane [EMAIL PROTECTED] PGP Key: 0x14964AC8 200503070028 http://biglumber.com/x/web?pk=2529DF6AB8F79407E94445B4BC9B906714964AC8 -----BEGIN PGP SIGNATURE----- iD8DBQFCK+a6vJuQZxSWSsgRAsGRAJ99vJ0Mlzzl8MWBv262K//h0NasLwCgiBHZ o2tgPvfwHR8zSJ1TAJ5/x30= =itOf -----END PGP SIGNATURE----- ---------------------------(end of broadcast)--------------------------- TIP 5: Have you checked our extensive FAQ? http://www.postgresql.org/docs/faq