[BUGS] Bug #633: CASE statement evaluation does not short-circut
James Cole (colejatmsu.edu) reports a bug with a severity of 2 The lower the number the more severe it is. Short Description CASE statement evaluation does not short-circut Long Description In 7.2.1, Both the WHEN and THEN clauses of a CASE statement are evaluated, even if the WHEN clause evaluates to FALSE. (I'm not sure if this behavior is allowed by the '92 spec, but it's different than under 7.1.x) Platform info: joel2=# select version(); version -- PostgreSQL 7.2.1 on sparc-sun-solaris2.6, compiled by GCC 2.95.2 (1 row) Sample Code joel2=# SELECT CASE WHEN 1 = 2 THEN 1 / 0 WHEN 1 = 1 THEN 1.0 END; ERROR: floating point exception! The last floating point operation either exceeded legal ranges or was a divide by zero No file was uploaded with this report ---(end of broadcast)--- TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]
Re: [BUGS] 7.2 crash...
Here is a patch with a fix outlined by Tom: test=> CREATE OR REPLACE FUNCTION runMaintenance() test-> RETURNS BOOL AS ' test'> VACUUM; test'> SELECT TRUE; test'> ' LANGUAGE sql; CREATE test=> test=> select runMaintenance(); ERROR: VACUUM cannot be executed from a function Looks good. Will commit after typical delay. --- Tom Lane wrote: > "Rod Taylor" <[EMAIL PROTECTED]> writes: > > 7.2 crashes with the below function: > > CREATE OR REPLACE FUNCTION runMaintenance() > > RETURNS BOOL AS ' > > VACUUM; > > SELECT TRUE; > > ' LANGUAGE sql; > > AFAICS there is no way that we can support VACUUM inside a function; > the forced transaction commits that VACUUM performs will recycle any > memory allocated by the function executor, leading to death and > destruction upon return from VACUUM. > > Accordingly, what we really need is a way of preventing VACUUM from > executing in the above scenario. The IsTransactionBlock() test it > already has isn't sufficient. > > I have thought of something that probably would be sufficient: > > if (!MemoryContextContains(QueryContext, vacstmt)) > elog(ERROR, "VACUUM cannot be executed from a function"); > > This is truly, horribly ugly ... but it'd get the job done, because only > interactive queries will generate parsetrees in QueryContext. > > Can someone think of a better way? > > regards, tom lane > > ---(end of broadcast)--- > TIP 5: Have you checked our extensive FAQ? > > http://www.postgresql.org/users-lounge/docs/faq.html > -- 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 Index: src/backend/commands/vacuum.c === RCS file: /cvsroot/pgsql/src/backend/commands/vacuum.c,v retrieving revision 1.223 diff -c -r1.223 vacuum.c *** src/backend/commands/vacuum.c 12 Apr 2002 20:38:25 - 1.223 --- src/backend/commands/vacuum.c 14 Apr 2002 16:41:37 - *** *** 181,186 --- 181,189 if (IsTransactionBlock()) elog(ERROR, "%s cannot run inside a BEGIN/END block", stmttype); + if (!MemoryContextContains(QueryContext, vacstmt)) + elog(ERROR, "VACUUM cannot be executed from a function"); + /* * Send info about dead objects to the statistics collector */ ---(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: [BUGS] 7.2 crash...
Bruce Momjian <[EMAIL PROTECTED]> writes: > *** src/backend/commands/vacuum.c 12 Apr 2002 20:38:25 - 1.223 > --- src/backend/commands/vacuum.c 14 Apr 2002 16:41:37 - > *** > *** 181,186 > --- 181,189 > if (IsTransactionBlock()) > elog(ERROR, "%s cannot run inside a BEGIN/END block", stmttype); > + if (!MemoryContextContains(QueryContext, vacstmt)) > + elog(ERROR, "VACUUM cannot be executed from a function"); > + > /* >* Send info about dead objects to the statistics collector >*/ > --ELM1018803173-10746-0_-- Compare to immediately preceding error check. Isn't there something missing here? regards, tom lane ---(end of broadcast)--- TIP 4: Don't 'kill -9' the postmaster
Re: [BUGS] 7.2 crash...
Oops, I see now. How is this? Remember, I am not incredibly capable, just persistent. :-) --- Tom Lane wrote: > Bruce Momjian <[EMAIL PROTECTED]> writes: > > *** src/backend/commands/vacuum.c 12 Apr 2002 20:38:25 - 1.223 > > --- src/backend/commands/vacuum.c 14 Apr 2002 16:41:37 - > > *** > > *** 181,186 > > --- 181,189 > > if (IsTransactionBlock()) > > elog(ERROR, "%s cannot run inside a BEGIN/END block", stmttype); > > > + if (!MemoryContextContains(QueryContext, vacstmt)) > > + elog(ERROR, "VACUUM cannot be executed from a function"); > > + > > /* > > * Send info about dead objects to the statistics collector > > */ > > > --ELM1018803173-10746-0_-- > > Compare to immediately preceding error check. Isn't there something > missing here? > > regards, tom lane > -- 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 Index: src/backend/commands/vacuum.c === RCS file: /cvsroot/pgsql/src/backend/commands/vacuum.c,v retrieving revision 1.223 diff -c -r1.223 vacuum.c *** src/backend/commands/vacuum.c 12 Apr 2002 20:38:25 - 1.223 --- src/backend/commands/vacuum.c 14 Apr 2002 16:41:37 - *** *** 181,186 --- 181,189 if (IsTransactionBlock()) elog(ERROR, "%s cannot run inside a BEGIN/END block", stmttype); + if (!MemoryContextContains(QueryContext, vacstmt)) + elog(ERROR, "%s cannot be executed from a function", stmttype); + /* * Send info about dead objects to the statistics collector */ ---(end of broadcast)--- TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]
Re: [BUGS] Bug #633: CASE statement evaluation does not short-circut
[EMAIL PROTECTED] writes: > In 7.2.1, Both the WHEN and THEN clauses of a CASE statement are evaluated, even if >the WHEN clause evaluates to FALSE. Not in the normal case. > SELECT > CASE > WHEN 1 = 2 THEN 1 / 0 > WHEN 1 = 1 THEN 1.0 > END; > ERROR: floating point exception! The last floating point operation either exceeded >legal ranges or was a divide by zero Hmm. The reason for this is that the constant-expression simplifier reduces all the subexpressions of the CASE before it tries to discard the ones with constant-FALSE preconditions. This particular example could be fixed by rearranging the order of the simplification operations, but you'd still see a failure with, say, SELECT CASE WHEN boolCol THEN 1 / 0 END FROM table; since 1/0 will be const-folded at planning time whether the table contains any TRUE entries or not. I don't really consider this a bug; at least, fixing it would imply not const-simplifying the result expressions of CASEs, which is a cure far worse than the disease IMHO. Does anyone think we *should* allow CASE to defeat const-simplification? Are there any real-world cases (as opposed to made-up examples) where this is necessary? regards, tom lane ---(end of broadcast)--- TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]
Re: [BUGS] 7.2 crash...
Bruce Momjian <[EMAIL PROTECTED]> writes: > Oops, I see now. How is this? Better. A comment explaining what the thing is doing would help too. regards, tom lane ---(end of broadcast)--- TIP 6: Have you searched our list archives? http://archives.postgresql.org
Re: [BUGS] Bug #630: date/time storage problem: timestamp parsed
> Ugh, I'm too tired to file a gdb report: > > 1490t = mktime(tmp); > (gdb) > 1491fprintf(stderr, "%p\n", t); > (gdb) print t > $7 = -1 > > Good call Tom. ... I'm going to file a PR w/ FreeBSD. The FreeBSD folk are absolutely adamant about having mktime() no compensate for deadzones between DST shifts and they insist that the application handle this. Someone's off looking at how other OS'es handle this, but this could be an arduous battle on that front. <:~) > I know the attached patch is something of a hack, but it works. I'm > not totally wild about altering the original time object, but I > don't know that I have a choice in this case. Does anyone switch > timezones and only adjust their clocks by anything other than 60min? > I seem to recall that happening in a few places, but the patch isn't > any worse than where we are now. ::shrug:: This look like an okay > patch? Are there any objections to the following? Instead of returning 0 or utc, I could have it raise an error. Would that be acceptable? -sc > Index: src/backend/utils/adt/datetime.c > === > RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/datetime.c,v > retrieving revision 1.88 > diff -u -r1.88 datetime.c > --- src/backend/utils/adt/datetime.c 2002/02/25 16:17:04 1.88 > +++ src/backend/utils/adt/datetime.c 2002/04/10 06:12:45 > @@ -1439,6 +1439,7 @@ > DetermineLocalTimeZone(struct tm * tm) > { > int tz; > + time_t t; > > if (HasCTZSet) > tz = CTimeZone; > @@ -1463,7 +1464,23 @@ > /* indicate timezone unknown */ > tmp->tm_isdst = -1; > > - mktime(tmp); > + t = mktime(tmp); > + if (t == -1) > + { > + /* Bump time up by an hour to see if time was an > + * invalid time during a daylight savings switch */ > + tmp->tm_hour += 1; > + t = mktime(tmp); > + > + /* Assume UTC if mktime() still fails. > + * > + * If mktime() was successful with the adjusted time, > + * adjust the real time object. */ > + if (t == -1) > + return 0; > + else > + tm->tm_hour += 1; > + } > > tm->tm_isdst = tmp->tm_isdst; > -- Sean Chittenden msg03995/pgp0.pgp Description: PGP signature
Re: [BUGS] Bug #597: ResultSet.next() throws NullPointerException
This patch has been applied by someone recently. Thanks. --- [EMAIL PROTECTED] wrote: > Craig Brown ([EMAIL PROTECTED]) reports a bug with a severity of 2 > The lower the number the more severe it is. > > Short Description > ResultSet.next() throws NullPointerException > > Long Description > When invoking the next() method on a ResultSet that has been closed a >NullPointerException is thrown. Ideally, an SQLException stating that the ResultSet >has been closed should be thrown. > > This bug affects several other methods within the jdbc2/ResultSet class. > > Sample Code > This patch fixes the above described problem. > > *** ./src/interfaces/jdbc/org/postgresql/errors.properties.orig Tue Feb 19 17:54:02 >2002 > --- ./src/interfaces/jdbc/org/postgresql/errors.properties Tue Feb 19 17:49:55 >2002 > *** > *** 54,59 > --- 54,60 > postgresql.res.badshort:Bad Short {0} > postgresql.res.badtime:Bad Time {0} > postgresql.res.badtimestamp:Bad Timestamp Format at {0} in {1} > + postgresql.res.closed:The ResultSet has been closed. > postgresql.res.colname:The column name {0} not found. > postgresql.res.colrange:The column index is out of range. > postgresql.serial.interface:You cannot serialize an interface. > *** ./src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java.orig Tue Feb 19 >17:53:46 2002 > --- ./src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java Tue Feb 19 17:50:12 >2002 > *** > *** 110,115 > --- 110,118 > */ > public boolean next() throws SQLException > { > + if (rows == null) > + throw new PSQLException("postgresql.res.closed"); > + > if (++current_row >= rows.size()) > return false; > this_row = (byte [][])rows.elementAt(current_row); > *** > *** 702,707 > --- 705,713 > */ > public java.sql.ResultSetMetaData getMetaData() throws SQLException > { > + if (rows == null) > + throw new PSQLException("postgresql.res.closed"); > + > return new ResultSetMetaData(rows, fields); > } > > *** > *** 828,833 > --- 834,841 > // index is 1-based, but internally we use 0-based indices > int internalIndex; > > + if (rows == null) > + throw new PSQLException("postgresql.res.closed"); > if (index == 0) > throw new SQLException("Cannot move to index of 0"); > > *** > *** 866,871 > --- 874,882 > > public void afterLast() throws SQLException > { > + if (rows == null) > + throw new PSQLException("postgresql.res.closed"); > + > final int rows_size = rows.size(); > if (rows_size > 0) > current_row = rows_size; > *** > *** 873,878 > --- 884,892 > > public void beforeFirst() throws SQLException > { > + if (rows == null) > + throw new PSQLException("postgresql.res.closed"); > + > if (rows.size() > 0) > current_row = -1; > } > *** > *** 891,896 > --- 905,913 > > public boolean first() throws SQLException > { > + if (rows == null) > + throw new PSQLException("postgresql.res.closed"); > + > if (rows.size() <= 0) > return false; > current_row = 0; > *** > *** 1035,1040 > --- 1052,1060 > > public int getFetchSize() throws SQLException > { > + if (rows == null) > + throw new PSQLException("postgresql.res.closed"); > + > // new in 7.1: In this implementation we return the entire result >set, so > // here return the number of rows we have. Sub-classes can return a >proper > // value > *** > *** 1078,1083 > --- 1098,1106 > > public int getRow() throws SQLException > { > + if (rows == null) > + throw new PSQLException("postgresql.res.closed"); > + > final int rows_size = rows.size(); > > if (current_row < 0 || current_row >= rows_size) > *** > *** 1108,1135 > --- 1131,1173 > > public boolean isAfterLast() throws SQLException > { > + if (rows == null) > + throw new PSQLException("postgresql.res.closed"); > + > final int rows_size = rows.size(); > return (current_row >= rows_size && rows_size >