code: def __str__(self) -> str:
      if self.predicate is not None:
          return "{} {} {} ON {}".format(
              self.left, self.join_type, self.right, self.predicate
          )
      else:
          return "{} {} {}".format(
              self.left, self.join_type, self.right
          )
  
imports: from __future__ import annotations
  from typing import Union
  from evadb.expression.abstract_expression import AbstractExpression
  from evadb.expression.function_expression import FunctionExpression
  from evadb.parser.alias import Alias
  from evadb.parser.select_statement import SelectStatement
  from evadb.parser.types import JoinType
label_desc: Use image node_id 3 for calling the JoinNode obj's underlying member method code with example usage: obj.__str__() and returns: str, str