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