DBZ-3413 Handle double single quotes in LogMinerDmlParser

Double single quotes are treated as 2 quotes instead of 1 escaped quote in the WHERE clause parsing function.
This commit is contained in:
Patrick Chu 2021-04-12 16:50:46 -07:00 committed by Chris Cranford
parent 672f958853
commit ecae5b6b91
2 changed files with 44 additions and 0 deletions

View File

@ -417,6 +417,11 @@ else if (c == '=' && !inColumnName && !inColumnValue) {
start = index + 1;
}
else if (c == '\'' && inColumnValue) {
// Skip over double single quote
if (inSingleQuote && lookAhead == '\'') {
index += 1;
continue;
}
// Set clause single-quoted column value
if (inSingleQuote) {
inSingleQuote = false;
@ -544,6 +549,11 @@ else if (c == 'I' && !inColumnName && !inColumnValue) {
}
}
else if (c == '\'' && inColumnValue) {
// Skip over double single quote
if (inSingleQuote && lookAhead == '\'') {
index += 1;
continue;
}
// Where clause single-quoted column value
if (inSingleQuote) {
inSingleQuote = false;

View File

@ -336,4 +336,38 @@ public void shouldParsingRedoSqlWithParenthesisInFunctionArgumentStrings() throw
assertThat(entry.getOldValues().get(1).getColumnData()).isNull();
assertThat(entry.getNewValues()).isEmpty();
}
@Test
@FixFor("DBZ-3413")
public void testParsingDoubleSingleQuoteInWhereClause() throws Exception {
final Table table = Table.editor()
.tableId(TableId.parse("DEBEZIUM.TEST"))
.addColumn(Column.editor().name("COL1").create())
.addColumn(Column.editor().name("COL2").create())
.create();
String sql = "update \"DEBEZIUM\".\"TEST\" set \"COL2\" = '1' where \"COL1\" = 'Bob''s dog' and \"COL2\" = '0';";
LogMinerDmlEntry entry = fastDmlParser.parse(sql, table, null);
assertThat(entry.getCommandType()).isEqualTo(Operation.UPDATE);
assertThat(entry.getOldValues()).hasSize(2);
assertThat(entry.getOldValues().get(0).getColumnName()).isEqualTo("COL1");
assertThat(entry.getOldValues().get(0).getColumnData()).isEqualTo("Bob''s dog");
assertThat(entry.getOldValues().get(1).getColumnName()).isEqualTo("COL2");
assertThat(entry.getOldValues().get(1).getColumnData()).isEqualTo("0");
assertThat(entry.getNewValues()).hasSize(2);
assertThat(entry.getNewValues().get(0).getColumnName()).isEqualTo("COL1");
assertThat(entry.getNewValues().get(0).getColumnData()).isEqualTo("Bob''s dog");
assertThat(entry.getNewValues().get(1).getColumnName()).isEqualTo("COL2");
assertThat(entry.getNewValues().get(1).getColumnData()).isEqualTo("1");
sql = "delete from \"DEBEZIUM\".\"TEST\" where \"COL1\" = 'Bob''s dog' and \"COL2\" = '1';";
entry = fastDmlParser.parse(sql, table, null);
assertThat(entry.getCommandType()).isEqualTo(Operation.DELETE);
assertThat(entry.getOldValues()).hasSize(2);
assertThat(entry.getOldValues().get(0).getColumnName()).isEqualTo("COL1");
assertThat(entry.getOldValues().get(0).getColumnData()).isEqualTo("Bob''s dog");
assertThat(entry.getOldValues().get(1).getColumnName()).isEqualTo("COL2");
assertThat(entry.getOldValues().get(1).getColumnData()).isEqualTo("1");
assertThat(entry.getNewValues()).isEmpty();
}
}