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 <[email protected]> > 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 !
