To whom concerns: when i use the avatica driver, found two bugs: one bug in protobuf serialization mode: 1.for org.apache.calcite.avatica.driver.remote.Service$CatalogsRequest,the response is org.apache.calcite.avatica.remote.Service$ResultSetResponse, and in Service$ResultSetResponse, the firstFrame is Meta$Frame(row is org.apache.calcite.avatica.driver.MetaImpl$MetaCatalog); 2.for org.apache.calcite.avatica.driver.remote.Service$SchemasRequest, the response is org.apache.calcite.avatica.remote.Service$ResultSetResponse, and in Service$ResultSetResponse, the firstFrame is Meta$Frame(row is org.apache.calcite.jdbc.CalciteMetaImpl$CalciteMetaSchema); 3.for org.apache.calcite.avatica.driver.remote.Service$TypeInfoRequest, the response is org.apache.calcite.avatica.remote.Service$ResultSetResponse, and in Service$ResultSetResponse, the firstFrame is Meta$Frame(row is org.apache.calcite.avatica.driver.MetaImpl$MetaTypeInfo); 4.for org.apache.calcite.avatica.driver.remote.Service$TableTypesRequest, the response is org.apache.calcite.avatica.remote.Service$ResultSetResponse, and in Service$ResultSetResponse, the firstFrame is Meta$Frame(row is org.apache.calcite.avatica.driver.MetaImpl$MetaTableType); all of above four types, in org.apache.calcite.avatica.driver.Meta$Frame, toProto()method throws new RuntimeException("Only arrays are supported") exception ,because MetaImpl$MetaCatalog??CalciteMetaImpl$CalciteMetaSchema?? MetaImpl$MetaTypeInfo??MetaImpl$MetaTableType are not instanceof Object[] or instanceof Iterable:
public static Common.Rep toProto(Common.TypedValue.Builder builder, Object o) { // Numbers if (o instanceof Byte) { writeToProtoWithType(builder, o, Common.Rep.BYTE); return Common.Rep.BYTE; } else if (o instanceof Short) { writeToProtoWithType(builder, o, Common.Rep.SHORT); return Common.Rep.SHORT; } else if (o instanceof Integer) { writeToProtoWithType(builder, o, Common.Rep.INTEGER); return Common.Rep.INTEGER; } else if (o instanceof Long) { writeToProtoWithType(builder, o, Common.Rep.LONG); return Common.Rep.LONG; } else if (o instanceof Double) { writeToProtoWithType(builder, o, Common.Rep.DOUBLE); return Common.Rep.DOUBLE; } else if (o instanceof Float) { writeToProtoWithType(builder, ((Float) o).longValue(), Common.Rep.FLOAT); return Common.Rep.FLOAT; } else if (o instanceof BigDecimal) { writeToProtoWithType(builder, o, Common.Rep.BIG_DECIMAL); return Common.Rep.BIG_DECIMAL; // Strings } else if (o instanceof String) { writeToProtoWithType(builder, o, Common.Rep.STRING); return Common.Rep.STRING; } else if (o instanceof Character) { writeToProtoWithType(builder, o.toString(), Common.Rep.CHARACTER); return Common.Rep.CHARACTER; // Bytes } else if (o instanceof byte[]) { writeToProtoWithType(builder, o, Common.Rep.BYTE_STRING); return Common.Rep.BYTE_STRING; // Boolean } else if (o instanceof Boolean) { writeToProtoWithType(builder, o, Common.Rep.BOOLEAN); return Common.Rep.BOOLEAN; } else if (o instanceof Timestamp) { writeToProtoWithType(builder, o, Common.Rep.JAVA_SQL_TIMESTAMP); return Common.Rep.JAVA_SQL_TIMESTAMP; } else if (o instanceof Date) { writeToProtoWithType(builder, o, Common.Rep.JAVA_SQL_DATE); return Common.Rep.JAVA_SQL_DATE; } else if (o instanceof Time) { writeToProtoWithType(builder, o, Common.Rep.JAVA_SQL_TIME); return Common.Rep.JAVA_SQL_TIME; } else if (o instanceof List) { // Treat a List as an Array builder.setType(Common.Rep.ARRAY); builder.setComponentType(Common.Rep.OBJECT); boolean setComponentType = false; for (Object listElement : (List<?>) o) { Common.TypedValue.Builder listElementBuilder = Common.TypedValue.newBuilder(); // Recurse on each list element Common.Rep componentRep = toProto(listElementBuilder, listElement); if (!setComponentType) { if (Common.Rep.NULL != componentRep) { builder.setComponentType(componentRep); } setComponentType = true; } builder.addArrayValue(listElementBuilder.build()); } return Common.Rep.ARRAY; } else if (o instanceof Array) { builder.setType(Common.Rep.ARRAY); Array a = (Array) o; try { ResultSet rs = a.getResultSet(); builder.setComponentType(Common.Rep.OBJECT); boolean setComponentType = false; while (rs.next()) { Common.TypedValue.Builder listElementBuilder = Common.TypedValue.newBuilder(); Object arrayValue = rs.getObject(2); Common.Rep componentRep = toProto(listElementBuilder, arrayValue); if (!setComponentType) { if (Common.Rep.NULL != componentRep) { builder.setComponentType(componentRep); } setComponentType = true; } builder.addArrayValue(listElementBuilder.build()); } } catch (SQLException e) { throw new RuntimeException("Could not serialize ARRAY", e); } return Common.Rep.ARRAY; } else if (null == o) { writeToProtoWithType(builder, o, Common.Rep.NULL); return Common.Rep.NULL; // Unhandled } else { throw new RuntimeException("Unhandled type in Frame: " + o.getClass()); } } another bug is: it does not support clob ,blob : in json serialization mode: for tables have a clob or blob datatype, throws JsonMappingException: Direct self-reference leading to cycle (through reference chain: org.apache.calcite.avatica.driver.remote.Service$FetchResponse["frame"]->org.apache.calcite.avatica.driver.Meta$Frame["rows"]->java.util.ArrayList[0]->java.util.Arrays$ArrayList[1]->oracle.sql.CLOB["dbaccess"]->oracle.jdbc.driver.T4CConnection["wrapper"]) [SQL State=00000, DB Errorcode=-1] in protobuf serialization mode: for tables have a clob or blob datatype, throws Remote driver error: RuntimeException: Unhandled type in Frame: class oracle.sql.CLOB [SQL State=00000, DB Errorcode=-1] 1 statement failed. please confirm the above two bugs, and let me know when to fix them, thanks a lot. Best regards. Victor Lv