DBZ-667 Sceintific numbers parsing

This commit is contained in:
Jiri Pechanec 2018-03-19 19:48:36 +01:00 committed by Gunnar Morling
parent 00b63bb808
commit 2b5370de1a
3 changed files with 45 additions and 5 deletions

View File

@ -811,6 +811,18 @@ public void shouldParseAndIgnoreCreateFunction() {
listener.forEach(this::printEvent);
}
@FixFor("DBZ-667")
@Test
public void shouldParseScientificNotationNumber() {
String ddl = "CREATE TABLE t (id INT NOT NULL, myvalue DOUBLE DEFAULT 1E-10, PRIMARY KEY (`id`));"
+ "CREATE TABLE t (id INT NOT NULL, myvalue DOUBLE DEFAULT 1.3E-10, PRIMARY KEY (`id`));"
+ "CREATE TABLE t (id INT NOT NULL, myvalue DOUBLE DEFAULT 1.3E+10, PRIMARY KEY (`id`));"
+ "CREATE TABLE t (id INT NOT NULL, myvalue DOUBLE DEFAULT 3E10, PRIMARY KEY (`id`));"
+ "CREATE TABLE t (id INT NOT NULL, myvalue DOUBLE DEFAULT 1.3e10, PRIMARY KEY (`id`))";
parser.parse(ddl, tables);
assertThat(tables.size()).isEqualTo(1);
}
@FixFor("DBZ-162")
@Test
public void shouldParseAlterTableWithNewlineFeeds() {

View File

@ -754,15 +754,16 @@ protected Object parseNumericLiteral(Marker start, boolean signed) {
sb.append(tokens.consumeInteger());
}
if (tokens.canConsume('.')) {
sb.append('.');
sb.append(tokens.consumeInteger());
decimal = true;
}
if (!tokens.canConsume('E')) {
if (!tokens.canConsumeAnyOf("E", "e")) {
if (decimal) return Double.parseDouble(sb.toString());
return Integer.parseInt(sb.toString());
}
sb.append('E');
if (tokens.matches("+", "-")) {
if (tokens.matchesAnyOf("+", "-")) {
sb.append(tokens.consumeAnyOf("+", "-"));
}
sb.append(tokens.consumeInteger());

View File

@ -17,6 +17,7 @@
import io.debezium.annotation.Immutable;
import io.debezium.annotation.NotThreadSafe;
import io.debezium.function.BooleanConsumer;
import io.debezium.relational.ddl.DdlTokenizer;
import io.debezium.util.Strings;
/**
@ -572,10 +573,22 @@ public Position nextPosition() {
public int consumeInteger() throws ParsingException, IllegalStateException {
if (completed) throwNoMoreContent();
// Get the value from the current token ...
String value = currentToken().value();
String value = currentToken().value().toUpperCase();
try {
List<Token> newTokens = new ArrayList<>();
int ePos = value.indexOf("E");
// Scientific format, need to identify mantissa and exponent and put it back to stream
if (ePos != -1) {
String mantissa = value.substring(0, ePos);
newTokens.add(new CaseInsensitiveToken(currentToken().startIndex() + ePos, currentToken().startIndex() + ePos + 1, DdlTokenizer.WORD, currentToken().position()));
// Number is in format xxxEyyy
if (ePos != value.length() - 1) {
newTokens.add(new CaseInsensitiveToken(currentToken().startIndex() + ePos + 1, currentToken().endIndex(), DdlTokenizer.WORD, currentToken().position()));
}
value = mantissa;
}
int result = Integer.parseInt(value);
moveToNextToken();
moveToNextToken(newTokens);
return result;
} catch (NumberFormatException e) {
Position position = currentToken().position();
@ -1795,7 +1808,17 @@ public String toString() {
return sb.toString();
}
private void moveToNextToken() {
private void moveToNextToken(List<Token> newTokens) {
if (newTokens != null && !newTokens.isEmpty()) {
for (Token t: newTokens) {
tokenIterator.add(t);
}
for (int i = 0; i < newTokens.size() - 1; i++) {
tokenIterator.previous();
}
currentToken = newTokens.get(0);
return;
}
// And move the currentToken to the next token ...
if (!tokenIterator.hasNext()) {
completed = true;
@ -1805,6 +1828,10 @@ private void moveToNextToken() {
}
}
private void moveToNextToken() {
moveToNextToken(null);
}
/**
* Get the current token.
*