'Returns the list of columns to use in the select statement. If no
columns have been specified, returns all columns relating to fields in
the model.
If \'with_aliases\' is true, any column names that are duplicated
(without the table names) are given unique aliases. This is needed in
some cases to avoid ambiguity with nested queries.'

def get_columns(self, with_aliases=False):

    qn = self.quote_name_unless_alias
    qn2 = self.connection.ops.quote_name
    result = [('(%s)    AS    %s' % (col[0], qn2(alias))) for (alias, col) in self.query.extra_select.iteritems()]
    aliases = set(self.query.extra_select.keys())
    if with_aliases:
        col_aliases = aliases.copy()
    else:
        col_aliases = set()
    if self.query.select:
        only_load = self.deferred_to_columns()
        for col in self.query.select:
            if isinstance(col, (list, tuple)):
                (alias, column) = col
                table = self.query.alias_map[alias][TABLE_NAME]
                if ((table in only_load) and (col not in only_load[table])):
                    continue
                r = ('%s.%s' % (qn(alias), qn(column)))
                if with_aliases:
                    if (col[1] in col_aliases):
                        c_alias = ('Col%d' % len(col_aliases))
                        result.append(('%s    AS    %s' % (r, c_alias)))
                        aliases.add(c_alias)
                        col_aliases.add(c_alias)
                    else:
                        result.append(('%s    AS    %s' % (r, qn2(col[1]))))
                        aliases.add(r)
                        col_aliases.add(col[1])
                else:
                    result.append(r)
                    aliases.add(r)
                    col_aliases.add(col[1])
            else:
                result.append(col.as_sql(qn, self.connection))
                if hasattr(col, 'alias'):
                    aliases.add(col.alias)
                    col_aliases.add(col.alias)
    elif self.query.default_cols:
        (cols, new_aliases) = self.get_default_columns(with_aliases, col_aliases)
        result.extend(cols)
        aliases.update(new_aliases)
    max_name_length = self.connection.ops.max_name_length()
    result.extend([('%s%s' % (aggregate.as_sql(qn, self.connection), (((alias is not None) and ('    AS    %s' % qn(truncate_name(alias, max_name_length)))) or ''))) for (alias, aggregate) in self.query.aggregate_select.items()])
    for (table, col) in self.query.related_select_cols:
        r = ('%s.%s' % (qn(table), qn(col)))
        if (with_aliases and (col in col_aliases)):
            c_alias = ('Col%d' % len(col_aliases))
            result.append(('%s    AS    %s' % (r, c_alias)))
            aliases.add(c_alias)
            col_aliases.add(c_alias)
        else:
            result.append(r)
            aliases.add(r)
            col_aliases.add(col)
    self._select_aliases = aliases
    return result
