PHOENIX-1794 Support Long.MIN_VALUE for phoenix BIGINT type
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/7aea6921 Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/7aea6921 Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/7aea6921 Branch: refs/heads/calcite Commit: 7aea69215a007103f031d1e006e8b4057ec7ffc5 Parents: 5ea3607 Author: James Taylor <[email protected]> Authored: Mon Apr 6 14:07:57 2015 -0700 Committer: James Taylor <[email protected]> Committed: Mon Apr 6 14:09:19 2015 -0700 ---------------------------------------------------------------------- .../org/apache/phoenix/end2end/ArrayIT.java | 12 ++-- .../end2end/ClientTimeArithmeticQueryIT.java | 10 +-- .../phoenix/end2end/CoalesceFunctionIT.java | 2 +- .../org/apache/phoenix/end2end/NotQueryIT.java | 8 +-- phoenix-core/src/main/antlr3/PhoenixSQL.g | 67 ++++---------------- .../apache/phoenix/parse/LiteralParseNode.java | 5 ++ .../apache/phoenix/parse/ParseNodeFactory.java | 42 ++++++++++++ .../apache/phoenix/schema/types/PDataType.java | 1 + .../apache/phoenix/schema/types/PDouble.java | 1 - .../phoenix/compile/QueryCompilerTest.java | 46 ++++++++++++++ 10 files changed, 121 insertions(+), 73 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/7aea6921/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayIT.java index ff8601b..d7dce54 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayIT.java @@ -463,7 +463,7 @@ public class ArrayIT extends BaseClientManagedTimeIT { props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 2)); // Execute at timestamp 2 conn = DriverManager.getConnection(getUrl(), props); String query = "SELECT a_double_array[1] FROM " + SIMPLE_TABLE_WITH_ARRAY - + " WHERE a_double_array[2] = 89.96d or a_char_array[0] = 'a'"; + + " WHERE a_double_array[2] = 89.96 or a_char_array[0] = 'a'"; PreparedStatement statement = conn.prepareStatement(query); ResultSet rs = statement.executeQuery(); assertTrue(rs.next()); @@ -493,7 +493,7 @@ public class ArrayIT extends BaseClientManagedTimeIT { props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 2)); // Execute at timestamp 2 conn = DriverManager.getConnection(getUrl(), props); String query = "SELECT a_double_array[1] FROM " + SIMPLE_TABLE_WITH_ARRAY - + " WHERE 89.96d = ANY(a_double_array)"; + + " WHERE CAST(89.96 AS DOUBLE) = ANY(a_double_array)"; PreparedStatement statement = conn.prepareStatement(query); ResultSet rs = statement.executeQuery(); assertTrue(rs.next()); @@ -522,7 +522,7 @@ public class ArrayIT extends BaseClientManagedTimeIT { props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 2)); // Execute at timestamp 2 conn = DriverManager.getConnection(getUrl(), props); String query = "SELECT a_double_array[1] FROM " + SIMPLE_TABLE_WITH_ARRAY - + " WHERE 64.87d = ALL(a_double_array)"; + + " WHERE CAST(64.87 as DOUBLE) = ALL(a_double_array)"; PreparedStatement statement = conn.prepareStatement(query); ResultSet rs = statement.executeQuery(); assertFalse(rs.next()); @@ -546,7 +546,7 @@ public class ArrayIT extends BaseClientManagedTimeIT { props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 2)); // Execute at timestamp 2 conn = DriverManager.getConnection(getUrl(), props); String query = "SELECT a_double_array[1] FROM " + SIMPLE_TABLE_WITH_ARRAY - + " WHERE a_char_array[0] = 'f' or 89.96d > ANY(a_double_array)"; + + " WHERE a_char_array[0] = 'f' or CAST(89.96 AS DOUBLE) > ANY(a_double_array)"; PreparedStatement statement = conn.prepareStatement(query); ResultSet rs = statement.executeQuery(); assertTrue(rs.next()); @@ -575,7 +575,7 @@ public class ArrayIT extends BaseClientManagedTimeIT { props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 2)); // Execute at timestamp 2 conn = DriverManager.getConnection(getUrl(), props); String query = "SELECT a_double_array[1], a_double_array[2] FROM " + SIMPLE_TABLE_WITH_ARRAY - + " WHERE a_char_array[0] = 'f' or 100.0d > ALL(a_double_array)"; + + " WHERE a_char_array[0] = 'f' or CAST(100.0 AS DOUBLE) > ALL(a_double_array)"; PreparedStatement statement = conn.prepareStatement(query); ResultSet rs = statement.executeQuery(); assertTrue(rs.next()); @@ -1001,7 +1001,7 @@ public class ArrayIT extends BaseClientManagedTimeIT { createTableWithArray(getUrl(), getDefaultSplits(tenantId), null, ts - 2); initTablesWithArrays(tenantId, null, ts, false, getUrl()); - String query = "SELECT a_double_array FROM TABLE_WITH_ARRAY WHERE a_double_array = ARRAY [ 25.343d, 36.763d, 37.56d,386.63d]"; + String query = "SELECT a_double_array FROM TABLE_WITH_ARRAY WHERE a_double_array = CAST(ARRAY [ 25.343, 36.763, 37.56,386.63] AS DOUBLE ARRAY)"; Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 2)); // Execute at timestamp 2 http://git-wip-us.apache.org/repos/asf/phoenix/blob/7aea6921/phoenix-core/src/it/java/org/apache/phoenix/end2end/ClientTimeArithmeticQueryIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ClientTimeArithmeticQueryIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ClientTimeArithmeticQueryIT.java index 17ed19d..00d835c 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ClientTimeArithmeticQueryIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ClientTimeArithmeticQueryIT.java @@ -72,7 +72,7 @@ public class ClientTimeArithmeticQueryIT extends BaseQueryIT { @Test public void testDateAdd() throws Exception { - String query = "SELECT entity_id, b_string FROM ATABLE WHERE a_date + 0.5d < ?"; + String query = "SELECT entity_id, b_string FROM ATABLE WHERE a_date + CAST(0.5 AS DOUBLE) < ?"; String url = getUrl() + ";" + PhoenixRuntime.CURRENT_SCN_ATTRIB + "=" + (ts + 5); // Run query at timestamp 5 Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); Connection conn = DriverManager.getConnection(url, props); @@ -236,7 +236,7 @@ public class ClientTimeArithmeticQueryIT extends BaseQueryIT { } @Test public void testDoubleSubtractionExpression() throws Exception { - String query = "SELECT entity_id FROM aTable where a_double - 0.0002d < 0"; + String query = "SELECT entity_id FROM aTable where a_double - CAST(0.0002 AS DOUBLE) < 0"; Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 2)); // Execute at timestamp 2 Connection conn = DriverManager.getConnection(getUrl(), props); @@ -338,7 +338,7 @@ public class ClientTimeArithmeticQueryIT extends BaseQueryIT { @Test public void testDoubleDivideExpression() throws Exception { - String query = "SELECT entity_id FROM aTable where a_double / 3.0d = 0.0003"; + String query = "SELECT entity_id FROM aTable where a_double / CAST(3.0 AS DOUBLE) = 0.0003"; Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 2)); // Execute at timestamp 2 Connection conn = DriverManager.getConnection(getUrl(), props); @@ -455,7 +455,7 @@ public class ClientTimeArithmeticQueryIT extends BaseQueryIT { @Test public void testDoubleMultiplyExpression() throws Exception { - String query = "SELECT entity_id FROM aTable where A_DOUBLE * 2.0d = 0.0002"; + String query = "SELECT entity_id FROM aTable where A_DOUBLE * CAST(2.0 AS DOUBLE) = 0.0002"; Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 2)); // Execute at timestamp 2 Connection conn = DriverManager.getConnection(getUrl(), props); @@ -577,7 +577,7 @@ public class ClientTimeArithmeticQueryIT extends BaseQueryIT { @Test public void testDateSubtract() throws Exception { - String query = "SELECT entity_id, b_string FROM ATABLE WHERE a_date - 0.5d > ?"; + String query = "SELECT entity_id, b_string FROM ATABLE WHERE a_date - CAST(0.5 AS DOUBLE) > ?"; String url = getUrl() + ";" + PhoenixRuntime.CURRENT_SCN_ATTRIB + "=" + (ts + 5); // Run query at timestamp 5 Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); Connection conn = DriverManager.getConnection(url, props); http://git-wip-us.apache.org/repos/asf/phoenix/blob/7aea6921/phoenix-core/src/it/java/org/apache/phoenix/end2end/CoalesceFunctionIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CoalesceFunctionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CoalesceFunctionIT.java index 1ad647b..92a9376 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CoalesceFunctionIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CoalesceFunctionIT.java @@ -78,7 +78,7 @@ public class CoalesceFunctionIT extends BaseHBaseManagedTimeIT { ResultSet rs = conn.createStatement().executeQuery( "SELECT " - + "COALESCE(SUM(COUNT), 0L) " //explicitly def long + + "COALESCE(SUM(COUNT), CAST(0 AS BIGINT)) " //explicitly def long + "FROM TEST_COALESCE " + "GROUP BY ID"); http://git-wip-us.apache.org/repos/asf/phoenix/blob/7aea6921/phoenix-core/src/it/java/org/apache/phoenix/end2end/NotQueryIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/NotQueryIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/NotQueryIT.java index 21074fc..7fd7979 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/NotQueryIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/NotQueryIT.java @@ -207,7 +207,7 @@ public class NotQueryIT extends BaseQueryIT { @Test public void testNotEqualsByFloat() throws Exception { String query = "SELECT a_float -- and here comment\n" + - "FROM aTable WHERE organization_id=? and a_float != 0.01d and a_float <= 0.02d"; + "FROM aTable WHERE organization_id=? and a_float != CAST(0.01 AS FLOAT) and a_float <= CAST(0.02 AS FLOAT)"; Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 2)); // Execute at timestamp 2 Connection conn = DriverManager.getConnection(getUrl(), props); @@ -226,7 +226,7 @@ public class NotQueryIT extends BaseQueryIT { @Test public void testNotEqualsByUnsignedFloat() throws Exception { String query = "SELECT a_unsigned_float -- and here comment\n" + - "FROM aTable WHERE organization_id=? and a_unsigned_float != 0.01d and a_unsigned_float <= 0.02d"; + "FROM aTable WHERE organization_id=? and a_unsigned_float != 0.01 and a_unsigned_float <= 0.02"; Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 2)); // Execute at timestamp 2 Connection conn = DriverManager.getConnection(getUrl(), props); @@ -245,7 +245,7 @@ public class NotQueryIT extends BaseQueryIT { @Test public void testNotEqualsByDouble() throws Exception { String query = "SELECT a_double -- and here comment\n" + - "FROM aTable WHERE organization_id=? and a_double != 0.0001d and a_double <= 0.0002d"; + "FROM aTable WHERE organization_id=? and a_double != CAST(0.0001 AS DOUBLE) and a_double <= CAST(0.0002 AS DOUBLE)"; Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 2)); // Execute at timestamp 2 Connection conn = DriverManager.getConnection(getUrl(), props); @@ -264,7 +264,7 @@ public class NotQueryIT extends BaseQueryIT { @Test public void testNotEqualsByUnsignedDouble() throws Exception { String query = "SELECT a_unsigned_double -- and here comment\n" + - "FROM aTable WHERE organization_id=? and a_unsigned_double != 0.0001d and a_unsigned_double <= 0.0002d"; + "FROM aTable WHERE organization_id=? and a_unsigned_double != 0.0001 and a_unsigned_double <= 0.0002"; Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 2)); // Execute at timestamp 2 Connection conn = DriverManager.getConnection(getUrl(), props); http://git-wip-us.apache.org/repos/asf/phoenix/blob/7aea6921/phoenix-core/src/main/antlr3/PhoenixSQL.g ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/antlr3/PhoenixSQL.g b/phoenix-core/src/main/antlr3/PhoenixSQL.g index 03ec9f5..295bd79 100644 --- a/phoenix-core/src/main/antlr3/PhoenixSQL.g +++ b/phoenix-core/src/main/antlr3/PhoenixSQL.g @@ -425,7 +425,7 @@ create_sequence_node returns [CreateSequenceStatement ret] ; int_literal_or_bind returns [ParseNode ret] - : n=int_literal { $ret = n; } + : n=int_or_long_literal { $ret = n; } | b=bind_expression { $ret = b; } ; @@ -630,7 +630,7 @@ delete_node returns [DeleteStatement ret] limit returns [LimitNode ret] : b=bind_expression { $ret = factory.limit(b); } - | l=int_literal { $ret = factory.limit(l); } + | l=int_or_long_literal { $ret = factory.limit(l); } ; sampling_rate returns [LiteralParseNode ret] @@ -894,18 +894,14 @@ literal_or_bind returns [ParseNode ret] // Get a string, integer, double, date, boolean, or NULL value. literal returns [LiteralParseNode ret] - : t=STRING_LITERAL { - ret = factory.literal(t.getText()); + : s=STRING_LITERAL { + ret = factory.literal(s.getText()); } - | l=int_literal { ret = l; } - | l=long_literal { ret = l; } - | l=double_literal { ret = l; } - | t=DECIMAL { - try { - ret = factory.literal(new BigDecimal(t.getText())); - } catch (NumberFormatException e) { // Shouldn't happen since we just parsed a decimal - throwRecognitionException(t); - } + | n=NUMBER { + ret = factory.wholeNumber(n.getText()); + } + | d=DECIMAL { + ret = factory.realNumber(d.getText()); } | NULL {ret = factory.literal(null);} | TRUE {ret = factory.literal(Boolean.TRUE);} @@ -919,42 +915,9 @@ literal returns [LiteralParseNode ret] } ; -int_literal returns [LiteralParseNode ret] +int_or_long_literal returns [LiteralParseNode ret] : n=NUMBER { - try { - Long v = Long.valueOf(n.getText()); - if (v >= Integer.MIN_VALUE && v <= Integer.MAX_VALUE) { - ret = factory.literal(v.intValue()); - } else { - ret = factory.literal(v); - } - } catch (NumberFormatException e) { // Shouldn't happen since we just parsed a number - throwRecognitionException(n); - } - } - ; - -long_literal returns [LiteralParseNode ret] - : l=LONG { - try { - String lt = l.getText(); - Long v = Long.valueOf(lt.substring(0, lt.length() - 1)); - ret = factory.literal(v); - } catch (NumberFormatException e) { // Shouldn't happen since we just parsed a number - throwRecognitionException(l); - } - } - ; - -double_literal returns [LiteralParseNode ret] - : d=DOUBLE { - try { - String dt = d.getText(); - Double v = Double.valueOf(dt.substring(0, dt.length() - 1)); - ret = factory.literal(v); - } catch (NumberFormatException e) { // Shouldn't happen since we just parsed a number - throwRecognitionException(d); - } + ret = factory.intOrLong(n.getText()); } ; @@ -1004,19 +967,11 @@ NUMBER : POSINTEGER ; -LONG - : POSINTEGER ('L'|'l') - ; - // Exponential format is not supported. DECIMAL : POSINTEGER? '.' POSINTEGER ; -DOUBLE - : DECIMAL ('D'|'d') - ; - DOUBLE_QUOTE : '"' ; http://git-wip-us.apache.org/repos/asf/phoenix/blob/7aea6921/phoenix-core/src/main/java/org/apache/phoenix/parse/LiteralParseNode.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/LiteralParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/LiteralParseNode.java index e0e8c3b..85f4ee5 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/parse/LiteralParseNode.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/LiteralParseNode.java @@ -17,6 +17,7 @@ */ package org.apache.phoenix.parse; +import java.math.BigDecimal; import java.sql.SQLException; import java.util.Collections; import java.util.List; @@ -39,6 +40,10 @@ public class LiteralParseNode extends TerminalParseNode { public static final ParseNode ONE = new LiteralParseNode(1); public static final ParseNode MINUS_ONE = new LiteralParseNode(-1L); public static final ParseNode TRUE = new LiteralParseNode(true); + // Parser representation of Long.MIN_VALUE, as ABS(Long.MIN_VALUE) is too big to fit into a Long + public static final ParseNode MIN_LONG_AS_BIG_DECIMAL = new LiteralParseNode(BigDecimal.valueOf(Long.MIN_VALUE).abs()); + // See ParseNodeFactory.negate(), as MIN_LONG_AS_BIG_DECIMAL will be converted MIN_LONG if negated. + public static final ParseNode MIN_LONG = new LiteralParseNode(Long.MIN_VALUE); private final Object value; private final PDataType type; http://git-wip-us.apache.org/repos/asf/phoenix/blob/7aea6921/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java index 5aba933..0f5074e 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java @@ -18,6 +18,7 @@ package org.apache.phoenix.parse; import java.lang.reflect.Constructor; +import java.math.BigDecimal; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.util.Arrays; @@ -73,6 +74,8 @@ public class ParseNodeFactory { AvgAggregateFunction.class ); private static final Map<BuiltInFunctionKey, BuiltInFunctionInfo> BUILT_IN_FUNCTION_MAP = Maps.newHashMap(); + private static final BigDecimal MAX_LONG = BigDecimal.valueOf(Long.MAX_VALUE); + /** * @@ -455,6 +458,39 @@ public class ParseNodeFactory { return new LiteralParseNode(value); } + public LiteralParseNode realNumber(String text) { + return new LiteralParseNode(new BigDecimal(text, PDataType.DEFAULT_MATH_CONTEXT)); + } + + public LiteralParseNode wholeNumber(String text) { + int length = text.length(); + // We know it'll fit into long, might still fit into int + if (length <= PDataType.LONG_PRECISION-1) { + long l = Long.parseLong(text); + if (l <= Integer.MAX_VALUE) { + // Fits into int + return new LiteralParseNode((int)l); + } + return new LiteralParseNode(l); + } + // Might still fit into long + BigDecimal d = new BigDecimal(text, PDataType.DEFAULT_MATH_CONTEXT); + if (d.compareTo(MAX_LONG) <= 0) { + return new LiteralParseNode(d.longValueExact()); + } + // Doesn't fit into long + return new LiteralParseNode(d); + } + + public LiteralParseNode intOrLong(String text) { + long l = Long.parseLong(text); + if (l <= Integer.MAX_VALUE) { + // Fits into int + return new LiteralParseNode((int)l); + } + return new LiteralParseNode(l); + } + public CastParseNode cast(ParseNode expression, String dataType, Integer maxLength, Integer scale) { return new CastParseNode(expression, dataType, maxLength, scale, false); } @@ -587,6 +623,12 @@ public class ParseNodeFactory { PLong.INSTANCE)) { return LiteralParseNode.MINUS_ONE; } + // Special case to convert Long.MIN_VALUE back to a Long. We can't initially represent it + // as a Long in the parser because we only represent positive values as constants in the + // parser, and ABS(Long.MIN_VALUE) is too big to fit into a Long. So we convert it back here. + if (LiteralParseNode.MIN_LONG_AS_BIG_DECIMAL.equals(child)) { + return LiteralParseNode.MIN_LONG; + } return new MultiplyParseNode(Arrays.asList(child,LiteralParseNode.MINUS_ONE)); } http://git-wip-us.apache.org/repos/asf/phoenix/blob/7aea6921/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDataType.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDataType.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDataType.java index 8f46a3b..48b215f 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDataType.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDataType.java @@ -503,6 +503,7 @@ public abstract class PDataType<T> implements DataType<T>, Comparable<PDataType< public final static Integer LONG_PRECISION = 19; public final static Integer SHORT_PRECISION = 5; public final static Integer BYTE_PRECISION = 3; + public final static Integer DOUBLE_PRECISION = 15; public static final int ARRAY_TYPE_BASE = 3000; public static final String ARRAY_TYPE_SUFFIX = "ARRAY"; http://git-wip-us.apache.org/repos/asf/phoenix/blob/7aea6921/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDouble.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDouble.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDouble.java index e0648f2..d11aedf 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDouble.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDouble.java @@ -27,7 +27,6 @@ import com.google.common.base.Preconditions; import com.google.common.primitives.Doubles; public class PDouble extends PRealNumber<Double> { - public static final PDouble INSTANCE = new PDouble(); private PDouble() { http://git-wip-us.apache.org/repos/asf/phoenix/blob/7aea6921/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java index 83c984b..77c1f9e 100644 --- a/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java +++ b/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java @@ -27,6 +27,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.math.BigDecimal; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; @@ -42,11 +43,14 @@ import org.apache.hadoop.hbase.filter.FirstKeyOnlyFilter; import org.apache.hadoop.hbase.util.Bytes; import org.apache.phoenix.coprocessor.BaseScannerRegionObserver; import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.expression.Expression; +import org.apache.phoenix.expression.LiteralExpression; import org.apache.phoenix.expression.aggregator.Aggregator; import org.apache.phoenix.expression.aggregator.CountAggregator; import org.apache.phoenix.expression.aggregator.ServerAggregators; import org.apache.phoenix.expression.function.TimeUnit; import org.apache.phoenix.jdbc.PhoenixConnection; +import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData; import org.apache.phoenix.jdbc.PhoenixPreparedStatement; import org.apache.phoenix.query.BaseConnectionlessQueryTest; import org.apache.phoenix.query.QueryConstants; @@ -1584,5 +1588,47 @@ public class QueryCompilerTest extends BaseConnectionlessQueryTest { stmt.executeQuery("select * from T where REGEXP_SUBSTR(v, '.\\\\d\\\\D\\\\s\\\\S\\\\w\\\\W') = 'val'"); } + private static void assertLiteralEquals(Object o, RowProjector p, int i) { + assertTrue(i < p.getColumnCount()); + Expression e = p.getColumnProjector(i).getExpression(); + assertTrue(e instanceof LiteralExpression); + LiteralExpression l = (LiteralExpression)e; + Object lo = l.getValue(); + assertEquals(o, lo); + } + + @Test + public void testIntAndLongMinValue() throws Exception { + BigDecimal oneLessThanMinLong = BigDecimal.valueOf(Long.MIN_VALUE).subtract(BigDecimal.ONE); + BigDecimal oneMoreThanMaxLong = BigDecimal.valueOf(Long.MAX_VALUE).add(BigDecimal.ONE); + String query = "SELECT " + + Integer.MIN_VALUE + "," + Long.MIN_VALUE + "," + + (Integer.MIN_VALUE+1) + "," + (Long.MIN_VALUE+1) + "," + + ((long)Integer.MIN_VALUE - 1) + "," + oneLessThanMinLong + "," + + Integer.MAX_VALUE + "," + Long.MAX_VALUE + "," + + (Integer.MAX_VALUE - 1) + "," + (Long.MAX_VALUE - 1) + "," + + ((long)Integer.MAX_VALUE + 1) + "," + oneMoreThanMaxLong + + " FROM " + PhoenixDatabaseMetaData.SYSTEM_STATS_NAME + " LIMIT 1"; + List<Object> binds = Collections.emptyList(); + QueryPlan plan = getQueryPlan(query, binds); + RowProjector p = plan.getProjector(); + // Negative integers end up as longs once the * -1 occurs + assertLiteralEquals((long)Integer.MIN_VALUE, p, 0); + // Min long still stays as long + assertLiteralEquals(Long.MIN_VALUE, p, 1); + assertLiteralEquals((long)Integer.MIN_VALUE + 1, p, 2); + assertLiteralEquals(Long.MIN_VALUE + 1, p, 3); + assertLiteralEquals((long)Integer.MIN_VALUE - 1, p, 4); + // Can't fit into long, so becomes BigDecimal + assertLiteralEquals(oneLessThanMinLong, p, 5); + // Positive integers stay as ints + assertLiteralEquals(Integer.MAX_VALUE, p, 6); + assertLiteralEquals(Long.MAX_VALUE, p, 7); + assertLiteralEquals(Integer.MAX_VALUE - 1, p, 8); + assertLiteralEquals(Long.MAX_VALUE - 1, p, 9); + assertLiteralEquals((long)Integer.MAX_VALUE + 1, p, 10); + assertLiteralEquals(oneMoreThanMaxLong, p, 11); + } + }
