On Aug 28, 2023, at 7:30 AM, stanilovsky evgeny
<estanilovs...@gridgain.com> wrote:
hello, please can someone explain me how LITERAL_AGG need to be
correctly serialized\deserealized and how to write appropriate tests.
Problem :
we have LITERAL_AGG
further:
toJson(org.apache.calcite.rel.core.AggregateCall) {
Map<String, Object> map = map();
map.put("agg", toJson(node.getAggregation()));
map.put("type", toJson(node.getType()));
map.put("distinct", node.isDistinct());
map.put("operands", node.getArgList());
map.put("filter", node.filterArg);
map.put("name", node.getName());
return map;
}
not serialized "rexList" here ^
deserialization part:
RelJsonReader#toAggCall(Map<String, Object> jsonAggCall) {
... cut ...
return AggregateCall.create(aggregation, distinct, false, false,
ImmutableList.of(), <-- empty list
operands,
filterOperand == null ? -1 : filterOperand,
null, RelCollations.EMPTY, type, name);
}
used ImmutableList.of() instead of "rexList" (no place where we can
obtain it here, ok)
and further call for assembly:
public static AggregateCall create(...
...
final List<RelDataType> preTypes = RexUtil.types(rexList); <- pre
types are empty
final List<RelDataType> types =
SqlTypeUtil.projectTypes(input.getRowType(), argList); <-
argList is empty too
final Aggregate.AggCallBinding callBinding =
new Aggregate.AggCallBinding(typeFactory, aggFunction,
preTypes,
types, groupCount, filterArg >= 0);
type = aggFunction.inferReturnType(callBinding);
private static RelDataType inferReturnType(SqlOperatorBinding
opBinding) {
// LITERAL_AGG takes one pre-operand and zero (post-)operands.
if (opBinding.getPreOperandCount() != 1
|| opBinding.getOperandCount() != 1) {
throw new AssertionError(); <-- brings this assertion
}
return opBinding.getOperandType(0);
}
it`s not clear for me how to write test for such a case.
I realize that description is probably not clear but i tried to make it
as informative as i can.
If all above is not clear, brief question : how to write
serizlization\deserialization tests for such Operands, yes i found
RelWriterTest but it still unclear for me:
@Test void testWriter1() {
int i = Frameworks.withPlanner((cluster, relOptSchema, rootSchema)
-> {
final RelDataTypeFactory typeFactory = cluster.getTypeFactory();
RelDataTypeField field = new RelDataTypeFieldImpl(
"ID", 0, typeFactory.createSqlType(SqlTypeName.INTEGER)
);
RelRecordType rowType = new
RelRecordType(Collections.singletonList(field));
RelOptAbstractTable t1 = new RelOptAbstractTable(null, "t1",
rowType) {
@Override
public <T> T unwrap(Class<T> clazz) {
return null;
}
};
LogicalTableScan lt = new LogicalTableScan(cluster, null,
List.of(), t1);
RelDataTypeSystem typeSys =
cluster.getTypeFactory().getTypeSystem();
SqlBasicAggFunction literalFunc = SqlLiteralAggFunction.INSTANCE;
RexLiteral rex = RexLiteral.fromJdbcString(
new BasicSqlType(typeSys, SqlTypeName.BOOLEAN),
SqlTypeName.BOOLEAN, "true");
AggregateCall type = AggregateCall.create(literalFunc, false,
false, false, List.of(rex),
ImmutableList.of(), -1, null,
RelCollations.of(new RelFieldCollation(1)), new
BasicSqlType(typeSys, SqlTypeName.BOOLEAN), "i");
LogicalAggregate la = new LogicalAggregate(cluster, null,
List.of(), lt, ImmutableBitSet.of(), null, List.of(type));
final JsonBuilder jsonBuilder = new JsonBuilder();
final RelJson json = RelJson.create().withJsonBuilder(jsonBuilder);
final Object o = json.toJson(la);
assertThat(o, notNullValue());
final String s = jsonBuilder.toJsonString(o);
//final String expectedJson = "";
//assertThat(s, is(expectedJson));
final RelDataType type2 = json.toType(typeFactory, o);
assertThat(type2, is(type));
return 0;
});
}
Thanks !