提交 3665807c authored 作者: Thomas Mueller's avatar Thomas Mueller

Literals of type BIGINT now have the correct data type.

上级 7bbf1613
...@@ -18,7 +18,7 @@ Change Log ...@@ -18,7 +18,7 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>- <ul><li>Literals of type BIGINT now have the correct data type.
</li></ul> </li></ul>
<h2>Version 1.2.131 (2010-03-05)</h2> <h2>Version 1.2.131 (2010-03-05)</h2>
......
...@@ -151,7 +151,7 @@ public class Parser { ...@@ -151,7 +151,7 @@ public class Parser {
// used during the tokenizer phase // used during the tokenizer phase
private static final int CHAR_END = 1, CHAR_VALUE = 2, CHAR_QUOTED = 3; private static final int CHAR_END = 1, CHAR_VALUE = 2, CHAR_QUOTED = 3;
private static final int CHAR_NAME = 4, CHAR_SPECIAL_1 = 5, CHAR_SPECIAL_2 = 6; private static final int CHAR_NAME = 4, CHAR_SPECIAL_1 = 5, CHAR_SPECIAL_2 = 6;
private static final int CHAR_STRING = 7, CHAR_DECIMAL = 8, CHAR_DOLLAR_QUOTED_STRING = 9; private static final int CHAR_STRING = 7, CHAR_DOT = 8, CHAR_DOLLAR_QUOTED_STRING = 9;
// this are token types // this are token types
private static final int KEYWORD = 1, IDENTIFIER = 2, PARAMETER = 3, END = 4, VALUE = 5; private static final int KEYWORD = 1, IDENTIFIER = 2, PARAMETER = 3, END = 4, VALUE = 5;
...@@ -2303,10 +2303,14 @@ public class Parser { ...@@ -2303,10 +2303,14 @@ public class Parser {
read(); read();
if (currentTokenType == VALUE) { if (currentTokenType == VALUE) {
r = ValueExpression.get(currentValue.negate()); r = ValueExpression.get(currentValue.negate());
// convert Integer.MIN_VALUE to int (-Integer.MIN_VALUE needed
// to be a long)
if (r.getType() == Value.LONG && r.getValue(session).getLong() == Integer.MIN_VALUE) { if (r.getType() == Value.LONG && r.getValue(session).getLong() == Integer.MIN_VALUE) {
// convert Integer.MIN_VALUE to type 'int'
// (Integer.MAX_VALUE+1 is of type 'long')
r = ValueExpression.get(ValueInt.get(Integer.MIN_VALUE)); r = ValueExpression.get(ValueInt.get(Integer.MIN_VALUE));
} else if (r.getType() == Value.DECIMAL && r.getValue(session).getBigDecimal().compareTo(ValueLong.MIN_BD) == 0) {
// convert Long.MIN_VALUE to type 'long'
// (Long.MAX_VALUE+1 is of type 'decimal')
r = ValueExpression.get(ValueLong.get(Long.MIN_VALUE));
} }
read(); read();
} else { } else {
...@@ -2698,7 +2702,7 @@ public class Parser { ...@@ -2698,7 +2702,7 @@ public class Parser {
i++; i++;
} }
return; return;
case CHAR_DECIMAL: case CHAR_DOT:
if (types[i] != CHAR_VALUE) { if (types[i] != CHAR_VALUE) {
currentTokenType = KEYWORD; currentTokenType = KEYWORD;
currentToken = "."; currentToken = ".";
...@@ -2785,12 +2789,14 @@ public class Parser { ...@@ -2785,12 +2789,14 @@ public class Parser {
// go until the first non-number // go until the first non-number
while (true) { while (true) {
int t = types[i]; int t = types[i];
if (t != CHAR_DECIMAL && t != CHAR_VALUE) { if (t != CHAR_DOT && t != CHAR_VALUE) {
break; break;
} }
i++; i++;
} }
if (chars[i] == 'E') { boolean containsE = false;
if (chars[i] == 'E' || chars[i] == 'e') {
containsE = true;
i++; i++;
if (chars[i] == '+' || chars[i] == '-') { if (chars[i] == '+' || chars[i] == '-') {
i++; i++;
...@@ -2804,13 +2810,21 @@ public class Parser { ...@@ -2804,13 +2810,21 @@ public class Parser {
} }
parseIndex = i; parseIndex = i;
String sub = sqlCommand.substring(start, i); String sub = sqlCommand.substring(start, i);
checkLiterals(false);
if (!containsE && sub.indexOf('.') < 0) {
BigInteger bi = new BigInteger(sub);
if (bi.compareTo(ValueLong.MAX) <= 0) {
currentValue = ValueLong.get(bi.longValue());
currentTokenType = VALUE;
return;
}
}
BigDecimal bd; BigDecimal bd;
try { try {
bd = new BigDecimal(sub); bd = new BigDecimal(sub);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, e, sub); throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, e, sub);
} }
checkLiterals(false);
currentValue = ValueDecimal.get(bd); currentValue = ValueDecimal.get(bd);
currentTokenType = VALUE; currentTokenType = VALUE;
} }
...@@ -2937,7 +2951,7 @@ public class Parser { ...@@ -2937,7 +2951,7 @@ public class Parser {
type = CHAR_SPECIAL_2; type = CHAR_SPECIAL_2;
break; break;
case '.': case '.':
type = CHAR_DECIMAL; type = CHAR_DOT;
break; break;
case '\'': case '\'':
type = types[i] = CHAR_STRING; type = types[i] = CHAR_STRING;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
*/ */
package org.h2.value; package org.h2.value;
import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.SQLException; import java.sql.SQLException;
...@@ -18,6 +19,9 @@ import org.h2.util.MathUtils; ...@@ -18,6 +19,9 @@ import org.h2.util.MathUtils;
*/ */
public class ValueLong extends Value { public class ValueLong extends Value {
public static final BigInteger MAX = BigInteger.valueOf(Long.MAX_VALUE);
public static final BigDecimal MIN_BD = BigDecimal.valueOf(Long.MIN_VALUE);
/** /**
* The precision in digits. * The precision in digits.
*/ */
...@@ -29,10 +33,9 @@ public class ValueLong extends Value { ...@@ -29,10 +33,9 @@ public class ValueLong extends Value {
*/ */
public static final int DISPLAY_SIZE = 20; public static final int DISPLAY_SIZE = 20;
private static final BigInteger MIN = BigInteger.valueOf(Long.MIN_VALUE);
private static final int STATIC_SIZE = 100; private static final int STATIC_SIZE = 100;
private static final ValueLong[] STATIC_CACHE; private static final ValueLong[] STATIC_CACHE;
private static final BigInteger MIN = BigInteger.valueOf(Long.MIN_VALUE);
private static final BigInteger MAX = BigInteger.valueOf(Long.MAX_VALUE);
private final long value; private final long value;
......
...@@ -11,6 +11,7 @@ import java.io.IOException; ...@@ -11,6 +11,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Array; import java.sql.Array;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DatabaseMetaData; import java.sql.DatabaseMetaData;
...@@ -53,6 +54,7 @@ public class TestResultSet extends TestBase { ...@@ -53,6 +54,7 @@ public class TestResultSet extends TestBase {
stat = conn.createStatement(); stat = conn.createStatement();
testParseSpecialValues();
testSpecialLocale(); testSpecialLocale();
testSubstringPrecision(); testSubstringPrecision();
testSubstringDataType(); testSubstringDataType();
...@@ -86,6 +88,32 @@ public class TestResultSet extends TestBase { ...@@ -86,6 +88,32 @@ public class TestResultSet extends TestBase {
} }
private void testParseSpecialValues() throws SQLException {
for (int i = -10; i < 10; i++) {
testParseSpecialValue("" + ((long) Integer.MIN_VALUE + i));
testParseSpecialValue("" + ((long) Integer.MAX_VALUE + i));
BigInteger bi = BigInteger.valueOf(i);
testParseSpecialValue(bi.add(BigInteger.valueOf(Long.MIN_VALUE)).toString());
testParseSpecialValue(bi.add(BigInteger.valueOf(Long.MAX_VALUE)).toString());
}
}
private void testParseSpecialValue(String x) throws SQLException {
Object expected;
expected = new BigDecimal(x);
try {
expected = Long.decode(x);
expected = Integer.decode(x);
} catch (Exception e) {
// ignore
}
ResultSet rs = stat.executeQuery("call " + x);
rs.next();
Object o = rs.getObject(1);
assertEquals(expected.getClass().getName(), o.getClass().getName());
assertTrue(expected.equals(o));
}
private void testSpecialLocale() throws SQLException { private void testSpecialLocale() throws SQLException {
Locale old = Locale.getDefault(); Locale old = Locale.getDefault();
try { try {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论