diff --git a/h2/src/docsrc/html/changelog.html b/h2/src/docsrc/html/changelog.html
index 09fbd1e921..56c4b60399 100644
--- a/h2/src/docsrc/html/changelog.html
+++ b/h2/src/docsrc/html/changelog.html
@@ -21,6 +21,8 @@
Change Log
Next Version (unreleased)
+- Issue #3981: Unexpected result when using trigonometric functions
+
- Issue #3983: INVISIBLE columns should be ignored in INSERT statement without explicit column list
- Issue #3960: NullPointerException when executing batch insert
diff --git a/h2/src/main/org/h2/expression/function/MathFunction1.java b/h2/src/main/org/h2/expression/function/MathFunction1.java
index f48b0d5026..38b51cae95 100644
--- a/h2/src/main/org/h2/expression/function/MathFunction1.java
+++ b/h2/src/main/org/h2/expression/function/MathFunction1.java
@@ -156,9 +156,15 @@ public Value getValue(SessionLocal session) {
d = Math.tanh(d);
break;
case ASIN:
+ if (d < -1d || d > 1d) {
+ throw DbException.getInvalidValueException("ASIN() argument", d);
+ }
d = Math.asin(d);
break;
case ACOS:
+ if (d < -1d || d > 1d) {
+ throw DbException.getInvalidValueException("ACOS() argument", d);
+ }
d = Math.acos(d);
break;
case ATAN:
diff --git a/h2/src/main/org/h2/index/RangeIndex.java b/h2/src/main/org/h2/index/RangeIndex.java
index 1be84a25f8..9a9c87eadc 100644
--- a/h2/src/main/org/h2/index/RangeIndex.java
+++ b/h2/src/main/org/h2/index/RangeIndex.java
@@ -95,8 +95,9 @@ public Cursor findFirstOrLast(SessionLocal session, boolean first) {
if (step == 0L) {
throw DbException.get(ErrorCode.STEP_SIZE_MUST_NOT_BE_ZERO);
}
- return new SingleRowCursor((step > 0 ? min <= max : min >= max)
- ? Row.get(new Value[]{ ValueBigint.get(first ^ min >= max ? min : max) }, 1) : null);
+ return (step > 0 ? min <= max : min >= max)
+ ? new SingleRowCursor(Row.get(new Value[] { ValueBigint.get(first ^ min >= max ? min : max) }, 1))
+ : SingleRowCursor.EMPTY;
}
@Override
diff --git a/h2/src/main/org/h2/index/SingleRowCursor.java b/h2/src/main/org/h2/index/SingleRowCursor.java
index f7e1cacc0a..c24c886a60 100644
--- a/h2/src/main/org/h2/index/SingleRowCursor.java
+++ b/h2/src/main/org/h2/index/SingleRowCursor.java
@@ -13,6 +13,12 @@
* A cursor with at most one row.
*/
public class SingleRowCursor implements Cursor {
+
+ /**
+ * An empty cursor.
+ */
+ public static final SingleRowCursor EMPTY = new SingleRowCursor(null);
+
private Row row;
private boolean end;
diff --git a/h2/src/main/org/h2/mvstore/db/MVPrimaryIndex.java b/h2/src/main/org/h2/mvstore/db/MVPrimaryIndex.java
index e1d0190e6f..31cffcf3d3 100644
--- a/h2/src/main/org/h2/mvstore/db/MVPrimaryIndex.java
+++ b/h2/src/main/org/h2/mvstore/db/MVPrimaryIndex.java
@@ -5,6 +5,7 @@
*/
package org.h2.mvstore.db;
+import java.math.BigDecimal;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicLong;
@@ -29,8 +30,8 @@
import org.h2.table.IndexColumn;
import org.h2.table.TableFilter;
import org.h2.value.Value;
+import org.h2.value.ValueDecfloat;
import org.h2.value.ValueLob;
-import org.h2.value.ValueNull;
import org.h2.value.VersionedValue;
/**
@@ -230,31 +231,101 @@ private Row lockRow(TransactionMap map, long key, int timeoutMil
@Override
public Cursor find(SessionLocal session, SearchRow first, SearchRow last) {
- long min = extractPKFromRow(first, Long.MIN_VALUE);
- long max = extractPKFromRow(last, Long.MAX_VALUE);
- return find(session, min, max);
- }
-
- private long extractPKFromRow(SearchRow row, long defaultValue) {
- long result;
- if (row == null) {
- result = defaultValue;
- } else if (mainIndexColumn == SearchRow.ROWID_INDEX) {
- result = row.getKey();
+ Long min, max;
+ Value v;
+ if (first == null) {
+ min = null;
+ } else if (mainIndexColumn == SearchRow.ROWID_INDEX || (v = first.getValue(mainIndexColumn)) == null) {
+ min = first.getKey();
} else {
- Value v = row.getValue(mainIndexColumn);
- if (v == null) {
- result = row.getKey();
- } else if (v == ValueNull.INSTANCE) {
- result = 0L;
- } else {
- result = v.getLong();
+ switch (v.getValueType()) {
+ case Value.NULL:
+ return SingleRowCursor.EMPTY;
+ case Value.REAL:
+ case Value.DOUBLE: {
+ double d = v.getDouble();
+ if (Double.isNaN(d)) {
+ return SingleRowCursor.EMPTY;
+ } else {
+ min = (long) d;
+ }
+ break;
+ }
+ case Value.DECFLOAT:
+ if (!((ValueDecfloat) v).isFinite()) {
+ if (v == ValueDecfloat.NEGATIVE_INFINITY) {
+ min = null;
+ } else {
+ return SingleRowCursor.EMPTY;
+ }
+ break;
+ }
+ //$FALL-THROUGH$
+ case Value.NUMERIC: {
+ BigDecimal bd = v.getBigDecimal();
+ if (bd.compareTo(Value.MAX_LONG_DECIMAL) > 0) {
+ return SingleRowCursor.EMPTY;
+ } else if (bd.compareTo(Value.MIN_LONG_DECIMAL) < 0) {
+ min = null;
+ } else {
+ min = bd.longValue();
+ }
+ break;
+ }
+ default:
+ min = v.getLong();
}
}
- return result;
+ if (last == null) {
+ max = null;
+ } else if (mainIndexColumn == SearchRow.ROWID_INDEX || (v = last.getValue(mainIndexColumn)) == null) {
+ max = last.getKey();
+ } else {
+ switch (v.getValueType()) {
+ case Value.NULL:
+ return SingleRowCursor.EMPTY;
+ case Value.REAL:
+ case Value.DOUBLE: {
+ double d = v.getDouble();
+ if (Double.isNaN(d)) {
+ max = null;
+ } else {
+ max = (long) d;
+ }
+ break;
+ }
+ case Value.DECFLOAT:
+ if (!((ValueDecfloat) v).isFinite()) {
+ if (v == ValueDecfloat.NEGATIVE_INFINITY) {
+ return SingleRowCursor.EMPTY;
+ } else {
+ max = null;
+ }
+ break;
+ }
+ //$FALL-THROUGH$
+ case Value.NUMERIC: {
+ BigDecimal bd = v.getBigDecimal();
+ if (bd.compareTo(Value.MAX_LONG_DECIMAL) > 0) {
+ max = null;
+ } else if (bd.compareTo(Value.MIN_LONG_DECIMAL) < 0) {
+ return SingleRowCursor.EMPTY;
+ } else {
+ max = bd.longValue();
+ }
+ break;
+ }
+ default:
+ max = v.getLong();
+ }
+ }
+ TransactionMap map = getMap(session);
+ if (min != null && max != null && min.longValue() == max.longValue()) {
+ return new SingleRowCursor(setRowKey((Row) map.getFromSnapshot(min), min));
+ }
+ return new MVStoreCursor(map.entryIterator(min, max));
}
-
@Override
public MVTable getTable() {
return mvTable;
@@ -319,7 +390,8 @@ public boolean canGetFirstOrLast() {
public Cursor findFirstOrLast(SessionLocal session, boolean first) {
TransactionMap map = getMap(session);
Entry entry = first ? map.firstEntry() : map.lastEntry();
- return new SingleRowCursor(entry != null ? setRowKey((Row) entry.getValue(), entry.getKey()) : null);
+ return entry != null ? new SingleRowCursor(setRowKey((Row) entry.getValue(), entry.getKey()))
+ : SingleRowCursor.EMPTY;
}
@Override
@@ -360,14 +432,6 @@ public void addBufferedRows(List bufferNames) {
throw new UnsupportedOperationException();
}
- private Cursor find(SessionLocal session, Long first, Long last) {
- TransactionMap map = getMap(session);
- if (first != null && last != null && first.longValue() == last.longValue()) {
- return new SingleRowCursor(setRowKey((Row) map.getFromSnapshot(first), first));
- }
- return new MVStoreCursor(map.entryIterator(first, last));
- }
-
@Override
public boolean isRowIdIndex() {
return true;
diff --git a/h2/src/main/org/h2/mvstore/db/MVSecondaryIndex.java b/h2/src/main/org/h2/mvstore/db/MVSecondaryIndex.java
index 7416406686..7675522562 100644
--- a/h2/src/main/org/h2/mvstore/db/MVSecondaryIndex.java
+++ b/h2/src/main/org/h2/mvstore/db/MVSecondaryIndex.java
@@ -334,7 +334,7 @@ public Cursor findFirstOrLast(SessionLocal session, boolean first) {
return new SingleRowCursor(mvTable.getRow(session, key.getKey()));
}
}
- return new SingleRowCursor(null);
+ return SingleRowCursor.EMPTY;
}
@Override
diff --git a/h2/src/main/org/h2/res/help.csv b/h2/src/main/org/h2/res/help.csv
index ffc91e508a..9337d97931 100644
--- a/h2/src/main/org/h2/res/help.csv
+++ b/h2/src/main/org/h2/res/help.csv
@@ -4845,8 +4845,10 @@ ABS(CAST(I AS BIGINT))
ACOS(numeric)
","
Calculate the arc cosine.
-See also Java ""Math.acos"".
-This method returns a double.
+
+Argument must be between -1 and 1 inclusive.
+
+This function returns a double precision value.
","
ACOS(D)
"
@@ -4855,8 +4857,10 @@ ACOS(D)
ASIN(numeric)
","
Calculate the arc sine.
-See also Java ""Math.asin"".
-This method returns a double.
+
+Argument must be between -1 and 1 inclusive.
+
+This function returns a double precision value.
","
ASIN(D)
"
@@ -4865,8 +4869,8 @@ ASIN(D)
ATAN(numeric)
","
Calculate the arc tangent.
-See also Java ""Math.atan"".
-This method returns a double.
+
+This function returns a double precision value.
","
ATAN(D)
"
@@ -4875,8 +4879,8 @@ ATAN(D)
COS(numeric)
","
Calculate the trigonometric cosine.
-See also Java ""Math.cos"".
-This method returns a double.
+
+This function returns a double precision value.
","
COS(ANGLE)
"
@@ -4885,8 +4889,8 @@ COS(ANGLE)
COSH(numeric)
","
Calculate the hyperbolic cosine.
-See also Java ""Math.cosh"".
-This method returns a double.
+
+This function returns a double precision value.
","
COSH(X)
"
@@ -4895,8 +4899,8 @@ COSH(X)
@h2@ COT(numeric)
","
Calculate the trigonometric cotangent (""1/TAN(ANGLE)"").
-See also Java ""Math.*"" functions.
-This method returns a double.
+
+This function returns a double precision value.
","
COT(ANGLE)
"
@@ -4905,8 +4909,8 @@ COT(ANGLE)
SIN(numeric)
","
Calculate the trigonometric sine.
-See also Java ""Math.sin"".
-This method returns a double.
+
+This function returns a double precision value.
","
SIN(ANGLE)
"
@@ -4915,8 +4919,8 @@ SIN(ANGLE)
SINH(numeric)
","
Calculate the hyperbolic sine.
-See also Java ""Math.sinh"".
-This method returns a double.
+
+This function returns a double precision value.
","
SINH(ANGLE)
"
@@ -4925,8 +4929,8 @@ SINH(ANGLE)
TAN(numeric)
","
Calculate the trigonometric tangent.
-See also Java ""Math.tan"".
-This method returns a double.
+
+This function returns a double precision value.
","
TAN(ANGLE)
"
@@ -4935,8 +4939,8 @@ TAN(ANGLE)
TANH(numeric)
","
Calculate the hyperbolic tangent.
-See also Java ""Math.tanh"".
-This method returns a double.
+
+This function returns a double precision value.
","
TANH(X)
"
@@ -4945,8 +4949,8 @@ TANH(X)
@h2@ ATAN2(numeric, numeric)
","
Calculate the angle when converting the rectangular coordinates to polar coordinates.
-See also Java ""Math.atan2"".
-This method returns a double.
+
+This function returns a double precision value.
","
ATAN2(X, Y)
"
diff --git a/h2/src/main/org/h2/value/Value.java b/h2/src/main/org/h2/value/Value.java
index b483e142db..ad911cea7b 100644
--- a/h2/src/main/org/h2/value/Value.java
+++ b/h2/src/main/org/h2/value/Value.java
@@ -378,10 +378,13 @@ public abstract class Value extends VersionedValue implements HasSQL, Typ
private static SoftReference softCache;
- static final BigDecimal MAX_LONG_DECIMAL = BigDecimal.valueOf(Long.MAX_VALUE);
+ /**
+ * The largest BIGINT value, as a BigDecimal.
+ */
+ public static final BigDecimal MAX_LONG_DECIMAL = BigDecimal.valueOf(Long.MAX_VALUE);
/**
- * The smallest Long value, as a BigDecimal.
+ * The smallest BIGINT value, as a BigDecimal.
*/
public static final BigDecimal MIN_LONG_DECIMAL = BigDecimal.valueOf(Long.MIN_VALUE);
diff --git a/h2/src/test/org/h2/test/db/TestTableEngines.java b/h2/src/test/org/h2/test/db/TestTableEngines.java
index df42e92b0b..4b190f3015 100644
--- a/h2/src/test/org/h2/test/db/TestTableEngines.java
+++ b/h2/src/test/org/h2/test/db/TestTableEngines.java
@@ -1007,8 +1007,8 @@ public boolean canGetFirstOrLast() {
@Override
public Cursor findFirstOrLast(SessionLocal session, boolean first) {
- return new SingleRowCursor((Row)
- (set.isEmpty() ? null : first ? set.first() : set.last()));
+ return set.isEmpty() ? SingleRowCursor.EMPTY
+ : new SingleRowCursor((Row) (first ? set.first() : set.last()));
}
@Override
diff --git a/h2/src/test/org/h2/test/scripts/functions/numeric/acos.sql b/h2/src/test/org/h2/test/scripts/functions/numeric/acos.sql
index 9a6a689feb..5e07edd202 100644
--- a/h2/src/test/org/h2/test/scripts/functions/numeric/acos.sql
+++ b/h2/src/test/org/h2/test/scripts/functions/numeric/acos.sql
@@ -8,3 +8,12 @@ select acos(null) vn, acos(-1) r1;
> ---- -----------------
> null 3.141592653589793
> rows: 1
+
+SELECT ACOS(-1.1);
+> exception INVALID_VALUE_2
+
+SELECT ACOS(1.1);
+> exception INVALID_VALUE_2
+
+SELECT ACOS(CAST('Infinity' AS DOUBLE PRECISION));
+> exception INVALID_VALUE_2
diff --git a/h2/src/test/org/h2/test/scripts/functions/numeric/asin.sql b/h2/src/test/org/h2/test/scripts/functions/numeric/asin.sql
index c653bea45a..3eccdec8d1 100644
--- a/h2/src/test/org/h2/test/scripts/functions/numeric/asin.sql
+++ b/h2/src/test/org/h2/test/scripts/functions/numeric/asin.sql
@@ -8,3 +8,12 @@ select asin(null) vn, asin(-1) r1;
> ---- -------------------
> null -1.5707963267948966
> rows: 1
+
+SELECT ASIN(-1.1);
+> exception INVALID_VALUE_2
+
+SELECT ASIN(1.1);
+> exception INVALID_VALUE_2
+
+SELECT ASIN(CAST('Infinity' AS DOUBLE PRECISION));
+> exception INVALID_VALUE_2
diff --git a/h2/src/test/org/h2/test/scripts/indexes.sql b/h2/src/test/org/h2/test/scripts/indexes.sql
index a1e469f4bd..a28de15e2e 100644
--- a/h2/src/test/org/h2/test/scripts/indexes.sql
+++ b/h2/src/test/org/h2/test/scripts/indexes.sql
@@ -435,3 +435,751 @@ EXPLAIN SELECT P.ID, G, MAX(CASE WHEN K = 'A' THEN V END) AS A, MAX(CASE WHEN K
DROP TABLE P, T;
> ok
+
+CREATE TABLE TEST(A BIGINT PRIMARY KEY, B BIGINT UNIQUE);
+> ok
+
+INSERT INTO TEST VALUES (-9223372036854775808, -9223372036854775808), (0, 0),
+ (9223372036854775807, 9223372036854775807);
+> update count: 3
+
+SELECT * FROM TEST WHERE A > 'NaN'::REAL;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B > 'NaN'::REAL;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A < 'NaN'::REAL;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE B < 'NaN'::REAL;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE A > 'Infinity'::REAL;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B > 'Infinity'::REAL;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A < 'Infinity'::REAL;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE B < 'Infinity'::REAL;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE A > 1E19::REAL;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B > 1E19::REAL;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A < 1E19::REAL;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE B < 1E19::REAL;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE A > '-Infinity'::REAL;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE B > '-Infinity'::REAL;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE A < '-Infinity'::REAL;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B < '-Infinity'::REAL;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A > -1E19::REAL;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE B > -1E19::REAL;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE A < -1E19::REAL;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B < -1E19::REAL;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A > 'NaN'::DOUBLE PRECISION;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B > 'NaN'::DOUBLE PRECISION;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A < 'NaN'::DOUBLE PRECISION;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE B < 'NaN'::DOUBLE PRECISION;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE A > 'Infinity'::DOUBLE PRECISION;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B > 'Infinity'::DOUBLE PRECISION;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A < 'Infinity'::DOUBLE PRECISION;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE B < 'Infinity'::DOUBLE PRECISION;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE A > 1E19::DOUBLE PRECISION;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B > 1E19::DOUBLE PRECISION;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A < 1E19::DOUBLE PRECISION;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE B < 1E19::DOUBLE PRECISION;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE A > '-Infinity'::DOUBLE PRECISION;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE B > '-Infinity'::DOUBLE PRECISION;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE A < '-Infinity'::DOUBLE PRECISION;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B < '-Infinity'::DOUBLE PRECISION;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A > -1E19::DOUBLE PRECISION;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE B > -1E19::DOUBLE PRECISION;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE A < -1E19::DOUBLE PRECISION;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B < -1E19::DOUBLE PRECISION;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A > 9223372036854775808::NUMERIC;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B > 9223372036854775808::NUMERIC;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A >= 9223372036854775807::NUMERIC;
+> A B
+> ------------------- -------------------
+> 9223372036854775807 9223372036854775807
+> rows: 1
+
+SELECT * FROM TEST WHERE B >= 9223372036854775807::NUMERIC;
+> A B
+> ------------------- -------------------
+> 9223372036854775807 9223372036854775807
+> rows: 1
+
+SELECT * FROM TEST WHERE A < 9223372036854775808::NUMERIC;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE B < 9223372036854775808::NUMERIC;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE A < 9223372036854775807::NUMERIC;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> rows: 2
+
+SELECT * FROM TEST WHERE B < 9223372036854775807::NUMERIC;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> rows: 2
+
+SELECT * FROM TEST WHERE A > -9223372036854775809::NUMERIC;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE B > -9223372036854775809::NUMERIC;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE A < -9223372036854775809::NUMERIC;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B < -9223372036854775809::NUMERIC;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A > 'NaN'::DECFLOAT;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B > 'NaN'::DECFLOAT;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A < 'NaN'::DECFLOAT;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE B < 'NaN'::DECFLOAT;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE A > 'Infinity'::DECFLOAT;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B > 'Infinity'::DECFLOAT;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A < 'Infinity'::DECFLOAT;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE B < 'Infinity'::DECFLOAT;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE A > 9223372036854775808::DECFLOAT;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B > 9223372036854775808::DECFLOAT;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A < 9223372036854775808::DECFLOAT;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE B < 9223372036854775808::DECFLOAT;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE A > '-Infinity'::DECFLOAT;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE B > '-Infinity'::DECFLOAT;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE A < '-Infinity'::DECFLOAT;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B < '-Infinity'::DECFLOAT;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A > -9223372036854775809::DECFLOAT;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE B > -9223372036854775809::DECFLOAT;
+> A B
+> -------------------- --------------------
+> -9223372036854775808 -9223372036854775808
+> 0 0
+> 9223372036854775807 9223372036854775807
+> rows: 3
+
+SELECT * FROM TEST WHERE A < -9223372036854775809::DECFLOAT;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B < -9223372036854775809::DECFLOAT;
+> A B
+> - -
+> rows: 0
+
+DROP TABLE TEST;
+> ok
+
+CREATE TABLE TEST(A TINYINT PRIMARY KEY, B TINYINT UNIQUE);
+> ok
+
+INSERT INTO TEST VALUES (-128, -128), (0, 0), (127, 127);
+> update count: 3
+
+SELECT * FROM TEST WHERE A > 'NaN'::REAL;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B > 'NaN'::REAL;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A < 'NaN'::REAL;
+> A B
+> ---- ----
+> -128 -128
+> 0 0
+> 127 127
+> rows: 3
+
+SELECT * FROM TEST WHERE B < 'NaN'::REAL;
+> A B
+> ---- ----
+> -128 -128
+> 0 0
+> 127 127
+> rows: 3
+
+SELECT * FROM TEST WHERE A > 'Infinity'::REAL;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B > 'Infinity'::REAL;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A < 'Infinity'::REAL;
+> A B
+> ---- ----
+> -128 -128
+> 0 0
+> 127 127
+> rows: 3
+
+SELECT * FROM TEST WHERE B < 'Infinity'::REAL;
+> A B
+> ---- ----
+> -128 -128
+> 0 0
+> 127 127
+> rows: 3
+
+SELECT * FROM TEST WHERE A > 1E19::REAL;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B > 1E19::REAL;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A < 1E19::REAL;
+> A B
+> ---- ----
+> -128 -128
+> 0 0
+> 127 127
+> rows: 3
+
+SELECT * FROM TEST WHERE B < 1E19::REAL;
+> A B
+> ---- ----
+> -128 -128
+> 0 0
+> 127 127
+> rows: 3
+
+SELECT * FROM TEST WHERE A > '-Infinity'::REAL;
+> A B
+> ---- ----
+> -128 -128
+> 0 0
+> 127 127
+> rows: 3
+
+SELECT * FROM TEST WHERE B > '-Infinity'::REAL;
+> A B
+> ---- ----
+> -128 -128
+> 0 0
+> 127 127
+> rows: 3
+
+SELECT * FROM TEST WHERE A < '-Infinity'::REAL;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B < '-Infinity'::REAL;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A > -1E19::REAL;
+> A B
+> ---- ----
+> -128 -128
+> 0 0
+> 127 127
+> rows: 3
+
+SELECT * FROM TEST WHERE B > -1E19::REAL;
+> A B
+> ---- ----
+> -128 -128
+> 0 0
+> 127 127
+> rows: 3
+
+SELECT * FROM TEST WHERE A < -1E19::REAL;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B < -1E19::REAL;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A > 'NaN'::DOUBLE PRECISION;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B > 'NaN'::DOUBLE PRECISION;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A < 'NaN'::DOUBLE PRECISION;
+> A B
+> ---- ----
+> -128 -128
+> 0 0
+> 127 127
+> rows: 3
+
+SELECT * FROM TEST WHERE B < 'NaN'::DOUBLE PRECISION;
+> A B
+> ---- ----
+> -128 -128
+> 0 0
+> 127 127
+> rows: 3
+
+SELECT * FROM TEST WHERE A > 'Infinity'::DOUBLE PRECISION;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B > 'Infinity'::DOUBLE PRECISION;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A < 'Infinity'::DOUBLE PRECISION;
+> A B
+> ---- ----
+> -128 -128
+> 0 0
+> 127 127
+> rows: 3
+
+SELECT * FROM TEST WHERE B < 'Infinity'::DOUBLE PRECISION;
+> A B
+> ---- ----
+> -128 -128
+> 0 0
+> 127 127
+> rows: 3
+
+SELECT * FROM TEST WHERE A > 1E19::DOUBLE PRECISION;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B > 1E19::DOUBLE PRECISION;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A < 1E19::DOUBLE PRECISION;
+> A B
+> ---- ----
+> -128 -128
+> 0 0
+> 127 127
+> rows: 3
+
+SELECT * FROM TEST WHERE B < 1E19::DOUBLE PRECISION;
+> A B
+> ---- ----
+> -128 -128
+> 0 0
+> 127 127
+> rows: 3
+
+SELECT * FROM TEST WHERE A > '-Infinity'::DOUBLE PRECISION;
+> A B
+> ---- ----
+> -128 -128
+> 0 0
+> 127 127
+> rows: 3
+
+SELECT * FROM TEST WHERE B > '-Infinity'::DOUBLE PRECISION;
+> A B
+> ---- ----
+> -128 -128
+> 0 0
+> 127 127
+> rows: 3
+
+SELECT * FROM TEST WHERE A < '-Infinity'::DOUBLE PRECISION;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B < '-Infinity'::DOUBLE PRECISION;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE A > -1E19::DOUBLE PRECISION;
+> A B
+> ---- ----
+> -128 -128
+> 0 0
+> 127 127
+> rows: 3
+
+SELECT * FROM TEST WHERE B > -1E19::DOUBLE PRECISION;
+> A B
+> ---- ----
+> -128 -128
+> 0 0
+> 127 127
+> rows: 3
+
+SELECT * FROM TEST WHERE A < -1E19::DOUBLE PRECISION;
+> A B
+> - -
+> rows: 0
+
+SELECT * FROM TEST WHERE B < -1E19::DOUBLE PRECISION;
+> A B
+> - -
+> rows: 0
+
+DROP TABLE TEST;
+> ok
+