@Override
  protected void serializeAttributes(ByteBuffer byteBuffer) {
    PlanNodeType.TABLE_JOIN_NODE.serialize(byteBuffer);

    ReadWriteIOUtils.write(joinType.ordinal(), byteBuffer);

    ReadWriteIOUtils.write(criteria.size(), byteBuffer);
    for (EquiJoinClause equiJoinClause : criteria) {
      Symbol.serialize(equiJoinClause.getLeft(), byteBuffer);
      Symbol.serialize(equiJoinClause.getRight(), byteBuffer);
    }

    if (asofCriteria.isPresent()) {
      ReadWriteIOUtils.write(true, byteBuffer);
      AsofJoinClause asofJoinClause = asofCriteria.get();
      ReadWriteIOUtils.write(asofJoinClause.getOperator().ordinal(), byteBuffer);
      Symbol.serialize(asofJoinClause.getLeft(), byteBuffer);
      Symbol.serialize(asofJoinClause.getRight(), byteBuffer);
    } else {
      ReadWriteIOUtils.write(false, byteBuffer);
    }

    ReadWriteIOUtils.write(leftOutputSymbols.size(), byteBuffer);
    for (Symbol leftOutputSymbol : leftOutputSymbols) {
      Symbol.serialize(leftOutputSymbol, byteBuffer);
    }
    ReadWriteIOUtils.write(rightOutputSymbols.size(), byteBuffer);
    for (Symbol rightOutputSymbol : rightOutputSymbols) {
      Symbol.serialize(rightOutputSymbol, byteBuffer);
    }
  }
@return a new JoinNode with the flipped attributes
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/JoinNode.java