From 0fa754122cb2c19a79511e2705eb73d4c2afce79 Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Thu, 9 May 2024 02:02:08 +0200 Subject: [PATCH] fix: fix representation of bit/varbit columns --- psycopg/psycopg/_typemod.py | 11 +++++++++++ psycopg/psycopg/crdb/_types.py | 7 ++++--- psycopg/psycopg/postgres.py | 7 ++++--- tests/test_column.py | 7 +++++++ tools/update_oids.py | 2 ++ 5 files changed, 28 insertions(+), 6 deletions(-) diff --git a/psycopg/psycopg/_typemod.py b/psycopg/psycopg/_typemod.py index d92b7cfb3..a558b0847 100644 --- a/psycopg/psycopg/_typemod.py +++ b/psycopg/psycopg/_typemod.py @@ -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.""" diff --git a/psycopg/psycopg/crdb/_types.py b/psycopg/psycopg/crdb/_types.py index b72d317ae..2b07fbe8a 100644 --- a/psycopg/psycopg/crdb/_types.py +++ b/psycopg/psycopg/crdb/_types.py @@ -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 ), diff --git a/psycopg/psycopg/postgres.py b/psycopg/psycopg/postgres.py index fa1fdd2c8..ef6d42a1b 100644 --- a/psycopg/psycopg/postgres.py +++ b/psycopg/psycopg/postgres.py @@ -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 ), diff --git a/tests/test_column.py b/tests/test_column.py index 1651b061a..0440d9756 100644 --- a/tests/test_column.py +++ b/tests/test_column.py @@ -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): diff --git a/tools/update_oids.py b/tools/update_oids.py index 221622d69..945979b56 100755 --- a/tools/update_oids.py +++ b/tools/update_oids.py @@ -129,6 +129,8 @@ typemods = { "timestamp": "TimeTypeModifier", "timestamptz": "TimeTypeModifier", "interval": "TimeTypeModifier", + "bit": "BitTypeModifier", + "varbit": "BitTypeModifier", } -- 2.47.3