Describe the bug
Doing a floor division // between a decimal numerator (float / numeric) and an int denominator results in the wrong sql
Optional link from https://docs.sqlalchemy.org which documents the behavior that is expected
No response
SQLAlchemy Version in Use
2.x
DBAPI (i.e. the database driver)
any
Database Vendor and Major Version
pg, any
Python Version
any
Operating system
any
To Reproduce
import sqlalchemy as sa
from sqlalchemy.dialects.postgresql import dialect
pg = dialect()
t = sa.Table(
"foo",
sa.MetaData(),
sa.Column("int_col", sa.Integer()),
sa.Column("float_col", sa.Float()),
sa.Column("numeric_col", sa.Numeric()),
sa.Column("int_col2", sa.Integer()),
sa.Column("float_col2", sa.Float()),
sa.Column("numeric_col2", sa.Numeric()),
)
def go(a_name, b_name, inverse):
a, b = t.c[a_name], t.c[b_name]
print(f"{a_name} / {b_name}:>", (a / b).compile(dialect=pg).string)
print(f"{a_name} // {b_name}:>", (a // b).compile(dialect=pg).string)
if inverse:
print(f"{b_name} / {a_name}:>", (b / a).compile(dialect=pg).string)
print(f"{b_name} // {a_name}:>", (b // a).compile(dialect=pg).string)
go("int_col", "int_col2", False)
go("float_col", "float_col2", False)
go("numeric_col", "numeric_col2", False)
go("int_col", "float_col", True)
go("int_col", "numeric_col", True)
go("float_col", "numeric_col", True)
Error
The above code prints
int_col / int_col2:> foo.int_col / CAST(foo.int_col2 AS NUMERIC)
int_col // int_col2:> foo.int_col / foo.int_col2
float_col / float_col2:> foo.float_col / CAST(foo.float_col2 AS FLOAT)
float_col // float_col2:> FLOOR(foo.float_col / foo.float_col2)
numeric_col / numeric_col2:> foo.numeric_col / CAST(foo.numeric_col2 AS NUMERIC)
numeric_col // numeric_col2:> FLOOR(foo.numeric_col / foo.numeric_col2)
int_col / float_col:> foo.int_col / CAST(foo.float_col AS FLOAT)
int_col // float_col:> FLOOR(foo.int_col / foo.float_col)
float_col / int_col:> foo.float_col / CAST(foo.int_col AS NUMERIC)
float_col // int_col:> foo.float_col / foo.int_col
int_col / numeric_col:> foo.int_col / CAST(foo.numeric_col AS NUMERIC)
int_col // numeric_col:> FLOOR(foo.int_col / foo.numeric_col)
numeric_col / int_col:> foo.numeric_col / CAST(foo.int_col AS NUMERIC)
numeric_col // int_col:> foo.numeric_col / foo.int_col
float_col / numeric_col:> foo.float_col / CAST(foo.numeric_col AS NUMERIC)
float_col // numeric_col:> FLOOR(foo.float_col / foo.numeric_col)
numeric_col / float_col:> foo.numeric_col / CAST(foo.float_col AS FLOAT)
numeric_col // float_col:> FLOOR(foo.numeric_col / foo.float_col)
These cases are wrong.
float_col // int_col:> foo.float_col / foo.int_col
numeric_col // int_col:> foo.numeric_col / foo.int_col
That code seems to try and detect int denominators and do something different, while it does not do the same for the other datatypes (example float/float gets an unnecessary cast: float_col / float_col2:> foo.float_col / CAST(foo.float_col2 AS FLOAT)) so I think it can probably remove this special logic for the int denominator and do in every case the floor logic
Additional context
No response
Describe the bug
Doing a floor division
//between a decimal numerator (float / numeric) and an int denominator results in the wrong sqlOptional link from https://docs.sqlalchemy.org which documents the behavior that is expected
No response
SQLAlchemy Version in Use
2.x
DBAPI (i.e. the database driver)
any
Database Vendor and Major Version
pg, any
Python Version
any
Operating system
any
To Reproduce
Error
The above code prints
These cases are wrong.
That code seems to try and detect int denominators and do something different, while it does not do the same for the other datatypes (example float/float gets an unnecessary cast:
float_col / float_col2:> foo.float_col / CAST(foo.float_col2 AS FLOAT)) so I think it can probably remove this special logic for the int denominator and do in every case the floor logicAdditional context
No response