]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
fix: fix representation of bit/varbit columns
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Thu, 9 May 2024 00:02:08 +0000 (02:02 +0200)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Wed, 15 May 2024 15:56:39 +0000 (17:56 +0200)
psycopg/psycopg/_typemod.py
psycopg/psycopg/crdb/_types.py
psycopg/psycopg/postgres.py
tests/test_column.py
tools/update_oids.py

index d92b7cfb3dbe5d1def346a8f0820c1b575f128c1..a558b084736afcb559afbc96ab818223de118308 100644 (file)
@@ -64,6 +64,17 @@ class CharTypeModifier(TypeModifier):
         return typemod - 4 if typemod >= 0 else None
 
 
+class BitTypeModifier(TypeModifier):
+    """Handle bit/varbit type modifier."""
+
+    def get_modifier(self, typemod: int) -> tuple[int, ...] | None:
+        dsize = self.get_display_size(typemod)
+        return (dsize,) if dsize else None
+
+    def get_display_size(self, typemod: int) -> int | None:
+        return typemod if typemod >= 0 else None
+
+
 class TimeTypeModifier(TypeModifier):
     """Handle time-related types modifier."""
 
index b72d317aea012b04735c269db2fa1f5161a6eaf1..2b07fbe8a92984ee9f0ce582470a44c84fbe5c5a 100644 (file)
@@ -9,7 +9,8 @@ from .._typeinfo import TypeInfo, TypesRegistry
 
 from ..abc import AdaptContext, NoneType
 from .._oids import TEXT_OID
-from .._typemod import CharTypeModifier, NumericTypeModifier, TimeTypeModifier
+from .._typemod import BitTypeModifier, CharTypeModifier, NumericTypeModifier
+from .._typemod import TimeTypeModifier
 from .._adapters_map import AdaptersMap
 from ..types.enum import EnumDumper, EnumBinaryDumper
 from ..types.none import NoneDumper
@@ -133,7 +134,7 @@ def register_crdb_types(types: TypesRegistry) -> None:
         TypeInfo('"char"', 18, 1002),  # special case, not generated
         # autogenerated: start
         # Generated from CockroachDB 23.1.10
-        TypeInfo("bit", 1560, 1561),
+        TypeInfo("bit", 1560, 1561, typemod=BitTypeModifier),
         TypeInfo("bool", 16, 1000, regtype="boolean"),
         TypeInfo("bpchar", 1042, 1014, regtype="character", typemod=CharTypeModifier),
         TypeInfo("bytea", 17, 1001),
@@ -191,7 +192,7 @@ def register_crdb_types(types: TypesRegistry) -> None:
         TypeInfo("tsvector", 3614, 3643),
         TypeInfo("unknown", 705, 0),
         TypeInfo("uuid", 2950, 2951),
-        TypeInfo("varbit", 1562, 1563, regtype="bit varying"),
+        TypeInfo("varbit", 1562, 1563, regtype="bit varying", typemod=BitTypeModifier),
         TypeInfo(
             "varchar", 1043, 1015, regtype="character varying", typemod=CharTypeModifier
         ),
index fa1fdd2c84f765b0e4b64d0428b2e2930792cbb9..ef6d42a1b93dcbb34d8944a7dee4f8b5dce58509 100644 (file)
@@ -5,7 +5,8 @@ Types configuration specific to PostgreSQL.
 # Copyright (C) 2020 The Psycopg Team
 
 from .abc import AdaptContext
-from ._typemod import CharTypeModifier, NumericTypeModifier, TimeTypeModifier
+from ._typemod import BitTypeModifier, CharTypeModifier, NumericTypeModifier
+from ._typemod import TimeTypeModifier
 from ._typeinfo import TypeInfo, TypesRegistry
 from ._adapters_map import AdaptersMap
 
@@ -26,7 +27,7 @@ def register_default_types(types: TypesRegistry) -> None:
         # autogenerated: start
         # Generated from PostgreSQL 16.2
         TypeInfo("aclitem", 1033, 1034),
-        TypeInfo("bit", 1560, 1561),
+        TypeInfo("bit", 1560, 1561, typemod=BitTypeModifier),
         TypeInfo("bool", 16, 1000, regtype="boolean"),
         TypeInfo("box", 603, 1020, delimiter=";"),
         TypeInfo("bpchar", 1042, 1014, regtype="character", typemod=CharTypeModifier),
@@ -107,7 +108,7 @@ def register_default_types(types: TypesRegistry) -> None:
         TypeInfo("tsvector", 3614, 3643),
         TypeInfo("txid_snapshot", 2970, 2949),
         TypeInfo("uuid", 2950, 2951),
-        TypeInfo("varbit", 1562, 1563, regtype="bit varying"),
+        TypeInfo("varbit", 1562, 1563, regtype="bit varying", typemod=BitTypeModifier),
         TypeInfo(
             "varchar", 1043, 1015, regtype="character varying", typemod=CharTypeModifier
         ),
index 1651b061a0d4800c6b0526aa977898cf6e5ac59b..0440d975620f9f27eaeafeb6633afb22439ba9cb 100644 (file)
@@ -85,6 +85,13 @@ def test_description_slice(conn):
         ("timestamp", None, None, None, 8),
         ("timestamptz", None, None, None, 8),
         ("interval", None, None, None, 16),
+        ("bit(1)", None, None, 1, None),
+        ("bit(42)", None, None, 42, None),
+        ("bit(83886080)", None, None, 83886080, None),
+        ("varbit", None, None, None, None),
+        ("varbit(1)", None, None, 1, None),
+        ("varbit(42)", None, None, 42, None),
+        ("varbit(83886080)", None, None, 83886080, None),
     ],
 )
 def test_details(conn, type, precision, scale, dsize, isize):
index 221622d695664b3026eafe997f33f51680a262cc..945979b5691289cf5cfddb7ea5b21efdc10e8739 100755 (executable)
@@ -129,6 +129,8 @@ typemods = {
     "timestamp": "TimeTypeModifier",
     "timestamptz": "TimeTypeModifier",
     "interval": "TimeTypeModifier",
+    "bit": "BitTypeModifier",
+    "varbit": "BitTypeModifier",
 }