Yes, it’s possible. 

But my concern is the lack of common approach. Here a few examples:

1) Correlate and Join both explains joinType as lowerName of enum’s value, 
hence it could be simply restored by relInput.getEnum("joinType", 
JoinRelType.class)

  @Override public RelWriter explainTerms(RelWriter pw) {
    return super.explainTerms(pw)
        .item("joinType", joinType.lowerName)
                ...
  } 

2) MultiJoin uses similar approach, but instead of lowerName uses original 
enum’s name

  @Override public RelWriter explainTerms(RelWriter pw) {
    List<String> joinTypeNames = new ArrayList<>();
                ...
    for (int i = 0; i < inputs.size(); i++) {
      joinTypeNames.add(joinTypes.get(i).name());
                ...
    }

    return pw.item("joinFilter", joinFilter)
                ...
        .item("joinTypes", joinTypeNames)
                ...
  }

3) TableModify uses RelEnumTypes.fromEnum(getOperation())) to explain operation 
type, but uses input.getEnum("operation", Operation.class) to restore it,
whereas there is RelEnumTypes#toEnum(String) method

4) Spool explains both types as enum value, and probably will fail during 
serialisation to json cause 
org.apache.calcite.rel.externalize.RelJson#toJson(java.lang.Object)
doesn’t know how to handle enum

  @Override public RelWriter explainTerms(RelWriter pw) {
    return super.explainTerms(pw)
        .item("readType", readType)
        .item("writeType", writeType);
  }

Does it make any sense to unify this?


-- 
Regards,
Konstantin Orlov




> On 8 Jun 2021, at 22:03, Julian Hyde <[email protected]> wrote:
> 
> Including class names in serialized JSON makes me nervous. It is a common 
> attack surface. Could we, say, include the name of the enum (without package 
> name) and map it to a list of supported Enums?
> 
>> On Jun 8, 2021, at 9:20 AM, Konstantin Orlov <[email protected]> wrote:
>> 
>> Hi, folks!
>> 
>> We have a problem with Spool node deserialisation. Currently it explains 
>> both readType and writeType fields as Enum,
>> thus those fields being serialized as map:
>> 
>>     {
>>        "id":"2",
>>        "relOp”:"MyTableSpool",
>>        "readType":{
>>           "class":"org.apache.calcite.rel.core.Spool$Type",
>>           "name":"LAZY"
>>        },
>>        "writeType":{
>>           "class":"org.apache.calcite.rel.core.Spool$Type",
>>           "name":"EAGER"
>>        }
>>     }
>> 
>> When deserializing, we use RelInput#getEnum which expects the provided tag 
>> being a string value representing the enum's value name.
>> 
>> Should we follow the way used for serialization of JoinRelType within the 
>> Join node (serialize the enum value as its name in lower case)? Here is 
>> example:
>> 
>>     {
>>        "id":"4",
>>        "relOp”:"MyJoin",
>>        "condition":{
>>           "op":{
>>              "name":">",
>>              "kind":"SqlKind#GREATER_THAN",
>>              "syntax":"SqlSyntax#BINARY"
>>           },
>>           "operands":[
>>              {
>>                 "input":1,
>>                 "name":"$1"
>>              },
>>              {
>>                 "input":4,
>>                 "name":"$4"
>>              }
>>           ]
>>        },
>>        "joinType":"inner",
>>        "variablesSet":[0],
>>        "correlationVariables":[0],
>>        "inputs":["0","3"]
>>     }
>> 
>> Or it's better to get the RelInput being able to deserialize enum 
>> represented as map as well?
>> 
>> Personally I prefer the first option cause the type of the enum is known for 
>> sure, so it's better not to waste the time to (de-)serialize it.
>> 
>> 
>> -- 
>> Regards,
>> Konstantin Orlov
>> 
>> 
>> 
>> 
> 

Reply via email to