From: Daniele Varrazzo Date: Wed, 25 May 2022 08:45:29 +0000 (+0200) Subject: feat: allow to customize the oid to dump None X-Git-Tag: 3.1~49^2~44 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b864a2868ab226e9025c484fda5f3803939f92d8;p=thirdparty%2Fpsycopg.git feat: allow to customize the oid to dump None On Postgres >= 10, INVALID_OID is ok, because it has a fallback text cast. CRDB doesn't have such cast, but can convert implicitly from text to other types, so TEXT_OID is a better choice. --- diff --git a/psycopg/psycopg/_transform.py b/psycopg/psycopg/_transform.py index 200f31c45..730358727 100644 --- a/psycopg/psycopg/_transform.py +++ b/psycopg/psycopg/_transform.py @@ -29,6 +29,7 @@ OidDumperCache: TypeAlias = Dict[int, "Dumper"] LoaderCache: TypeAlias = Dict[int, "Loader"] TEXT = pq.Format.TEXT +PY_TEXT = PyFormat.TEXT class Transformer(AdaptContext): @@ -169,7 +170,7 @@ class Transformer(AdaptContext): out[i] = self._row_dumpers[i].dump(param) return out - types = [INVALID_OID] * nparams + types = [self._get_none_oid()] * nparams pqformats = [TEXT] * nparams for i in range(nparams): @@ -187,7 +188,7 @@ class Transformer(AdaptContext): return out def as_literal(self, obj: Any) -> Buffer: - dumper = self.get_dumper(obj, PyFormat.TEXT) + dumper = self.get_dumper(obj, PY_TEXT) rv = dumper.quote(obj) # If the result is quoted, and the oid not unknown or text, # add an explicit type cast. @@ -244,6 +245,19 @@ class Transformer(AdaptContext): dumper = cache[key1] = dumper.upgrade(obj, format) return dumper + def _get_none_oid(self): + try: + return self._none_oid + except AttributeError: + pass + + try: + rv = self._none_oid = self._adapters.get_dumper(NoneType, PY_TEXT).oid + except KeyError: + raise e.InterfaceError("None dumper not found") + + return rv + def get_dumper_by_oid(self, oid: int, format: pq.Format) -> "Dumper": """ Return a Dumper to dump an object to the type with given oid. diff --git a/psycopg_c/psycopg_c/_psycopg/transform.pyx b/psycopg_c/psycopg_c/_psycopg/transform.pyx index 8f2b5f3ee..7adfd7923 100644 --- a/psycopg_c/psycopg_c/_psycopg/transform.pyx +++ b/psycopg_c/psycopg_c/_psycopg/transform.pyx @@ -76,6 +76,7 @@ cdef class Transformer: cdef readonly object types cdef readonly object formats cdef str _encoding + cdef int _none_oid # mapping class -> Dumper instance (auto, text, binary) cdef dict _auto_dumpers @@ -107,6 +108,7 @@ cdef class Transformer: self.connection = None self.types = self.formats = None + self._none_oid = -1 @classmethod def from_context(cls, context: Optional["AdaptContext"]): @@ -361,6 +363,9 @@ cdef class Transformer: cdef object dumped cdef Py_ssize_t size + if self._none_oid < 0: + self._none_oid = self.adapters.get_dumper(NoneType, "s").oid + dumpers = self._row_dumpers if dumpers: @@ -406,7 +411,7 @@ cdef class Transformer: fmt = (dumper_ptr).format else: dumped = None - oid = oids.INVALID_OID + oid = self._none_oid fmt = PQ_TEXT Py_INCREF(dumped)