Thanks, i fill the issue.
https://issues.apache.org/jira/browse/CALCITE-5969

First off, can you create a jira case? This is clearly a bug.

I think AggregateCall.rexList is new and will need to be explicitly handled in serialization and deserialization. Testing shouldn’t be difficult if you extend or modify existing RelJson tests.

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 !

Reply via email to