From 5d202346e56f453152b820caaf0811a0198129b1 Mon Sep 17 00:00:00 2001 From: Mike Swierczek <441523+Michael-S@users.noreply.github.com> Date: Wed, 9 Oct 2024 14:20:58 +0000 Subject: [PATCH] Fix: CSV and Raw output, escape quotes Fixes #3050 Signed-off-by: Mike Swierczek <441523+Michael-S@users.noreply.github.com> --- .../protocol/response/format/FlatResponseBase.java | 6 +++++- .../response/format/CsvResponseFormatterTest.java | 7 +++++-- .../response/format/RawResponseFormatterTest.java | 14 +++++++++++--- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/protocol/src/main/java/org/opensearch/sql/protocol/response/format/FlatResponseBase.java b/protocol/src/main/java/org/opensearch/sql/protocol/response/format/FlatResponseBase.java index 98e79a4048..be2517bf6c 100644 --- a/protocol/src/main/java/org/opensearch/sql/protocol/response/format/FlatResponseBase.java +++ b/protocol/src/main/java/org/opensearch/sql/protocol/response/format/FlatResponseBase.java @@ -84,6 +84,10 @@ protected List> formatData(List> lines) { protected String quoteIfRequired(String separator, String cell) { final String quote = "\""; - return cell.contains(separator) ? quote + cell.replaceAll("\"", "\"\"") + quote : cell; + if (cell != null && (cell.contains(separator) || cell.contains(quote))) { + return quote + cell.replaceAll(quote, quote + quote) + quote; + } else { + return cell; + } } } diff --git a/protocol/src/test/java/org/opensearch/sql/protocol/response/format/CsvResponseFormatterTest.java b/protocol/src/test/java/org/opensearch/sql/protocol/response/format/CsvResponseFormatterTest.java index 554d5ae8bb..ef2f2e8da8 100644 --- a/protocol/src/test/java/org/opensearch/sql/protocol/response/format/CsvResponseFormatterTest.java +++ b/protocol/src/test/java/org/opensearch/sql/protocol/response/format/CsvResponseFormatterTest.java @@ -108,8 +108,11 @@ void quoteIfRequired() { QueryResult response = new QueryResult( schema, - Arrays.asList(tupleValue(ImmutableMap.of("na,me", "John,Smith", ",,age", "30,,,")))); - String expected = "\"na,me\",\",,age\"%n\"John,Smith\",\"30,,,\""; + Arrays.asList( + tupleValue(ImmutableMap.of("na,me", "John,Smith", ",,age", "30,,,")), + tupleValue(ImmutableMap.of("na,me", "\"Janice Jones", ",,age", "26\"")))); + String expected = + "\"na,me\",\",,age\"%n\"John,Smith\",\"30,,,\"%n\"\"\"Janice Jones\",\"26\"\"\""; assertEquals(format(expected), formatter.format(response)); } diff --git a/protocol/src/test/java/org/opensearch/sql/protocol/response/format/RawResponseFormatterTest.java b/protocol/src/test/java/org/opensearch/sql/protocol/response/format/RawResponseFormatterTest.java index fd057437a0..ebdadcd50b 100644 --- a/protocol/src/test/java/org/opensearch/sql/protocol/response/format/RawResponseFormatterTest.java +++ b/protocol/src/test/java/org/opensearch/sql/protocol/response/format/RawResponseFormatterTest.java @@ -120,10 +120,18 @@ void quoteIfRequired() { QueryResult response = new QueryResult( schema, - Arrays.asList(tupleValue(ImmutableMap.of("na|me", "John|Smith", "||age", "30|||")))); - String expected = "\"na|me\"|\"||age\"%n" + "\"John|Smith\"|\"30|||\""; + Arrays.asList( + tupleValue(ImmutableMap.of("na|me", "John|Smith", "||age", "30|||")), + tupleValue(ImmutableMap.of("na|me", "Ja\"ne J\"ones", "||age", "\"40\"")))); + String expected = + "\"na|me\"|\"||age\"%n" + + "\"John|Smith\"|\"30|||\"%n" + + "\"Ja\"\"ne J\"\"ones\"|\"\"\"40\"\"\""; assertEquals(format(expected), getRawFormatter().format(response)); - String expectedPretty = "\"na|me\" |\"||age\"%n" + "\"John|Smith\"|\"30|||\""; + String expectedPretty = + "\"na|me\" |\"||age\" %n" + + "\"John|Smith\" |\"30|||\" %n" + + "\"Ja\"\"ne J\"\"ones\"|\"\"\"40\"\"\""; assertEquals(format(expectedPretty), getRawFormatterPretty().format(response)); }