private ResultTree extractResultTree(final ResultSet set) throws SQLException {
LOG.trace("Extracting result tree");
// cast to obtain more information from the result set.
final Jdbc4ResultSet pgSet = (Jdbc4ResultSet) set;
final ResultSetMetaData rsMetaData = pgSet.getMetaData();
final ResultTree tree = new ResultTree();
for (int i = 1; i <= rsMetaData.getColumnCount(); i++) {
final int typeId = pgSet.getColumnOID(i);
DbResultNode node = null;
final Object obj = pgSet.getObject(i);
final String name = rsMetaData.getColumnName(i);
// TODO pribeiro We should use polymorphism here. Build like a chain
if ((obj instanceof PGobject) && ((PGobject) obj).getType().equals("record")) {
final PGobject pgObj = (PGobject) obj;
final DbFunction function = DbFunctionRegister.getFunction(name, pgSet.getStatement().getConnection());
List<String> fieldValues;
try {
fieldValues = ParseUtils.postgresROW2StringList(pgObj.getValue());
} catch (final RowParserException e) {
throw new SQLException(e);
}
int j = 1;
for (final String fieldValue : fieldValues) {
final DbTypeField fieldDef = function.getFieldByPos(j);
DbResultNode currentNode = null;
if (fieldDef.getType().equals("USER-DEFINED")) {
currentNode = new ObjectResultNode(fieldValue, fieldDef.getName(), fieldDef.getTypeName(),
fieldDef.getTypeId(), pgSet.getStatement().getConnection());
} else if (fieldDef.getType().equals("ARRAY")) {
currentNode = new ArrayResultNode(fieldDef.getName(), fieldValue,
fieldDef.getTypeName().substring(1), fieldDef.getTypeId(),
pgSet.getStatement().getConnection());
} else {
currentNode = new SimpleResultNode(fieldValue, fieldDef.getName());
}
tree.addChild(currentNode);
j++;
}
i++;
continue;
} else if (obj instanceof Map) {
node = new MapResultNode((Map<String, String>) obj, name);
} else if (obj instanceof PGobject) {
final PGobject pgObj = (PGobject) obj;
node = new ObjectResultNode(pgObj.getValue(), name, pgObj.getType(), typeId,
pgSet.getStatement().getConnection());
} else if (obj instanceof Jdbc4Array) {
final Jdbc4Array arrayObj = (Jdbc4Array) obj;
// TODO pribeiro jdbc driver lacks support for arrays of user defined types. We should whether
// implement the missing feature in driver or use the current approach (parse string).
final String typeName = arrayObj.getBaseTypeName();
final String value = arrayObj.toString();
node = new ArrayResultNode(name, value, typeName, typeId, pgSet.getStatement().getConnection());
} else {
node = new SimpleResultNode(obj, name);
}
tree.addChild(node);