code: def lower_has_substring_binary_compositions(ir_blocks):
      
      def visitor_fn(expression):
          """Rewrite BinaryComposition expressions with "has_substring" into representable form."""
          # The implementation of "has_substring" must use the LIKE operator in MATCH, and must
          # prepend and append "%" symbols to the substring being matched.
          # We transform any structures that resemble the following:
          #    BinaryComposition(u'has_substring', X, Y)
          # into the following:
          #    BinaryComposition(
          #        u'LIKE',
          #        X,
          #        BinaryComposition(
          #            u'+',
          #            Literal("%"),
          #            BinaryComposition(
          #                 u'+',
          #                 Y,
          #                 Literal("%")
          #            )
          #        )
          #    )
          if not isinstance(expression, BinaryComposition) or expression.operator != u'has_substring':
              return expression
  
          return BinaryComposition(
              u'LIKE',
              expression.left,
              BinaryComposition(
                  u'+',
                  Literal('%'),
                  BinaryComposition(
                      u'+',
                      expression.right,
                      Literal('%')
                  )
              )
          )
  
      new_ir_blocks = [
          block.visit_and_update_expressions(visitor_fn)
          for block in ir_blocks
      ]
  
      return new_ir_blocks
docs: Lower Filter blocks that use the "has_substring" operation into MATCH-representable form.