code: def extract_range_list_from_predicate(
      predicate: AbstractExpression, lower_bound: int, upper_bound: int
  ) -> List:
      """The function converts the range predicate on the column in the
          `predicate` to a list of [(start_1, end_1), ... ] pairs.
  
          It assumes the predicate contains conditions on only one column.
          It is the responsibility of the caller that `predicate` does not contains conditions on multiple columns.
  
      Args:
          predicate (AbstractExpression): Input predicate to extract
              valid ranges. The predicate should contain conditions on
              only one columns, else it raise error.
          lower_bound (int): lower bound of the comparison predicate
          upper_bound (int): upper bound of the comparison predicate
  
      Returns:
          List[Tuple]: list of (start, end) pairs of valid ranges
  
      Example:
              id < 10 : [(0, 9)]
              id > 5 AND id < 10 : [(6, 9)]
              id < 10 OR id >20 : [(0, 9), (21, Inf)]
      """
  
      def overlap(x, y):
          overlap = (max(x[0], y[0]), min(x[1], y[1]))
          if overlap[0] <= overlap[1]:
              return overlap
  
      def union(ranges: List):
          # union all the ranges
          reduced_list = []
          for begin, end in sorted(ranges):
              if reduced_list and reduced_list[-1][1] >= begin - 1:
                  reduced_list[-1] = (
                      reduced_list[-1][0],
                      max(reduced_list[-1][1], end),
                  )
              else:
                  reduced_list.append((begin, end))
          return reduced_list
  
      if predicate.etype == ExpressionType.LOGICAL_AND:
          left_ranges = extract_range_list_from_predicate(
              predicate.children[0], lower_bound, upper_bound
          )
          right_ranges = extract_range_list_from_predicate(
              predicate.children[1], lower_bound, upper_bound
          )
          valid_overlaps = []
          for left_range in left_ranges:
              for right_range in right_ranges:
                  over = overlap(left_range, right_range)
                  if over:
                      valid_overlaps.append(over)
          return union(valid_overlaps)
  
      elif predicate.etype == ExpressionType.LOGICAL_OR:
          left_ranges = extract_range_list_from_predicate(
              predicate.children[0], lower_bound, upper_bound
          )
          right_ranges = extract_range_list_from_predicate(
              predicate.children[1], lower_bound, upper_bound
          )
          return union(left_ranges + right_ranges)
  
      elif isinstance(predicate, ComparisonExpression):
          return union(
              extract_range_list_from_comparison_expr(
                  predicate, lower_bound, upper_bound
              )
          )
  
      else:
          raise RuntimeError(
              f"Contains unsupported expression {type(predicate)}"
          )
  
file_path: evadb/evadb/expression/expression_utils.py
imports: from typing import List, Set
  from evadb.expression.abstract_expression import AbstractExpression, ExpressionType
  from evadb.expression.comparison_expression import ComparisonExpression
  from evadb.expression.constant_value_expression import ConstantValueExpression
  from evadb.expression.logical_expression import LogicalExpression
  from evadb.expression.tuple_value_expression import TupleValueExpression
label_desc: Use image node_id 4 for calling a global function with example usage: extract_range_list_from_predicate(predicate, lower_bound, upper_bound) and returns: reduced_list, union, overlap, union, union