[ 
https://issues.apache.org/jira/browse/GEODE-9174?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Owen Nichols closed GEODE-9174.
-------------------------------

> The result of a gfsh query containing a UUID may not be displayed properly
> --------------------------------------------------------------------------
>
>                 Key: GEODE-9174
>                 URL: https://issues.apache.org/jira/browse/GEODE-9174
>             Project: Geode
>          Issue Type: Bug
>          Components: gfsh, querying
>            Reporter: Barrett Oglesby
>            Assignee: Mario Kevo
>            Priority: Major
>              Labels: pull-request-available
>             Fix For: 1.15.0
>
>
> For example, if the key is a UUID, then a query like this won't show the 
> results even though there is one:
> {noformat}
> gfsh>query --query="select key from /data.entries where value.id = 
> '55e907b6-a1fe-42ea-90a2-6a5698e9b27c'"
> Result : true
> Limit  : 100
> Rows   : 1
> {noformat}
> But a query like this will:
> {noformat}
> gfsh>query --query="select key,value from /data.entries where value.id = 
> '55e907b6-a1fe-42ea-90a2-6a5698e9b27c'"
> Result : true
> Limit  : 100
> Rows   : 1
>                  key                   | value
> -------------------------------------- | 
> ---------------------------------------------------------------------------------------
> "55e907b6-a1fe-42ea-90a2-6a5698e9b27c" | 
> {"id":"55e907b6-a1fe-42ea-90a2-6a5698e9b27c","cusip":"AAPL","shares":22,"price":352.32}
> {noformat}
> Thats because of the way {{DataCommandResult.resolveObjectToColumns}} works.
> {noformat}
> private void resolveObjectToColumns(Map<String, String> columnData, Object 
> value) {
>   if (value instanceof PdxInstance) {
>     resolvePdxToColumns(columnData, (PdxInstance) value);
>   } else if (value instanceof Struct) {
>     resolveStructToColumns(columnData, (StructImpl) value);
>   } else {
>     ObjectMapper mapper = new ObjectMapper();
>     JsonNode node = mapper.valueToTree(value);
>     node.fieldNames().forEachRemaining(field -> {
>       ...
>       columnData.put(field, mapper.writeValueAsString(node.get(field)));
>     });
>   }
> }
> {noformat}
> The value in the first query is a {{UUID}} so the last else clause is 
> invoked. In this case, a {{JsonNode}} is used to determine the columns. 
> {{ObjectMapper.valueToTree}} converts a {{UUID}} to a {{TextNode}}. 
> {{TextNodes}} have no fieldNames, and {{JsonNode.fieldNames}} returns an 
> {{EmptyIterator}} by default:
> {noformat}
> public Iterator<String> fieldNames() {
>   return ClassUtil.emptyIterator();
> }
> {noformat}
> So, {{resolveObjectToColumns}} doesn't fill in columnData, which causes the 
> {{DataCommandResult.buildTable}} in the locator to not add any rows to the 
> table.
> The value in the second query is a {{Struct}} so the second else clause is 
> invoked. The {{resolveStructToColumns}} method does:
> {noformat}
> private void resolveStructToColumns(Map<String, String> columnData, 
> StructImpl struct) {
>   for (String field : struct.getFieldNames()) {
>     columnData.put(field, valueToJson(struct.get(field)));
>   }
> }
> {noformat}
> I'm not sure if there is a way to make {{ObjectMapper.valueToTree}} handle 
> {{UUIDs}} differently, but they can easily be special-cased like 
> {{PdxInstances}} and {{Structs}}:
> {noformat}
> } else if (value instanceof UUID) {
>   columnData.put("uuid", valueToJson(value));
> {noformat}
> I'm not sure if this is the best solution, but it works. With this clause 
> added, the query does:
> {noformat}
> gfsh>query --query="select key from /data.entries where value.id = 
> '55e907b6-a1fe-42ea-90a2-6a5698e9b27c'"
> Result : true
> Limit  : 100
> Rows   : 1
> uuid
> --------------------------------------
> "55e907b6-a1fe-42ea-90a2-6a5698e9b27c"
> {noformat}



--
This message was sent by Atlassian Jira
(v8.20.7#820007)

Reply via email to