提交 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
<h1>Change Log</h1>
<h2>Next Version (unreleased)</h2>
<ul><li>-
<ul><li>Literals of type BIGINT now have the correct data type.
</li></ul>
<h2>Version 1.2.131 (2010-03-05)</h2>
......
......@@ -151,7 +151,7 @@ public class Parser {
// used during the tokenizer phase
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_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
private static final int KEYWORD = 1, IDENTIFIER = 2, PARAMETER = 3, END = 4, VALUE = 5;
......@@ -2303,10 +2303,14 @@ public class Parser {
read();
if (currentTokenType == VALUE) {
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) {
// convert Integer.MIN_VALUE to type 'int'
// (Integer.MAX_VALUE+1 is of type 'long')
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();
} else {
......@@ -2698,7 +2702,7 @@ public class Parser {
i++;
}
return;
case CHAR_DECIMAL:
case CHAR_DOT:
if (types[i] != CHAR_VALUE) {
currentTokenType = KEYWORD;
currentToken = ".";
......@@ -2785,12 +2789,14 @@ public class Parser {
// go until the first non-number
while (true) {
int t = types[i];
if (t != CHAR_DECIMAL && t != CHAR_VALUE) {
if (t != CHAR_DOT && t != CHAR_VALUE) {
break;
}
i++;
}
if (chars[i] == 'E') {
boolean containsE = false;
if (chars[i] == 'E' || chars[i] == 'e') {
containsE = true;
i++;
if (chars[i] == '+' || chars[i] == '-') {
i++;
......@@ -2804,13 +2810,21 @@ public class Parser {
}
parseIndex = 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;
try {
bd = new BigDecimal(sub);
} catch (NumberFormatException e) {
throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, e, sub);
}
checkLiterals(false);
currentValue = ValueDecimal.get(bd);
currentTokenType = VALUE;
}
......@@ -2937,7 +2951,7 @@ public class Parser {
type = CHAR_SPECIAL_2;
break;
case '.':
type = CHAR_DECIMAL;
type = CHAR_DOT;
break;
case '\'':
type = types[i] = CHAR_STRING;
......
......@@ -6,6 +6,7 @@
*/
package org.h2.value;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.PreparedStatement;
import java.sql.SQLException;
......@@ -18,6 +19,9 @@ import org.h2.util.MathUtils;
*/
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.
*/
......@@ -29,10 +33,9 @@ public class ValueLong extends Value {
*/
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 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;
......
......@@ -11,6 +11,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Array;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
......@@ -53,6 +54,7 @@ public class TestResultSet extends TestBase {
stat = conn.createStatement();
testParseSpecialValues();
testSpecialLocale();
testSubstringPrecision();
testSubstringDataType();
......@@ -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 {
Locale old = Locale.getDefault();
try {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论