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); 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") @FixFor("DBZ-162")
@Test @Test
public void shouldParseAlterTableWithNewlineFeeds() { public void shouldParseAlterTableWithNewlineFeeds() {

View File

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

View File

@ -17,6 +17,7 @@
import io.debezium.annotation.Immutable; import io.debezium.annotation.Immutable;
import io.debezium.annotation.NotThreadSafe; import io.debezium.annotation.NotThreadSafe;
import io.debezium.function.BooleanConsumer; import io.debezium.function.BooleanConsumer;
import io.debezium.relational.ddl.DdlTokenizer;
import io.debezium.util.Strings; import io.debezium.util.Strings;
/** /**
@ -572,10 +573,22 @@ public Position nextPosition() {
public int consumeInteger() throws ParsingException, IllegalStateException { public int consumeInteger() throws ParsingException, IllegalStateException {
if (completed) throwNoMoreContent(); if (completed) throwNoMoreContent();
// Get the value from the current token ... // Get the value from the current token ...
String value = currentToken().value(); String value = currentToken().value().toUpperCase();
try { 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); int result = Integer.parseInt(value);
moveToNextToken(); moveToNextToken(newTokens);
return result; return result;
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
Position position = currentToken().position(); Position position = currentToken().position();
@ -1795,7 +1808,17 @@ public String toString() {
return sb.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 ... // And move the currentToken to the next token ...
if (!tokenIterator.hasNext()) { if (!tokenIterator.hasNext()) {
completed = true; completed = true;
@ -1805,6 +1828,10 @@ private void moveToNextToken() {
} }
} }
private void moveToNextToken() {
moveToNextToken(null);
}
/** /**
* Get the current token. * Get the current token.
* *