33import com .fasterxml .jackson .databind .JsonNode ;
44import com .fasterxml .jackson .databind .json .JsonMapper ;
55import com .fasterxml .jackson .databind .node .TextNode ;
6+ import com .google .common .annotations .VisibleForTesting ;
67import com .google .common .collect .Lists ;
78import com .provectus .kafka .ui .exception .KsqlApiException ;
89import com .provectus .kafka .ui .service .ksql .KsqlApiClient ;
910import java .util .ArrayList ;
10- import java .util .Arrays ;
1111import java .util .List ;
1212import java .util .Optional ;
13- import java .util .stream .Collectors ;
1413import org .springframework .web .reactive .function .client .WebClientResponseException ;
1514
1615public class ResponseParser {
@@ -24,11 +23,7 @@ public static Optional<KsqlApiClient.KsqlResponseTable> parseSelectResponse(Json
2423 return Optional .of (
2524 KsqlApiClient .KsqlResponseTable .builder ()
2625 .header ("Schema" )
27- .columnNames (
28- Arrays .stream (jsonNode .get ("header" ).get ("schema" ).asText ().split ("," ))
29- .map (String ::trim )
30- .collect (Collectors .toList ())
31- )
26+ .columnNames (parseSelectHeadersString (jsonNode .get ("header" ).get ("schema" ).asText ()))
3227 .build ());
3328 }
3429 if (arrayFieldNonEmpty (jsonNode , "row" )) {
@@ -46,6 +41,34 @@ public static Optional<KsqlApiClient.KsqlResponseTable> parseSelectResponse(Json
4641 return Optional .empty ();
4742 }
4843
44+ @ VisibleForTesting
45+ static List <String > parseSelectHeadersString (String str ) {
46+ List <String > headers = new ArrayList <>();
47+ int structNesting = 0 ;
48+ boolean quotes = false ;
49+ var headerBuilder = new StringBuilder ();
50+ for (char ch : str .toCharArray ()) {
51+ if (ch == '<' ) {
52+ structNesting ++;
53+ } else if (ch == '>' ) {
54+ structNesting --;
55+ } else if (ch == '`' ) {
56+ quotes = !quotes ;
57+ } else if (ch == ' ' && headerBuilder .isEmpty ()) {
58+ continue ; //skipping leading & training whitespaces
59+ } else if (ch == ',' && structNesting == 0 && !quotes ) {
60+ headers .add (headerBuilder .toString ());
61+ headerBuilder = new StringBuilder ();
62+ continue ;
63+ }
64+ headerBuilder .append (ch );
65+ }
66+ if (!headerBuilder .isEmpty ()) {
67+ headers .add (headerBuilder .toString ());
68+ }
69+ return headers ;
70+ }
71+
4972 public static KsqlApiClient .KsqlResponseTable errorTableWithTextMsg (String errorText ) {
5073 return KsqlApiClient .KsqlResponseTable .builder ()
5174 .header ("Execution error" )
0 commit comments