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