docs: def as_salesforce(self, compiler, connection):
          """
          Return the SQL version of the where clause and the value to be
          substituted in. Return '', [] if this node matches everything,
          None, [] if this node is empty, and raise EmptyResultSet if this
          node can't match anything.
          """
  
          # *** patch 1 (add) begin
          # # prepare SOQL translations
          if not isinstance(compiler, SQLCompiler):
              # future fix for DJANGO_20_PLUS, when deprecated "use_for_related_fields"
              # removed from managers,
              # "str(<UpdateQuery...>)" or "<UpdateQuery...>.get_compiler('default').as_sql()"
              return super(SalesforceWhereNode, self).as_sql(compiler, connection)
          soql_trans = compiler.query_topology()
          # *** patch 1 end
  
          result = []
          result_params = []
          if self.connector == AND:
              full_needed, empty_needed = len(self.children), 1
          else:
              full_needed, empty_needed = 1, len(self.children)
  
          for child in self.children:
              try:
                  sql, params = compiler.compile(child)
              except EmptyResultSet:
                  empty_needed -= 1
              else:
                  if sql:
  
                      # *** patch 2 (add) begin
                      # # translate the alias of child to SOQL name
                      x_match = re.match(r'(\w+)\.(.*)', sql)
                      if x_match:
                          x_table, x_field = x_match.groups()
                          sql = '%s.%s' % (soql_trans[x_table], x_field)
                          # print('sql params:', sql, params)
                      # *** patch 2 end
  
                      result.append(sql)
                      result_params.extend(params)
                  else:
                      full_needed -= 1
              # Check if this node matches nothing or everything.
              # First check the amount of full nodes and empty nodes
              # to make this node empty/full.
              # Now, check if this node is full/empty using the
              # counts.
              if empty_needed == 0:
                  if self.negated:
                      return '', []
                  else:
                      raise EmptyResultSet
              if full_needed == 0:
                  if self.negated:
                      raise EmptyResultSet
                  else:
                      return '', []
          conn = ' %s ' % self.connector
          sql_string = conn.join(result)
          if sql_string:
              if self.negated:
                  # *** patch 3 (remove) begin
                  # # Some backends (Oracle at least) need parentheses
                  # # around the inner SQL in the negated case, even if the
                  # # inner SQL contains just a single expression.
                  # sql_string = 'NOT (%s)' % sql_string
                  # *** patch 3 (add)
                  # SOQL requires parentheses around "NOT" expression, if combined with AND/OR
                  sql_string = '(NOT (%s))' % sql_string
                  # *** patch 3 end
  
              # *** patch 4 (combine two versions into one compatible) begin
              # elif len(result) > 1:                                    # Django 1.10, 1.11
              # elif len(result) > 1 or self.resolved:                   # Django 2.0, 2.1
              elif len(result) > 1 or getattr(self, 'resolved', False):  # compatible code
                  # *** patch 4 end
  
                  sql_string = '(%s)' % sql_string
          return sql_string, result_params