]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
Detect the range oid from the subtype for non-builtins too
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Fri, 5 Feb 2021 02:45:05 +0000 (03:45 +0100)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Fri, 5 Feb 2021 02:52:13 +0000 (03:52 +0100)
psycopg3/psycopg3/types/range.py
tests/types/test_range.py

index 5e2165ee079841b1c9eeb27c23becb534c689fe0..69ac4ee441214b9ac7a40996cdc7890728925644 100644 (file)
@@ -260,12 +260,15 @@ class RangeDumper(SequenceDumper):
         sd = self._tx.get_dumper(item, Pg3Format.TEXT)
         dumper = type(self)(self.cls, self._tx)
         dumper.sub_dumper = sd
-        if not isinstance(item, int):
-            dumper.oid = self._get_range_oid(sd.oid)
-        else:
+        if isinstance(item, int):
             # postgres won't cast int4range -> int8range so we must use
             # text format and unknown oid here
             dumper.oid = INVALID_OID
+        elif isinstance(item, str) and sd.oid == INVALID_OID:
+            # Work around the normal mapping where text is dumped as unknown
+            dumper.oid = self._get_range_oid(self._types["text"].oid)
+        else:
+            dumper.oid = self._get_range_oid(sd.oid)
         return dumper
 
     def _get_item(self, obj: Range[Any]) -> Any:
@@ -280,9 +283,6 @@ class RangeDumper(SequenceDumper):
         Return the oid of the range from the oid of its elements.
 
         Raise InterfaceError if not found.
-
-        TODO: we shouldn't consider builtins only, but other adaptation
-        contexts too
         """
         info = self._types.get_range(sub_oid)
         return info.oid if info else INVALID_OID
@@ -374,8 +374,9 @@ class RangeInfo(TypeInfo):
         self,
         context: Optional[AdaptContext] = None,
     ) -> None:
-        # A new dumper is not required. However TODO we will need to register
-        # the dumper in the adapters type registry, when we have one.
+
+        if context:
+            context.adapters.types.add(self)
 
         # generate and register a customized text loader
         loader: Type[Loader] = type(
index b69371c91614b79a98608857b72c4edd42abe3ad..0ccbc9545008055c0c3e58bac478d06b5032e7f3 100644 (file)
@@ -201,13 +201,10 @@ def test_dump_quoting(conn, testrange):
     info.register(conn)
     cur = conn.cursor()
     for i in range(1, 254):
-        # TODO: when types registry is merged to adaptation context and we
-        # are able to establish "the type of the range whose element is text",
-        # this should work without ::testrange cast.
         cur.execute(
             """
-            select ascii(lower(%(r)s::testrange)) = %(low)s
-                and ascii(upper(%(r)s::testrange)) = %(up)s
+            select ascii(lower(%(r)s)) = %(low)s
+                and ascii(upper(%(r)s)) = %(up)s
             """,
             {"r": Range(chr(i), chr(i + 1)), "low": i, "up": i + 1},
         )