'Create the SQL for this query. Return the SQL string and list of
parameters.
If \'with_limits\' is False, any limit/offset information is not included
in the query.'

def as_sql(self, with_limits=True, with_col_aliases=False):

    refcounts_before = self.query.alias_refcount.copy()
    try:
        (extra_select, order_by, group_by) = self.pre_sql_setup()
        for_update_part = None
        combinator = self.query.combinator
        features = self.connection.features
        if combinator:
            if (not getattr(features, 'supports_select_{}'.format(combinator))):
                raise NotSupportedError('{}    is    not    supported    on    this    database    backend.'.format(combinator))
            (result, params) = self.get_combinator_sql(combinator, self.query.combinator_all)
        else:
            distinct_fields = self.get_distinct()
            (from_, f_params) = self.get_from_clause()
            (where, w_params) = (self.compile(self.where) if (self.where is not None) else ('', []))
            (having, h_params) = (self.compile(self.having) if (self.having is not None) else ('', []))
            result = ['SELECT']
            params = []
            if self.query.distinct:
                result.append(self.connection.ops.distinct_sql(distinct_fields))
            out_cols = []
            col_idx = 1
            for (_, (s_sql, s_params), alias) in (self.select + extra_select):
                if alias:
                    s_sql = ('%s    AS    %s' % (s_sql, self.connection.ops.quote_name(alias)))
                elif with_col_aliases:
                    s_sql = ('%s    AS    %s' % (s_sql, ('Col%d' % col_idx)))
                    col_idx += 1
                params.extend(s_params)
                out_cols.append(s_sql)
            result.append(',    '.join(out_cols))
            result.append('FROM')
            result.extend(from_)
            params.extend(f_params)
            if (self.query.select_for_update and self.connection.features.has_select_for_update):
                if self.connection.get_autocommit():
                    raise TransactionManagementError('select_for_update    cannot    be    used    outside    of    a    transaction.')
                if (with_limits and (not self.connection.features.supports_select_for_update_with_limit)):
                    raise NotSupportedError('LIMIT/OFFSET    is    not    supported    with    select_for_update    on    this    database    backend.')
                nowait = self.query.select_for_update_nowait
                skip_locked = self.query.select_for_update_skip_locked
                of = self.query.select_for_update_of
                if (nowait and (not self.connection.features.has_select_for_update_nowait)):
                    raise NotSupportedError('NOWAIT    is    not    supported    on    this    database    backend.')
                elif (skip_locked and (not self.connection.features.has_select_for_update_skip_locked)):
                    raise NotSupportedError('SKIP    LOCKED    is    not    supported    on    this    database    backend.')
                elif (of and (not self.connection.features.has_select_for_update_of)):
                    raise NotSupportedError('FOR    UPDATE    OF    is    not    supported    on    this    database    backend.')
                for_update_part = self.connection.ops.for_update_sql(nowait=nowait, skip_locked=skip_locked, of=self.get_select_for_update_of_arguments())
            if (for_update_part and self.connection.features.for_update_after_from):
                result.append(for_update_part)
            if where:
                result.append(('WHERE    %s' % where))
                params.extend(w_params)
            grouping = []
            for (g_sql, g_params) in group_by:
                grouping.append(g_sql)
                params.extend(g_params)
            if grouping:
                if distinct_fields:
                    raise NotImplementedError('annotate()    +    distinct(fields)    is    not    implemented.')
                if (not order_by):
                    order_by = self.connection.ops.force_no_ordering()
                result.append(('GROUP    BY    %s' % ',    '.join(grouping)))
            if having:
                result.append(('HAVING    %s' % having))
                params.extend(h_params)
        if order_by:
            ordering = []
            for (_, (o_sql, o_params, _)) in order_by:
                ordering.append(o_sql)
                params.extend(o_params)
            result.append(('ORDER    BY    %s' % ',    '.join(ordering)))
        if with_limits:
            if (self.query.high_mark is not None):
                result.append(('LIMIT    %d' % (self.query.high_mark - self.query.low_mark)))
            if self.query.low_mark:
                if (self.query.high_mark is None):
                    val = self.connection.ops.no_limit_value()
                    if val:
                        result.append(('LIMIT    %d' % val))
                result.append(('OFFSET    %d' % self.query.low_mark))
        if (for_update_part and (not self.connection.features.for_update_after_from)):
            result.append(for_update_part)
        if (self.query.subquery and extra_select):
            sub_selects = []
            sub_params = []
            for (select, _, alias) in self.select:
                if alias:
                    sub_selects.append(('%s.%s' % (self.connection.ops.quote_name('subquery'), self.connection.ops.quote_name(alias))))
                else:
                    select_clone = select.relabeled_clone({select.alias: 'subquery'})
                    (subselect, subparams) = select_clone.as_sql(self, self.connection)
                    sub_selects.append(subselect)
                    sub_params.extend(subparams)
            return (('SELECT    %s    FROM    (%s)    AS    subquery' % (',    '.join(sub_selects), '    '.join(result))), (sub_params + params))
        return ('    '.join(result), tuple(params))
    finally:
        self.query.reset_refcounts(refcounts_before)
