Django

Code

Changeset 7457

Show
Ignore:
Timestamp:
04/25/08 01:54:35 (2 months ago)
Author:
mtredinnick
Message:

queryset-refactor: An attempt to fix an ambiguous column error that can arise
in Oracle queries. Adds an options to add output column aliases.

The testing I can do shows that the query is being constructed correctly. I
haven't run the test against an Oracle install, though.

Refs #7057 (ticket can be closed if the Oracle tests pass).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/queryset-refactor/django/db/backends/oracle/query.py

    r7443 r7457  
    7373            return values 
    7474 
    75         def as_sql(self, with_limits=True): 
     75        def as_sql(self, with_limits=True, with_col_aliases=False): 
    7676            """ 
    7777            Creates the SQL for this query. Returns the SQL string and list 
     
    8989            # `as_sql`. 
    9090            if not do_offset: 
    91                 return super(OracleQuery, self).as_sql(with_limits=False) 
     91                return super(OracleQuery, self).as_sql(with_limits=False, 
     92                        with_col_aliases=with_col_aliases) 
    9293 
    9394            # `get_columns` needs to be called before `get_ordering` to 
     
    111112            # extra selection SQL. 
    112113            self.extra_select['rn'] = 'ROW_NUMBER() OVER (ORDER BY %s )' % rn_orderby 
    113             sql, params= super(OracleQuery, self).as_sql(with_limits=False) 
     114            sql, params= super(OracleQuery, self).as_sql(with_limits=False, 
     115                    with_col_aliases=True) 
    114116 
    115117            # Constructing the result SQL, using the initial select SQL 
  • django/branches/queryset-refactor/django/db/models/sql/query.py

    r7455 r7457  
    207207        return number 
    208208 
    209     def as_sql(self, with_limits=True): 
     209    def as_sql(self, with_limits=True, with_col_aliases=False): 
    210210        """ 
    211211        Creates the SQL for this query. Returns the SQL string and list of 
     
    216216        """ 
    217217        self.pre_sql_setup() 
    218         out_cols = self.get_columns(
     218        out_cols = self.get_columns(with_col_aliases
    219219        ordering = self.get_ordering() 
    220220 
     
    355355            self.fill_related_selections() 
    356356 
    357     def get_columns(self): 
     357    def get_columns(self, with_aliases=False): 
    358358        """ 
    359359        Return the list of columns to use in the select statement. If no 
    360360        columns have been specified, returns all columns relating to fields in 
    361361        the model. 
     362 
     363        If 'with_aliases' is true, any column names that are duplicated 
     364        (without the table names) are given unique aliases. This is needed in 
     365        some cases to avoid ambiguitity with nested queries. 
    362366        """ 
    363367        qn = self.quote_name_unless_alias 
    364368        result = ['(%s) AS %s' % (col, alias) for alias, col in self.extra_select.iteritems()] 
    365369        aliases = self.extra_select.keys() 
     370        if with_aliases: 
     371            col_aliases = set(aliases) 
     372        else: 
     373            col_aliases = set() 
    366374        if self.select: 
    367375            for col in self.select: 
    368376                if isinstance(col, (list, tuple)): 
    369377                    r = '%s.%s' % (qn(col[0]), qn(col[1])) 
    370                     result.append(r) 
    371                     aliases.append(r) 
     378                    if with_aliases and col[1] in col_aliases: 
     379                        c_alias = 'Col%d' % len(col_aliases) 
     380                        result.append('%s AS %s' % (r, c_alias)) 
     381                        aliases.append(c_alias) 
     382                        col_aliases.add(c_alias) 
     383                    else: 
     384                        result.append(r) 
     385                        aliases.append(r) 
     386                        col_aliases.add(col[1]) 
    372387                else: 
    373388                    result.append(col.as_sql(quote_func=qn)) 
    374389                    if hasattr(col, 'alias'): 
    375390                        aliases.append(col.alias) 
     391                        col_aliases.add(col.alias) 
    376392        elif self.default_cols: 
    377             cols = self.get_default_columns(True
     393            cols = self.get_default_columns(True, with_aliases, col_aliases
    378394            result.extend(cols) 
    379395            aliases.extend(cols) 
    380396        for table, col in self.related_select_cols: 
    381397            r = '%s.%s' % (qn(table), qn(col)) 
    382             result.append(r) 
    383             aliases.append(r) 
     398            if with_aliases and col in col_aliases: 
     399                c_alias = 'Col%d' % len(col_aliases) 
     400                result.append('%s AS %s' % (r, c_alias)) 
     401                aliases.append(c_alias) 
     402                col_aliases.add(c_alias) 
     403            else: 
     404                result.append(r) 
     405                aliases.append(r) 
     406                col_aliases.add(col) 
    384407 
    385408        self._select_aliases = set(aliases) 
    386409        return result 
    387410 
    388     def get_default_columns(self, as_str=False): 
     411    def get_default_columns(self, as_str=False, with_aliases=False, 
     412            col_aliases=None): 
    389413        """ 
    390414        Computes the default columns for selecting every field in the base 
     
    407431                seen[model] = alias 
    408432            if as_str: 
    409                 result.append('%s.%s' % (qn(alias), qn2(field.column))) 
     433                if with_aliases and field.column in col_aliases: 
     434                    c_alias = 'Col%d' % len(col_aliases) 
     435                    result.append('%s.%s AS %s' % (qn(alias), 
     436                        qn2(field.column), c_aliase)) 
     437                else: 
     438                    result.append('%s.%s' % (qn(alias), qn2(field.column))) 
    410439            else: 
    411440                result.append((alias, field.column))