[ 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)