]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
Register automatically the array loader on all the builtins
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Wed, 23 Dec 2020 21:02:19 +0000 (22:02 +0100)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Thu, 24 Dec 2020 03:51:34 +0000 (04:51 +0100)
Also added reg* types to the known builtins. This way regtype[] is
loaded as a list of strings.

psycopg3/psycopg3/oids.py
psycopg3/psycopg3/types/array.py
psycopg3_c/psycopg3_c/oids.pxd
tests/types/test_array.py
tools/update_oids.py

index c8791a0076c6861e67003d62508e96d0cc4dbb99..ccaef1f886360cd12c85d978bede3289713e5481 100644 (file)
@@ -142,6 +142,17 @@ for r in [
     ('polygon', 604, 1027, 'polygon', ','),
     ('record', 2249, 2287, 'record', ','),
     ('refcursor', 1790, 2201, 'refcursor', ','),
+    ('regclass', 2205, 2210, 'regclass', ','),
+    ('regcollation', 4191, 4192, 'regcollation', ','),
+    ('regconfig', 3734, 3735, 'regconfig', ','),
+    ('regdictionary', 3769, 3770, 'regdictionary', ','),
+    ('regnamespace', 4089, 4090, 'regnamespace', ','),
+    ('regoper', 2203, 2208, 'regoper', ','),
+    ('regoperator', 2204, 2209, 'regoperator', ','),
+    ('regproc', 24, 1008, 'regproc', ','),
+    ('regprocedure', 2202, 2207, 'regprocedure', ','),
+    ('regrole', 4096, 4097, 'regrole', ','),
+    ('regtype', 2206, 2211, 'regtype', ','),
     ('text', 25, 1009, 'text', ','),
     ('tid', 27, 1010, 'tid', ','),
     ('time', 1083, 1183, 'time without time zone', ','),
index 6599e3339aaf086af0381564d8358b191ec0adf9..7cfe8cc188f1347f1106a2297f9246f0e5eeeff2 100644 (file)
@@ -291,8 +291,6 @@ def register_all_arrays() -> None:
     registered all the base loaders.
     """
     for t in builtins:
-        if t.array_oid and (
-            (t.oid, Format.TEXT) in Loader.globals
-            or (t.oid, Format.BINARY) in Loader.globals
-        ):
+        # TODO: handle different delimiters (box)
+        if t.array_oid and getattr(t, "delimiter", None) == ",":
             register(t.array_oid, t.oid, name=t.name)
index d5b0b12a826a8e59507127fe530ec318cad984b5..711ffdc3dc4b0d3cf1c1b530ea6beea383d2d794 100644 (file)
@@ -67,6 +67,17 @@ cdef enum:
     POLYGON_OID = 604
     RECORD_OID = 2249
     REFCURSOR_OID = 1790
+    REGCLASS_OID = 2205
+    REGCOLLATION_OID = 4191
+    REGCONFIG_OID = 3734
+    REGDICTIONARY_OID = 3769
+    REGNAMESPACE_OID = 4089
+    REGOPER_OID = 2203
+    REGOPERATOR_OID = 2204
+    REGPROC_OID = 24
+    REGPROCEDURE_OID = 2202
+    REGROLE_OID = 4096
+    REGTYPE_OID = 2206
     TEXT_OID = 25
     TID_OID = 27
     TIME_OID = 1083
index b2a98332752643b36812bc47a34a8ac317818e74..591901cfa6219005f80e35949d60a359c19895d2 100644 (file)
@@ -101,18 +101,32 @@ def test_load_list_int(conn, obj, want, fmt_out):
 
 
 def test_array_register(conn):
-    # unknown for real
     cur = conn.cursor()
-    cur.execute("select '{postgres=arwdDxt/postgres}'::aclitem[]")
-    res = cur.fetchone()[0]
-    assert res == "{postgres=arwdDxt/postgres}"
+    cur.execute("create table mytype (data text)")
+    cur.execute("""select '(foo)'::mytype, '{"(foo)"}'::mytype[]""")
+    res = cur.fetchone()
+    assert res[0] == "(foo)"
+    assert res[1] == "{(foo)}"
 
     array.register(
-        builtins["aclitem"].array_oid, builtins["aclitem"].oid, context=conn
+        cur.description[1].type_code, cur.description[0].type_code, context=cur
     )
-    cur.execute("select '{postgres=arwdDxt/postgres}'::aclitem[]")
-    res = cur.fetchone()[0]
-    assert res == ["postgres=arwdDxt/postgres"]
+    cur.execute("""select '(foo)'::mytype, '{"(foo)"}'::mytype[]""")
+    res = cur.fetchone()
+    assert res[0] == "(foo)"
+    assert res[1] == ["(foo)"]
+
+
+def test_array_of_unknown_builtin(conn):
+    # we cannot load this type, but we understand it is an array
+    val = "postgres=arwdDxt/postgres"
+    cur = conn.cursor()
+    cur.execute(f"select '{val}'::aclitem, array['{val}']::aclitem[]")
+    res = cur.fetchone()
+    assert cur.description[0].type_code == builtins["aclitem"].oid
+    assert res[0] == val
+    assert cur.description[1].type_code == builtins["aclitem"].array_oid
+    assert res[1] == [val]
 
 
 @pytest.mark.xfail
index edfd05c7210bc60225eeeebb2a51dea3762e447a..0cbbea4af7841fb95ab251b6ceab2587a8605f58 100755 (executable)
@@ -26,7 +26,7 @@ select format(
         typname, oid, typarray, oid::regtype, typdelim)
     from pg_type
     where oid < 10000
-    and typname !~ all('{^(_|pg_|reg),_handler$}')
+    and typname !~ all('{^(_|pg_),_handler$}')
     order by typname
 """
 
@@ -35,7 +35,7 @@ cython_oids_sql = """
 select format('%s_OID = %s', upper(typname), oid)
     from pg_type
     where oid < 10000
-    and typname !~ all('{^(_|pg_|reg),_handler$}')
+    and typname !~ all('{^(_|pg_),_handler$}')
     order by typname
 """