diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/operation/tables/TableRowProjection.java b/src/main/java/io/stargate/sgv2/jsonapi/service/operation/tables/TableRowProjection.java index 127fa28a0..0e2072903 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/operation/tables/TableRowProjection.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/operation/tables/TableRowProjection.java @@ -74,11 +74,9 @@ public DocumentSource documentSource(Row row) { } try { final Object columnValue = row.getObject(i); - // We have a choice here: convert into JSON null (explicit) or drop (save space)? - // For now, do former: may change or make configurable later. - if (columnValue == null) { - result.putNull(columnName); - } else { + // By default, null value will not be returned. + // https://github.com/stargate/data-api/issues/1636 issue for adding nullOption + if (columnValue != null) { result.put(columnName, codec.toJSON(objectMapper, columnValue)); } } catch (ToJSONCodecException e) { diff --git a/src/test/java/io/stargate/sgv2/jsonapi/api/v1/tables/AbstractTableIntegrationTestBase.java b/src/test/java/io/stargate/sgv2/jsonapi/api/v1/tables/AbstractTableIntegrationTestBase.java index 17094882b..6a59cfc67 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/api/v1/tables/AbstractTableIntegrationTestBase.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/api/v1/tables/AbstractTableIntegrationTestBase.java @@ -1,12 +1,35 @@ package io.stargate.sgv2.jsonapi.api.v1.tables; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; import io.stargate.sgv2.jsonapi.api.v1.AbstractKeyspaceIntegrationTestBase; /** Abstract class for all table int tests that needs a collection to execute tests in. */ public class AbstractTableIntegrationTestBase extends AbstractKeyspaceIntegrationTestBase { private static final ObjectMapper MAPPER = new ObjectMapper(); + String removeNullValues(String doc) { + ObjectNode newNode = MAPPER.createObjectNode(); + JsonNode oldNode = null; + try { + oldNode = MAPPER.readTree(doc); + } catch (JsonProcessingException e) { + throw new IllegalArgumentException("Failed to parse JSON: " + doc, e); + } + oldNode + .fields() + .forEachRemaining( + entry -> { + JsonNode value = entry.getValue(); + if (!value.isNull()) { + newNode.putIfAbsent(entry.getKey(), value); + } + }); + return newNode.toString(); + } + // protected DataApiResponseValidator createTableWithColumns( // String tableName, Map columns, Object primaryKeyDef) { // return createTable( diff --git a/src/test/java/io/stargate/sgv2/jsonapi/api/v1/tables/FindOneTableIntegrationTest.java b/src/test/java/io/stargate/sgv2/jsonapi/api/v1/tables/FindOneTableIntegrationTest.java index b29112fe9..596b79580 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/api/v1/tables/FindOneTableIntegrationTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/api/v1/tables/FindOneTableIntegrationTest.java @@ -140,13 +140,15 @@ public void findOneSingleStringKey() { .wasSuccessful() .hasJSONField( "data.document", - """ + // By default, null values are not returned + removeNullValues( + """ { "id": "c", "age": null, "name": null } - """); + """)); } @Test @@ -255,7 +257,7 @@ public void findOneDocIdKey() { } """) .wasSuccessful() - .hasJSONField("data.document", DOC_B_JSON); + .hasJSONField("data.document", removeNullValues(DOC_B_JSON)); } } diff --git a/src/test/java/io/stargate/sgv2/jsonapi/api/v1/tables/UpdateTableIntegrationTest.java b/src/test/java/io/stargate/sgv2/jsonapi/api/v1/tables/UpdateTableIntegrationTest.java index fa8154a1d..8bc01312e 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/api/v1/tables/UpdateTableIntegrationTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/api/v1/tables/UpdateTableIntegrationTest.java @@ -289,7 +289,7 @@ public void unsetSuccessful() { .updateOne(FULL_PRIMARY_KEY_FILTER_DEFAULT_ROW, updateClauseJSON) .wasSuccessful() .hasNoWarnings(); - checkUpdatedData(FULL_PRIMARY_KEY_FILTER_DEFAULT_ROW, expectedUpdatedRow); + checkUpdatedData(FULL_PRIMARY_KEY_FILTER_DEFAULT_ROW, removeNullValues(expectedUpdatedRow)); } @Test