Re: [HACKERS] Error codes for LIMIT and OFFSET
Peter Eisentraut writes: > What should we do here, if anything? Redefine > ERRCODE_INVALID_LIMIT_VALUE to the new SQL:2008 code? If you're going to spell the errcode macros as suggested in the patch, just remove ERRCODE_INVALID_LIMIT_VALUE. Note that this patch misses at least two places where new errcodes need to be listed (plerrcodes.h and the documentation appendix) regards, tom lane -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
[HACKERS] Error codes for LIMIT and OFFSET
I was looking into adding new specific SQL:2008 error codes for invalid LIMIT and OFFSET values (see attached patch), when I came across an existing error code definition: #define ERRCODE_INVALID_LIMIT_VALUE MAKE_SQLSTATE('2','2', '0','2','0') This definition has been in our sources since error codes were first added, but I don't find this code in the standard (it uses a standard-space SQLSTATE code), and as far as I can tell, it hasn't been actually used anywhere. Except that PL/pgSQL defines it in plerrcodes.h (and Google shows that various other interfaces list it as well), but it can never happen, I think. What should we do here, if anything? Redefine ERRCODE_INVALID_LIMIT_VALUE to the new SQL:2008 code? Or remove the whole thing (assuming that no PL/pgSQL code actually referes to it)? Index: src/backend/executor/nodeLimit.c === RCS file: /cvsroot/pgsql/src/backend/executor/nodeLimit.c,v retrieving revision 1.35 diff -u -3 -p -r1.35 nodeLimit.c --- src/backend/executor/nodeLimit.c 1 Jan 2009 17:23:41 - 1.35 +++ src/backend/executor/nodeLimit.c 27 Feb 2009 11:23:13 - @@ -247,7 +247,7 @@ recompute_limits(LimitState *node) node->offset = DatumGetInt64(val); if (node->offset < 0) ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + (errcode(ERRCODE_INVALID_ROW_COUNT_IN_RESULT_OFFSET_CLAUSE), errmsg("OFFSET must not be negative"))); } } @@ -274,7 +274,7 @@ recompute_limits(LimitState *node) node->count = DatumGetInt64(val); if (node->count < 0) ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + (errcode(ERRCODE_INVALID_ROW_COUNT_IN_LIMIT_CLAUSE), errmsg("LIMIT must not be negative"))); node->noCount = false; } Index: src/include/utils/errcodes.h === RCS file: /cvsroot/pgsql/src/include/utils/errcodes.h,v retrieving revision 1.28 diff -u -3 -p -r1.28 errcodes.h --- src/include/utils/errcodes.h 1 Jan 2009 17:24:02 - 1.28 +++ src/include/utils/errcodes.h 27 Feb 2009 11:23:13 - @@ -136,6 +136,8 @@ #define ERRCODE_INVALID_LIMIT_VALUE MAKE_SQLSTATE('2','2', '0','2','0') #define ERRCODE_INVALID_PARAMETER_VALUE MAKE_SQLSTATE('2','2', '0','2','3') #define ERRCODE_INVALID_REGULAR_EXPRESSION MAKE_SQLSTATE('2','2', '0','1','B') +#define ERRCODE_INVALID_ROW_COUNT_IN_LIMIT_CLAUSE MAKE_SQLSTATE('2', '2', '0', '1', 'W') +#define ERRCODE_INVALID_ROW_COUNT_IN_RESULT_OFFSET_CLAUSE MAKE_SQLSTATE('2', '2', '0', '1', 'X') #define ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE MAKE_SQLSTATE('2','2', '0','0','9') #define ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER MAKE_SQLSTATE('2','2', '0','0','C') #define ERRCODE_MOST_SPECIFIC_TYPE_MISMATCH MAKE_SQLSTATE('2','2', '0','0','G') -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Error Codes
On Tue, Jul 06, 2004 at 01:22:35PM -0400, Bruce Momjian wrote: > David Fetter wrote: > > Kind people, > > > > So far, I have found two places where one can find the SQLSTATE > > error codes: a header file, and the errcodes-appendix doc. Those > > are excellent places. > > > > Did I miss how to get a list of them in SQL? If I missed it > > because it isn't there, what would be a good way to have a current > > list available? > > You know, it would be cool to have the codes and descriptions in a > global SQL table. I think so, too :) So, I'm looking at src/include/utils/errcodes.h in CVS tip, and I see what looks to me like two columns in a table: sqlstate (e.g. 0100C) warning (e.g. ERRCODE_WARNING_DYNAMIC_RESULT_SETS_RETURNED) this would make an excellent table to have handy. How to make sure that it is, in fact, available, and that its contents match errcodes.h? Here is a perl hack for parsing errcodes.h: #!/usr/bin/perl -wl use strict; open F, ") { chomp; next unless (/^#define\s+ERRCODE_(\S+)\s+MAKE_SQLSTATE\('(.*)'\).*$/); # print; my ($warning, $sqlstate) = ($1, $2); $warning =~ s/^ERRCODE_//; $sqlstate =~ s/\W//g; # clean up my $sql = "INSERT INTO sqlstates (sqlstate, warning) VALUES ($sqlstate, $warning);"; print $sql; # Now, do the inserts...but where? } Cheers, D -- David Fetter [EMAIL PROTECTED] http://fetter.org/ phone: +1 510 893 6100 mobile: +1 415 235 3778 Remember to vote! ---(end of broadcast)--- TIP 5: Have you checked our extensive FAQ? http://www.postgresql.org/docs/faqs/FAQ.html
Re: [HACKERS] Error Codes
David Fetter wrote: > Kind people, > > So far, I have found two places where one can find the SQLSTATE error > codes: a header file, and the errcodes-appendix doc. Those are > excellent places. > > Did I miss how to get a list of them in SQL? If I missed it because > it isn't there, what would be a good way to have a current list > available? You know, it would be cool to have the codes and descriptions in a global SQL table. -- Bruce Momjian| http://candle.pha.pa.us [EMAIL PROTECTED] | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup.| Newtown Square, Pennsylvania 19073 ---(end of broadcast)--- TIP 2: you can get off all lists at once with the unregister command (send "unregister YourEmailAddressHere" to [EMAIL PROTECTED])
[HACKERS] Error Codes
Kind people, So far, I have found two places where one can find the SQLSTATE error codes: a header file, and the errcodes-appendix doc. Those are excellent places. Did I miss how to get a list of them in SQL? If I missed it because it isn't there, what would be a good way to have a current list available? TIA for brickbats, comments, &c. :) Cheers, D -- David Fetter [EMAIL PROTECTED] http://fetter.org/ phone: +1 510 893 6100mobile: +1 415 235 3778 Before you try to play the history card, make sure it's in your hand. ---(end of broadcast)--- TIP 8: explain analyze is your friend
Re: [HACKERS] Error codes revisited
> > Given the repeatedly-asked-for functionalities (like error codes) > for which the stopper has been the long-threatened protocol revision, > I'd think it might be boring, but would hardly be thankless. Heck, I'd > expect a few whoops of joy around the lists. > Yes. Error codes would be great. Regards, Christoph ---(end of broadcast)--- TIP 2: you can get off all lists at once with the unregister command (send "unregister YourEmailAddressHere" to [EMAIL PROTECTED])
Re: [HACKERS] Error codes revisited
On Tue, Mar 04, 2003 at 11:04:03PM -0500, Tom Lane wrote: > > There is still barely enough time to do the long-threatened protocol > revision for 7.4, if we suck it up and get started on that now. I've > been avoiding the issue myself, because it seems generally boring and > thankless work, but maybe it's time to face up to it? Given the repeatedly-asked-for functionalities (like error codes) for which the stopper has been the long-threatened protocol revision, I'd think it might be boring, but would hardly be thankless. Heck, I'd expect a few whoops of joy around the lists. Ross ---(end of broadcast)--- TIP 4: Don't 'kill -9' the postmaster
Re: [HACKERS] Error codes revisited
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 > The *last* thing we need is a half-baked stopgap solution that we'll > have to be backwards-compatible with forevermore. Fix it right or > don't do it at all, is MHO. I agree. > There is still barely enough time to do the long-threatened protocol > revision for 7.4, if we suck it up and get started on that now. I've > been avoiding the issue myself, because it seems generally boring and > thankless work, but maybe it's time to face up to it? Definitely. Sure seems to be a lot involved, looking at the TODO page. Which brings up another question - if a protocol change doesn't warrant a bump to 8.0, what does? :) - -- Greg Sabino Mullane [EMAIL PROTECTED] PGP Key: 0x14964AC8 200303040645 -BEGIN PGP SIGNATURE- Comment: http://www.turnstep.com/pgp.html iD8DBQE+ZC1LvJuQZxSWSsgRAkJLAKDUE54ZELrPc4ASqEtwUCk7CYJH/ACfZ7nQ bLRqMde1T9MDjzmejF+PBis= =Plww -END PGP SIGNATURE- ---(end of broadcast)--- TIP 3: if posting/reading through Usenet, please send an appropriate subscribe-nomail command to [EMAIL PROTECTED] so that your message can get through to the mailing list cleanly
Re: [HACKERS] Error codes revisited
[EMAIL PROTECTED] writes: > What about a variable that allowed the codes to be switched on so a > number is returned instead of a string? This would be off by default > so as not to break existing applications. Similarly, we can return > other information (FILE, LINE, etc.) with different variables. This > should all be doable without a protocol change, as long as everything > is returned as a string in a standard format. The *last* thing we need is a half-baked stopgap solution that we'll have to be backwards-compatible with forevermore. Fix it right or don't do it at all, is MHO. There is still barely enough time to do the long-threatened protocol revision for 7.4, if we suck it up and get started on that now. I've been avoiding the issue myself, because it seems generally boring and thankless work, but maybe it's time to face up to it? regards, tom lane ---(end of broadcast)--- TIP 4: Don't 'kill -9' the postmaster
[HACKERS] Error codes revisited
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 As promised, I've been looking over the error handling (especially the archived discussions) and it's a real rat's nest. :) I'm not sure where we should start, but just getting some error codes enabled and out there would be a great start. The protocol changes can come later. And the codes should not be part of the string. What about a variable that allowed the codes to be switched on so a number is returned instead of a string? This would be off by default so as not to break existing applications. Similarly, we can return other information (FILE, LINE, etc.) with different variables. This should all be doable without a protocol change, as long as everything is returned as a string in a standard format. - -- Greg Sabino Mullane [EMAIL PROTECTED] PGP Key: 0x14964AC8 200303041516 -BEGIN PGP SIGNATURE- Comment: http://www.turnstep.com/pgp.html iD8DBQE+ZQo2vJuQZxSWSsgRAiKiAKDImuVDD5v4mvY1ClrTo9YrYFlDogCgwz1C Q/DS7rHZ2XWCPuZd8oQoVeA= =ixmb -END PGP SIGNATURE- ---(end of broadcast)--- TIP 4: Don't 'kill -9' the postmaster
Re: [HACKERS] error codes
Insisting on Andreas suggestion, why can't we just prefix all error message strings with the SQLState code? So all error messages would have the format CCSSS - Where CCSSS is the standard SQLState code and the message text is a more specific description. Note that the standard allows for implementation-defined codes, so we can have our own CC classes and all the SSS subclasses that we need. -- Fernando Nasser Red Hat - Toronto E-Mail: [EMAIL PROTECTED] 2323 Yonge Street, Suite #300 Toronto, Ontario M4P 2C9 ---(end of broadcast)--- TIP 6: Have you searched our list archives? http://archives.postgresql.org
Re: [HACKERS] error codes
Bruce wrote: > Actual error code numbers/letters. I think the new elog levels will > help with this. We have to decide if we want error numbers, or some > pneumonic like NOATTR or CONSTVIOL. I suggest the latter. Since there is an actual standard for error codes, I would strongly suggest to adhere. The standardized codes are SQLSTATE a char(5) (well standardized for many classes of db errors). Also common, but not so standardized is SQLCODE a long (only a very few are standardized, like 100 = 'no data found'). And also sqlca. Also look at ecpg for sqlcode and sqlca. A Quote from dec rdb: o SQLCODE-This is the original SQL error handling mechanism. It is an integer value. SQLCODE differentiates among errors (negative numbers), warnings (positive numbers), succesful completion (0), and a special code of 100, which means no data. SQLCODE is a deprecated feature of the ANSI/ISO SQL standard. o SQLCA-This is an extension of the SQLCODE error handling mechanism. It contains other context information that supplements the SQLCODE value. SQLCA is not part of the ANSI/ISO SQL standard. However, many foreign databases such as DB2 and ORACLE RDBMS have defined proprietary semantics and syntax to implement it. o SQLSTATE-This is the error handling mechanism for the ANSI/ISO SQL standard. The SQLSTATE value is a character string that is associated with diagnostic information. To use the SQLSTATE status parameter, you must specify the SQL92 dialect and compile your module using DEC Rdb Version 6.0. Andreas ---(end of broadcast)--- TIP 4: Don't 'kill -9' the postmaster
Re: [HACKERS] error codes
> Should every elog() have an error code? I'm not sure -- there are many > elog() calls that will never been seen by the user, since the error > they represent will be caught before control reaches the elog (e.g. > parse errors, internal consistency checks, multiple elog(ERROR) > for the same user error, etc.) Perhaps for those error messages > that don't have numbers, we could just give them ERRNO_UNKNOWN or > a similar constant. It might be cool to a little command utility "pg_error" or whatever that you pass an error code to and it prints out a very detailed description of the problem... Chris ---(end of broadcast)--- TIP 6: Have you searched our list archives? http://archives.postgresql.org
Re: [HACKERS] error codes
Neil Conway writes: > I'd like to implement error codes. I think they would be pretty useful, > although there are a few difficulties in the implementation I'd like > to get some input on. OK, allow me to pass on to you the accumulated wisdom on this topic. :-) > Should every elog() have an error code? The set of error codes should primarily be that defined by SQL99 part 2 clause 22 "Status codes" and PostgreSQL extensions that follow that spirit. That means that all those "can't happen" or "all is lost anyway" types should be lumped (perhaps in some implicit way) under "internal error". That means, yes, an error code should be returned in every case of an error, but it doesn't have to be a distinct error code for every condition. > How should the backend code signal an error with an error number? > The problem here is that many errors will require more information > that that, in order for the client to handle them properly. For > example, how should a COPY indicate that an RI violation has > occured? Ideally, we'd like to allow the client application to > know that in line a, column b, the literal value 'c' was > not found in the referenced column d of the referenced table d. Precisely. You will find that SQL99 part 2 clause 19 "Diagnostics management" defines all the fields that form part of a diagnostic (i.e., error or notice). This includes for example, fields that contain the name and schema of the table that was involved, if appropriate. (Again, appropriate PostgreSQL extensions could be made.) It is recommendable that this scheme be followed, so PL/pgSQL and ECPG, to name some candidates, could implement the GET DIAGNOSTICS statement as in the standard. (Notice that, for example, a diagnostic still contains a text message in addition to a code.) > How should the error number be sent to the client, and would this > require an FE/BE change? I think we can avoid that: including the > error number in the error message itself, make PQgetErrorMessage() > (and similar funcs) smart enough to remove the error number, and > add a separate function (such as PQgetErrorNumber() ) to report > the error number, if there is one. I would advise against trying to cram everything into a string. Consider the extra fields explained above. Consider being nice to old clients. Also, libpq allows that more than one error message might arrive per query cycle. Currently, the error messages are concatenated. That won't work anymore. You need a new API anyway. You need a new API for notices, too. One possiblity to justify a protocol change is to break something else with it, like a new copy protocol. > On a related note, it would be nice to get a consistent style of > punctuation for elog() messages -- currently, some of them end > in a period (e.g. "Database xxx does not exist in the system > catalog."), while the majority do not. Which is better? Yup, we've talked about that some time ago. I have a style guide mostly worked out for discussion. > It would be relatively easy to replace elog() with a macro of > the form: > > #define elog(...) real_elog(__FILE__, __LINE__, __VA_ARGS__) > > And then adjust real_elog() to report that information as > appropriate. And it would be relatively easy to break every old compiler that way... -- Peter Eisentraut [EMAIL PROTECTED] ---(end of broadcast)--- TIP 6: Have you searched our list archives? http://archives.postgresql.org
Re: [HACKERS] error codes
Neil, attached are three email messages dealing with error message wording. I like Tom's idea of coding only the messages that are common/user errors and leaving the others with a catch-all code. We now have more elog levels in 7.3, so it should be easier to classify the messages. I can see this job as several parts: --- Cleanup of error wording, removal of function names. See attached emails for possible standard. --- Reporting of file, line, function reporting using GUC/SET variable. For function names I see in the gcc 3.1 docs at http://gcc.gnu.org/onlinedocs/gcc-3.1/cpp/Standard-Predefined-Macros.html: C99 introduces __func__, and GCC has provided __FUNCTION__ for a long time. Both of these are strings containing the name of the current function (there are slight semantic differences; see the GCC manual). Neither of them is a macro; the preprocessor does not know the name of the current function. They tend to be useful in conjunction with __FILE__ and __LINE__, though. My gcc 2.95 (gcc version 2.95.2 19991024) supports both __FUNCTION__ and __func__, even though they are not documented in the info manual pages I have. I think we will need a configure.in test for this because it isn't a macro you can #ifdef. --- Actual error code numbers/letters. I think the new elog levels will help with this. We have to decide if we want error numbers, or some pneumonic like NOATTR or CONSTVIOL. I suggest the latter. --- I think we have plenty of time to get this done for 7.3. -- Bruce Momjian| http://candle.pha.pa.us [EMAIL PROTECTED] | (610) 853-3000 + If your life is a hard drive, | 830 Blythe Avenue + Christ can be your backup.| Drexel Hill, Pennsylvania 19026 >From [EMAIL PROTECTED] Fri Nov 30 >12:14:19 2001 Return-path: <[EMAIL PROTECTED]> Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fAUIEIR21802 for <[EMAIL PROTECTED]>; Fri, 30 Nov 2001 13:14:18 -0500 (EST) Received: from postgresql.org (postgresql.org [64.49.215.8]) by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fAUI6ER13094 for <[EMAIL PROTECTED]>; Fri, 30 Nov 2001 12:11:00 -0600 (CST) (envelope-from [EMAIL PROTECTED]) Received: from moutvdom01.kundenserver.de (moutvdom01.kundenserver.de [195.20.224.200]) by postgresql.org (8.11.3/8.11.4) with ESMTP id fAUI58m98870 for <[EMAIL PROTECTED]>; Fri, 30 Nov 2001 13:05:08 -0500 (EST) (envelope-from [EMAIL PROTECTED]) Received: from [195.20.224.208] (helo=mrvdom01.schlund.de) by moutvdom01.kundenserver.de with esmtp (Exim 2.12 #2) id 169s27-00049P-00 for [EMAIL PROTECTED]; Fri, 30 Nov 2001 19:05:07 +0100 Received: from p3e9e6fa2.dip0.t-ipconnect.de ([62.158.111.162]) by mrvdom01.schlund.de with esmtp (Exim 2.12 #2) id 169s21-0001UP-00 for [EMAIL PROTECTED]; Fri, 30 Nov 2001 19:05:03 +0100 Date: Fri, 30 Nov 2001 19:12:16 +0100 (CET) From: Peter Eisentraut <[EMAIL PROTECTED]> X-Sender: <[EMAIL PROTECTED]> To: PostgreSQL Development <[EMAIL PROTECTED]> Subject: [HACKERS] Backend error message style issues Message-ID: <[EMAIL PROTECTED]> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Precedence: bulk Sender: [EMAIL PROTECTED] Status: ORr Now that we've gone through nearly one development cycle with national language support, I'd like to bring up a number of issues concerning the style of the backend error messages that make life difficult, but probably not only for the translators but for users as well. Not all of these are strictly translation issues, but the message catalogs make for a good overview of what's going on. I hope we can work through all of these during the next development period. Prefixing messages with command names - For instance, | CREATE DATABASE: permission denied This "command: message" style is typical for command-line programs and it's pretty useful there if you run many commands in a pipe. The same usefulness could probably be derived if you run many SQL commands in a function. (Just "permission denied" would be very confusing there!) If we want to use that style we should make it consistent and we should automate it. Via the "command tag" mechanism we already know what command we're executing, so we can automatically prefix all messages that way. It could even be switched off by the user if it's deemed annoying. Prefixing messages with function names -- The function names obvi
Re: [HACKERS] error codes
On Wed, Jul 17, 2002 at 03:57:56PM -0400, Tom Lane wrote: > [EMAIL PROTECTED] (Neil Conway) writes: > > Should every elog() have an error code? > > I believe we decided that it'd be okay to use one or two codes defined > like "internal error", "corrupted data", etc for all the elogs that are > not-supposed-to-happen conditions. Ok, makes sense to me. > > How should the backend code signal an error with an error number? > > Please read some of the archived discussions about this. All the points > you mention have been brought up before. Woops -- I wasn't aware that this had been discussed before, my apologies. I'm reading the archives now... Peter: are you planning to implement this? Cheers, Neil -- Neil Conway <[EMAIL PROTECTED]> PGP Key ID: DB3C29FC ---(end of broadcast)--- TIP 2: you can get off all lists at once with the unregister command (send "unregister YourEmailAddressHere" to [EMAIL PROTECTED])
Re: [HACKERS] error codes
[EMAIL PROTECTED] (Neil Conway) writes: > Should every elog() have an error code? I believe we decided that it'd be okay to use one or two codes defined like "internal error", "corrupted data", etc for all the elogs that are not-supposed-to-happen conditions. What error codes are really for is distinguishing different kinds of user mistakes, and so that's where you need specificness. > How should the backend code signal an error with an error number? Please read some of the archived discussions about this. All the points you mention have been brought up before. regards, tom lane ---(end of broadcast)--- TIP 5: Have you checked our extensive FAQ? http://www.postgresql.org/users-lounge/docs/faq.html
[HACKERS] error codes
I'd like to implement error codes. I think they would be pretty useful, although there are a few difficulties in the implementation I'd like to get some input on. Should every elog() have an error code? I'm not sure -- there are many elog() calls that will never been seen by the user, since the error they represent will be caught before control reaches the elog (e.g. parse errors, internal consistency checks, multiple elog(ERROR) for the same user error, etc.) Perhaps for those error messages that don't have numbers, we could just give them ERRNO_UNKNOWN or a similar constant. How should the backend code signal an error with an error number? Perhaps we could report errors with error numbers via a separate function, which would take the error number as its only param. For example: error(ERRNO_REF_INT_VIOLATION); The problem here is that many errors will require more information that that, in order for the client to handle them properly. For example, how should a COPY indicate that an RI violation has occured? Ideally, we'd like to allow the client application to know that in line a, column b, the literal value 'c' was not found in the referenced column d of the referenced table d. How should the error number be sent to the client, and would this require an FE/BE change? I think we can avoid that: including the error number in the error message itself, make PQgetErrorMessage() (and similar funcs) smart enough to remove the error number, and add a separate function (such as PQgetErrorNumber() ) to report the error number, if there is one. On a related note, it would be nice to get a consistent style of punctuation for elog() messages -- currently, some of them end in a period (e.g. "Database xxx does not exist in the system catalog."), while the majority do not. Which is better? Also, I think it was Bruce who mentioned that it would be nice to add function names, source files, and/or line numbers to error messages, instead of the current inconsistent method of sometimes specifying the function name in the elog() message. Would this be a good idea? Should all errors include this information? It would be relatively easy to replace elog() with a macro of the form: #define elog(...) real_elog(__FILE__, __LINE__, __VA_ARGS__) And then adjust real_elog() to report that information as appropriate. Cheers, Neil -- Neil Conway <[EMAIL PROTECTED]> PGP Key ID: DB3C29FC ---(end of broadcast)--- TIP 2: you can get off all lists at once with the unregister command (send "unregister YourEmailAddressHere" to [EMAIL PROTECTED])