SQL Server repurposing of ORDER BY -> OVER mis-applies label_reference

Issue #3711 resolved
Mike Bayer repo owner created an issue

the select() element wraps each order by with "label_reference()", which is only appropriate to call upon in the ORDER BY. mssql dialect should unwrap these before it moves the order by into OVER:

from sqlalchemy import *

m = MetaData()

t = Table('t', m, Column('x', Integer))

expr1 = func.foo(t.c.x).label('x')
expr2 = func.foo(t.c.x).label('y')

stmt1 = select([expr1]).order_by(expr1.desc()).offset(1)
stmt2 = select([expr2]).order_by(expr2.desc()).offset(1)

from sqlalchemy.dialects import mssql

print stmt1.compile(dialect=mssql.dialect())

print stmt2.compile(dialect=mssql.dialect())

output:

#!


SELECT anon_1.x 
FROM (SELECT foo(t.x) AS x, ROW_NUMBER() OVER (ORDER BY x DESC) AS mssql_rn 
FROM t) AS anon_1 
WHERE mssql_rn > :param_1

SELECT anon_1.y 
FROM (SELECT foo(t.x) AS y, ROW_NUMBER() OVER (ORDER BY foo(t.x) DESC) AS mssql_rn 
FROM t) AS anon_1 
WHERE mssql_rn > :param_1

Comments (4)

  1. Mike Bayer reporter

    also, because of where the OVER is resolved, the label_resolve_dict we use isn't even the one that has the label, it uses the one w/ the raw column. so needs to be unwrapped.

    (Pdb) print self.stack[-1]['selectable']._label_resolve_dict
    ({'x': <sqlalchemy.sql.elements.Label object at 0x7f0fda165690>, 'mssql_rn': <sqlalchemy.sql.elements.Label object at 0x7f0fda158650>}, {'x': Column('x', Integer(), table=<t>)})
    
  2. Mike Bayer reporter

    Fix label referencing in SQL Server OFFSET logic

    Fixed bug where by ROW_NUMBER OVER clause applied for OFFSET selects in SQL Server would inappropriately substitute a plain column from the local statement that overlaps with a label name used by the ORDER BY criteria of the statement.

    Change-Id: Ic2500c886cbfc83a1ad5a2681783f008b9f23838 Fixes: #3711

    → <<cset 0604116814a8>>

  3. Mike Bayer reporter

    Fix label referencing in SQL Server OFFSET logic

    Fixed bug where by ROW_NUMBER OVER clause applied for OFFSET selects in SQL Server would inappropriately substitute a plain column from the local statement that overlaps with a label name used by the ORDER BY criteria of the statement.

    Change-Id: Ic2500c886cbfc83a1ad5a2681783f008b9f23838 Fixes: #3711 (cherry picked from commit a4be7c92393e08607dc46f318e97803519052a93)

    → <<cset 40b0e4b424c8>>

  4. Log in to comment