--- /dev/null
+.. change::
+ :tags: bug, sql
+ :tickets: 7909
+
+ The in-place type detection for Python integers, as occurs with an
+ expression such as ``literal(25)``, will now apply value-based adaption as
+ well to accommodate Python large integers, where the datatype determined
+ will be :class:`.BigInteger` rather than :class:`.Integer`. This
+ accommodates for dialects such as that of asyncpg which both sends implicit
+ typing information to the driver as well as is sensitive to numeric scale.
def python_type(self):
return int
+ def _resolve_for_literal(self, value):
+ if value.bit_length() >= 32:
+ return _BIGINTEGER
+ else:
+ return self
+
def literal_processor(self, dialect):
def process(value):
return str(int(value))
TABLEVALUE = TableValueType()
DATETIME_TIMEZONE = DateTime(timezone=True)
TIME_TIMEZONE = Time(timezone=True)
+_BIGINTEGER = BigInteger()
_DATETIME = DateTime()
_TIME = Time()
_STRING = String()
def test_literal(self, literal_round_trip):
literal_round_trip(Integer, [5], [5])
- def test_huge_int(self, integer_round_trip):
- integer_round_trip(BigInteger, 1376537018368127)
+ def _huge_ints():
+
+ return testing.combinations(
+ 2147483649, # 32 bits
+ 2147483648, # 32 bits
+ 2147483647, # 31 bits
+ 2147483646, # 31 bits
+ -2147483649, # 32 bits
+ -2147483648, # 32 interestingly, asyncpg accepts this one as int32
+ -2147483647, # 31
+ -2147483646, # 31
+ 0,
+ 1376537018368127,
+ -1376537018368127,
+ argnames="intvalue",
+ )
+
+ @_huge_ints()
+ def test_huge_int_auto_accommodation(self, connection, intvalue):
+ """test #7909"""
+
+ eq_(
+ connection.scalar(
+ select(intvalue).where(literal(intvalue) == intvalue)
+ ),
+ intvalue,
+ )
+
+ @_huge_ints()
+ def test_huge_int(self, integer_round_trip, intvalue):
+ integer_round_trip(BigInteger, intvalue)
@testing.fixture
def integer_round_trip(self, metadata, connection):