From: Daniele Varrazzo Date: Sat, 21 Nov 2020 21:38:21 +0000 (+0000) Subject: Added oid constants in cython extension X-Git-Tag: 3.0.dev0~332^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d4e4c6d39e4c6e24775f7473748c0642e74807cf;p=thirdparty%2Fpsycopg.git Added oid constants in cython extension --- diff --git a/psycopg3/psycopg3/oids.py b/psycopg3/psycopg3/oids.py index 394f5ccc8..c8791a007 100644 --- a/psycopg3/psycopg3/oids.py +++ b/psycopg3/psycopg3/oids.py @@ -1,13 +1,9 @@ """ Maps of builtin types and names - -You can update this file by executing it, using the PG* env var to connect -to a Postgres server. """ # Copyright (C) 2020 The Psycopg Team -import re from typing import Dict, Iterator, Optional, Union INVALID_OID = 0 @@ -85,8 +81,7 @@ class TypesRegistry: builtins = TypesRegistry() -# In order to update the registry, just execute this file, using the PG* -# env vars to point to a running PostgreSQL instance of the desired version. +# Use tools/update_oids.py to update this data. for r in [ # fmt: off # autogenerated: start @@ -171,53 +166,3 @@ for r in [ # fmt: on ]: builtins.add(BuiltinTypeInfo(*r)) - - -def self_update() -> None: - import subprocess as sp - - queries = [ - """ -select format($$ -# Generated from PostgreSQL %s.%s -$$, - setting::int / 10000, setting::int % 100) -- assume PG >= 10 - from pg_settings - where name = 'server_version_num' -""", - r""" -select format( - '(%L, %s, %s, %L, %L),', - typname, oid, typarray, oid::regtype, typdelim) - from pg_type - where oid < 10000 - and typname !~ all('{^(_|pg_|reg),_handler$}') - order by typname -""", - ] - - with open(__file__, "rb") as f: - lines = f.read().splitlines() - - new = [] - for query in queries: - out = sp.run( - ["psql", "-AXqt", "-c", query], stdout=sp.PIPE, check=True - ) - new.extend(out.stdout.splitlines()) - - new = [b" " * 4 + line if line else b"" for line in new] # indent - istart, iend = [ - i - for i, line in enumerate(lines) - if re.match(br"\s*#\s*autogenerated:\s+(start|end)", line) - ] - lines[istart + 1 : iend] = new - - with open(__file__, "wb") as f: - f.write(b"\n".join(lines)) - f.write(b"\n") - - -if __name__ == "__main__": - self_update() diff --git a/psycopg3_c/psycopg3_c/oids.pxd b/psycopg3_c/psycopg3_c/oids.pxd new file mode 100644 index 000000000..d5b0b12a8 --- /dev/null +++ b/psycopg3_c/psycopg3_c/oids.pxd @@ -0,0 +1,90 @@ +""" +Constants to refer to OIDS in C +""" + +# Copyright (C) 2020 The Psycopg Team + +# Use tools/update_oids.py to update this data. + +cdef enum: + INVALID_OID = 0 + + # autogenerated: start + + # Generated from PostgreSQL 13.0 + + ACLITEM_OID = 1033 + ANY_OID = 2276 + ANYARRAY_OID = 2277 + ANYCOMPATIBLE_OID = 5077 + ANYCOMPATIBLEARRAY_OID = 5078 + ANYCOMPATIBLENONARRAY_OID = 5079 + ANYCOMPATIBLERANGE_OID = 5080 + ANYELEMENT_OID = 2283 + ANYENUM_OID = 3500 + ANYNONARRAY_OID = 2776 + ANYRANGE_OID = 3831 + BIT_OID = 1560 + BOOL_OID = 16 + BOX_OID = 603 + BPCHAR_OID = 1042 + BYTEA_OID = 17 + CHAR_OID = 18 + CID_OID = 29 + CIDR_OID = 650 + CIRCLE_OID = 718 + CSTRING_OID = 2275 + DATE_OID = 1082 + DATERANGE_OID = 3912 + EVENT_TRIGGER_OID = 3838 + FLOAT4_OID = 700 + FLOAT8_OID = 701 + GTSVECTOR_OID = 3642 + INET_OID = 869 + INT2_OID = 21 + INT2VECTOR_OID = 22 + INT4_OID = 23 + INT4RANGE_OID = 3904 + INT8_OID = 20 + INT8RANGE_OID = 3926 + INTERNAL_OID = 2281 + INTERVAL_OID = 1186 + JSON_OID = 114 + JSONB_OID = 3802 + JSONPATH_OID = 4072 + LINE_OID = 628 + LSEG_OID = 601 + MACADDR_OID = 829 + MACADDR8_OID = 774 + MONEY_OID = 790 + NAME_OID = 19 + NUMERIC_OID = 1700 + NUMRANGE_OID = 3906 + OID_OID = 26 + OIDVECTOR_OID = 30 + PATH_OID = 602 + POINT_OID = 600 + POLYGON_OID = 604 + RECORD_OID = 2249 + REFCURSOR_OID = 1790 + TEXT_OID = 25 + TID_OID = 27 + TIME_OID = 1083 + TIMESTAMP_OID = 1114 + TIMESTAMPTZ_OID = 1184 + TIMETZ_OID = 1266 + TRIGGER_OID = 2279 + TSQUERY_OID = 3615 + TSRANGE_OID = 3908 + TSTZRANGE_OID = 3910 + TSVECTOR_OID = 3614 + TXID_SNAPSHOT_OID = 2970 + UNKNOWN_OID = 705 + UUID_OID = 2950 + VARBIT_OID = 1562 + VARCHAR_OID = 1043 + VOID_OID = 2278 + XID_OID = 28 + XID8_OID = 5069 + XML_OID = 142 + # autogenerated: end diff --git a/psycopg3_c/psycopg3_c/transform.pyx b/psycopg3_c/psycopg3_c/transform.pyx index 0fa2f1705..311a04da0 100644 --- a/psycopg3_c/psycopg3_c/transform.pyx +++ b/psycopg3_c/psycopg3_c/transform.pyx @@ -13,14 +13,12 @@ from cpython.tuple cimport PyTuple_New, PyTuple_SET_ITEM from typing import Any, Dict, Iterable, List, Optional, Sequence, Tuple -from psycopg3_c cimport libpq +from psycopg3_c cimport libpq, oids from psycopg3_c.pq_cython cimport PGresult from psycopg3 import errors as e from psycopg3.pq.enums import Format -TEXT_OID = 25 - cdef class RowLoader: cdef object pyloader @@ -282,7 +280,7 @@ cdef class Transformer: break else: from psycopg3.adapt import Loader - loader_cls = Loader.globals[0, format] # INVALID_OID + loader_cls = Loader.globals[oids.INVALID_OID, format] self._loaders_cache[key] = loader = loader_cls(key[0], self) return loader diff --git a/psycopg3_c/psycopg3_c/types/numeric.pyx b/psycopg3_c/psycopg3_c/types/numeric.pyx index f24a879ed..a13b4c272 100644 --- a/psycopg3_c/psycopg3_c/types/numeric.pyx +++ b/psycopg3_c/psycopg3_c/types/numeric.pyx @@ -5,12 +5,13 @@ Cython adapters for numeric types. # Copyright (C) 2020 The Psycopg Team from libc.stdint cimport * -from psycopg3_c.endian cimport be16toh, be32toh, be64toh, htobe64 - from cpython.long cimport PyLong_FromString, PyLong_FromLong, PyLong_AsLongLong from cpython.long cimport PyLong_FromLongLong, PyLong_FromUnsignedLong from cpython.float cimport PyFloat_FromDouble +from psycopg3_c cimport oids +from psycopg3_c.endian cimport be16toh, be32toh, be64toh, htobe64 + cdef extern from "Python.h": # work around https://github.com/cython/cython/issues/3909 double PyOS_string_to_double( @@ -20,7 +21,7 @@ cdef extern from "Python.h": cdef class IntDumper(CDumper): - oid = 20 # TODO: int8 oid + oid = oids.INT8_OID def dump(self, obj: Any) -> bytes: cdef char buf[22] @@ -99,21 +100,19 @@ cdef class Float8BinaryLoader(CLoader): cdef void register_numeric_c_adapters(): logger.debug("registering optimised numeric c adapters") - from psycopg3.oids import builtins - IntDumper.register(int) IntBinaryDumper.register_binary(int) - IntLoader.register(builtins["int2"].oid) - IntLoader.register(builtins["int4"].oid) - IntLoader.register(builtins["int8"].oid) - IntLoader.register(builtins["oid"].oid) - FloatLoader.register(builtins["float4"].oid) - FloatLoader.register(builtins["float8"].oid) - - Int2BinaryLoader.register_binary(builtins["int2"].oid) - Int4BinaryLoader.register_binary(builtins["int4"].oid) - Int8BinaryLoader.register_binary(builtins["int8"].oid) - OidBinaryLoader.register_binary(builtins["oid"].oid) - Float4BinaryLoader.register_binary(builtins["float4"].oid) - Float8BinaryLoader.register_binary(builtins["float8"].oid) + IntLoader.register(oids.INT2_OID) + IntLoader.register(oids.INT4_OID) + IntLoader.register(oids.INT8_OID) + IntLoader.register(oids.OID_OID) + FloatLoader.register(oids.FLOAT4_OID) + FloatLoader.register(oids.FLOAT8_OID) + + Int2BinaryLoader.register_binary(oids.INT2_OID) + Int4BinaryLoader.register_binary(oids.INT4_OID) + Int8BinaryLoader.register_binary(oids.INT8_OID) + OidBinaryLoader.register_binary(oids.OID_OID) + Float4BinaryLoader.register_binary(oids.FLOAT4_OID) + Float8BinaryLoader.register_binary(oids.FLOAT8_OID) diff --git a/psycopg3_c/psycopg3_c/types/singletons.pyx b/psycopg3_c/psycopg3_c/types/singletons.pyx index 5d1b8033d..2377d4452 100644 --- a/psycopg3_c/psycopg3_c/types/singletons.pyx +++ b/psycopg3_c/psycopg3_c/types/singletons.pyx @@ -4,8 +4,11 @@ Cython adapters for boolean. # Copyright (C) 2020 The Psycopg Team +from psycopg3_c cimport oids + + cdef class BoolDumper(CDumper): - oid = 16 # TODO: bool oid + oid = oids.BOOL_OID def dump(self, obj: bool) -> bytes: # Fast paths, just a pointer comparison @@ -49,10 +52,8 @@ cdef class BoolBinaryLoader(CLoader): cdef void register_singletons_c_adapters(): logger.debug("registering optimised singletons c adapters") - from psycopg3.oids import builtins - BoolDumper.register(bool) BoolBinaryDumper.register_binary(bool) - BoolLoader.register(builtins["bool"].oid) - BoolBinaryLoader.register_binary(builtins["bool"].oid) + BoolLoader.register(oids.BOOL_OID) + BoolBinaryLoader.register_binary(oids.BOOL_OID) diff --git a/psycopg3_c/psycopg3_c/types/text.pyx b/psycopg3_c/psycopg3_c/types/text.pyx index 27b17e68f..ebc6bd13d 100644 --- a/psycopg3_c/psycopg3_c/types/text.pyx +++ b/psycopg3_c/psycopg3_c/types/text.pyx @@ -5,7 +5,7 @@ Cython adapters for textual types. # Copyright (C) 2020 The Psycopg Team from cpython.unicode cimport PyUnicode_Decode, PyUnicode_DecodeUTF8 -from psycopg3_c cimport libpq +from psycopg3_c cimport libpq, oids cdef class TextLoader(CLoader): @@ -60,14 +60,11 @@ cdef class ByteaBinaryLoader(CLoader): cdef void register_text_c_adapters(): logger.debug("registering optimised text c adapters") - from psycopg3.oids import builtins - from psycopg3.adapt import Loader + TextLoader.register(oids.INVALID_OID) + TextLoader.register(oids.TEXT_OID) + TextLoader.register_binary(oids.TEXT_OID) + TextLoader.register(oids.VARCHAR_OID) + TextLoader.register_binary(oids.VARCHAR_OID) - TextLoader.register(0) # INVALID_OID - TextLoader.register(builtins["text"].oid) - TextLoader.register_binary(builtins["text"].oid) - TextLoader.register(builtins["varchar"].oid) - TextLoader.register_binary(builtins["varchar"].oid) - - ByteaLoader.register(builtins['bytea'].oid) - ByteaBinaryLoader.register_binary(builtins['bytea'].oid) + ByteaLoader.register(oids.BYTEA_OID) + ByteaBinaryLoader.register_binary(oids.BYTEA_OID) diff --git a/tools/update_errors.py b/tools/update_errors.py index 4ec60f180..82b44c2b7 100755 --- a/tools/update_errors.py +++ b/tools/update_errors.py @@ -1,5 +1,6 @@ #!/usr/bin/env python -"""Generate per-sqlstate errors from PostgreSQL source code. +""" +Generate per-sqlstate errors from PostgreSQL source code. The script can be run at a new PostgreSQL release to refresh the module. """ @@ -15,7 +16,7 @@ import subprocess as sp from urllib.request import urlopen from collections import defaultdict -from psycopg3.errors import get_base_exception +from psycopg3.errors import get_base_exception # type: ignore logger = logging.getLogger() logging.basicConfig( diff --git a/tools/update_oids.py b/tools/update_oids.py new file mode 100755 index 000000000..edfd05c72 --- /dev/null +++ b/tools/update_oids.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python +""" +Update the maps of builtin types and names. + +You can update this file by executing it, using the PG* env var to connect +""" + +import os +import re +import subprocess as sp +from typing import List + + +version_sql = """ +select format($$ +# Generated from PostgreSQL %s.%s +$$, + setting::int / 10000, setting::int % 100) -- assume PG >= 10 + from pg_settings + where name = 'server_version_num' +""" + +py_oids_sql = """ +select format( + '(%L, %s, %s, %L, %L),', + typname, oid, typarray, oid::regtype, typdelim) + from pg_type + where oid < 10000 + and typname !~ all('{^(_|pg_|reg),_handler$}') + order by typname +""" + + +cython_oids_sql = """ +select format('%s_OID = %s', upper(typname), oid) + from pg_type + where oid < 10000 + and typname !~ all('{^(_|pg_|reg),_handler$}') + order by typname +""" + + +def update_python_oids() -> None: + queries = [version_sql, py_oids_sql] + fn = os.path.dirname(__file__) + "/../psycopg3/psycopg3/oids.py" + update_file(fn, queries) + + +def update_cython_oids() -> None: + queries = [version_sql, cython_oids_sql] + fn = os.path.dirname(__file__) + "/../psycopg3_c/psycopg3_c/oids.pxd" + update_file(fn, queries) + + +def update_file(fn: str, queries: List[str]) -> None: + with open(fn, "rb") as f: + lines = f.read().splitlines() + + new = [] + for query in queries: + out = sp.run( + ["psql", "-AXqt", "-c", query], stdout=sp.PIPE, check=True + ) + new.extend(out.stdout.splitlines()) + + new = [b" " * 4 + line if line else b"" for line in new] # indent + istart, iend = [ + i + for i, line in enumerate(lines) + if re.match(br"\s*#\s*autogenerated:\s+(start|end)", line) + ] + lines[istart + 1 : iend] = new + + with open(fn, "wb") as f: + f.write(b"\n".join(lines)) + f.write(b"\n") + + +if __name__ == "__main__": + update_python_oids() + update_cython_oids()