docs: def _make_condition(self, arg):
          """
          Translate the input arg into the equivalent SQL condition (a string)
          :param arg: any valid restriction object.
          :return: an SQL condition string or a boolean value.
          """
          def prep_value(v):
              return str(v) if isinstance(v, (datetime.date, datetime.datetime, datetime.time, decimal.Decimal)) else v
  
          negate = False
          while isinstance(arg, Not):
              negate = not negate
              arg = arg.restriction
          template = "NOT (%s)" if negate else "%s"
  
          # restrict by string
          if isinstance(arg, str):
              return template % arg.strip().replace("%", "%%")  # escape % in strings, see issue #376
  
          # restrict by AndList
          if isinstance(arg, AndList):
              # omit all conditions that evaluate to True
              items = [item for item in (self._make_condition(i) for i in arg) if item is not True]
              if any(item is False for item in items):
                  return negate  # if any item is False, the whole thing is False
              if not items:
                  return not negate   # and empty AndList is True
              return template % ('(' + ') AND ('.join(items) + ')')
  
          # restriction by dj.U evaluates to True
          if isinstance(arg, U):
              return not negate
  
          # restrict by boolean
          if isinstance(arg, bool):
              return negate != arg
  
          # restrict by a mapping such as a dict -- convert to an AndList of string equality conditions
          if isinstance(arg, collections.abc.Mapping):
              return template % self._make_condition(
                  AndList('`%s`=%r' % (k, prep_value(v)) for k, v in arg.items() if k in self.heading))
  
          # restrict by a numpy record -- convert to an AndList of string equality conditions
          if isinstance(arg, np.void):
              return template % self._make_condition(
                  AndList(('`%s`=%r' % (k, prep_value(arg[k])) for k in arg.dtype.fields if k in self.heading)))
  
          # restrict by a QueryExpression subclass -- triggers instantiation
          if inspect.isclass(arg) and issubclass(arg, QueryExpression):
              arg = arg()
  
          # restrict by another expression (aka semijoin and antijoin)
          if isinstance(arg, QueryExpression):
              assert_join_compatibility(self, arg)
              common_attributes = [q for q in arg.heading.names if q in self.heading.names]
              return (
                  # without common attributes, any non-empty set matches everything
                  (not negate if arg else negate) if not common_attributes
                  else '({fields}) {not_}in ({subquery})'.format(
                      fields='`' + '`,`'.join(common_attributes) + '`',
                      not_="not " if negate else "",
                      subquery=arg.make_sql(common_attributes)))
  
          # restrict by pandas.DataFrames
          if isinstance(arg, pandas.DataFrame):
              arg = arg.to_records()   # convert to np.recarray
  
          # if iterable (but not a string, a QueryExpression, or an AndList), treat as an OrList
          try:
              or_list = [self._make_condition(q) for q in arg]
          except TypeError:
              raise DataJointError('Invalid restriction type %r' % arg)
          else:
              or_list = [item for item in or_list if item is not False]  # ignore all False conditions
              if any(item is True for item in or_list):  # if any item is True, the whole thing is True
                  return not negate
              return template % ('(%s)' % ' OR '.join(or_list)) if or_list else negate