diff --git a/server/pxf-api/src/main/java/org/greenplum/pxf/api/examples/DemoTextResolver.java b/server/pxf-api/src/main/java/org/greenplum/pxf/api/examples/DemoTextResolver.java index 775959e5a..90377626a 100644 --- a/server/pxf-api/src/main/java/org/greenplum/pxf/api/examples/DemoTextResolver.java +++ b/server/pxf-api/src/main/java/org/greenplum/pxf/api/examples/DemoTextResolver.java @@ -23,11 +23,13 @@ import org.greenplum.pxf.api.OneRow; import org.greenplum.pxf.api.io.DataType; +import java.nio.charset.StandardCharsets; import java.util.LinkedList; import java.util.List; /** - * Class that defines the serialization / deserialization of one record brought from the external input data. + * Class that defines the serialization / deserialization of one record brought + * from the external input data. *

* Demo implementation of resolver that returns text format */ @@ -57,13 +59,34 @@ public List getFields(OneRow row) { */ @Override public OneRow setFields(List record) throws Exception { - // text row data is passed as a single field - if (record == null || record.size() != 1) { - throw new Exception("Unexpected record format, expected 1 field, found " + - (record == null ? 0 : record.size())); + if (record == null || record.isEmpty()) { + throw new Exception("Unexpected record format, no fields provided"); } - byte[] value = (byte[]) record.get(0).val; - // empty array means the end of input stream, return null to stop iterations - return value.length == 0 ? null : new OneRow(value); + + // Legacy single-field end-of-stream marker (empty byte[]), keep behavior + if (record.size() == 1 && record.get(0).val instanceof byte[]) { + byte[] value = (byte[]) record.get(0).val; + if (value.length == 0) { + return null; + } + // Preserve legacy single-field behavior: return the bytes as-is + return new OneRow(value); + } + + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < record.size(); i++) { + Object val = record.get(i).val; + if (val instanceof byte[]) { + sb.append(new String((byte[]) val, StandardCharsets.UTF_8)); + } else if (val != null) { + sb.append(val.toString()); + } + if (i < record.size() - 1) { + sb.append(','); + } + } + sb.append('\n'); + + return new OneRow(sb.toString().getBytes(StandardCharsets.UTF_8)); } } diff --git a/server/pxf-api/src/test/java/org/greenplum/pxf/api/DemoResolverTest.java b/server/pxf-api/src/test/java/org/greenplum/pxf/api/DemoResolverTest.java index 1f7e72fc5..a8b02195e 100755 --- a/server/pxf-api/src/test/java/org/greenplum/pxf/api/DemoResolverTest.java +++ b/server/pxf-api/src/test/java/org/greenplum/pxf/api/DemoResolverTest.java @@ -19,7 +19,6 @@ * under the License. */ - import org.greenplum.pxf.api.examples.DemoResolver; import org.greenplum.pxf.api.examples.DemoTextResolver; import org.greenplum.pxf.api.model.RequestContext; @@ -79,7 +78,7 @@ public void testSetTextData() throws Exception { @Test public void testSetEmptyTextData() throws Exception { - OneField field = new OneField(VARCHAR.getOID(), new byte[]{}); + OneField field = new OneField(VARCHAR.getOID(), new byte[] {}); OneRow output = textResolver.setFields(Collections.singletonList(field)); assertNull(output); } @@ -97,16 +96,17 @@ public void testSetTextDataEmptyInput() { } @Test - public void testSetTextDataManyElements() { - assertThrows(Exception.class, - () -> textResolver.setFields(Arrays.asList(field, field))); + public void testSetTextDataManyElements() throws Exception { + OneRow output = textResolver.setFields(Arrays.asList(field, field)); + assertArrayEquals("value1,value2,value1,value2\n".getBytes(), + (byte[]) output.getData()); } @Test public void testSetFieldsIsUnsupported() { - Exception e = assertThrows(UnsupportedOperationException.class, + Exception e = assertThrows(UnsupportedOperationException.class, () -> customResolver.setFields(null)); - assertEquals("Demo resolver does not support write operation", e.getMessage()); + assertEquals("Demo resolver does not support write operation", e.getMessage()); } }