mirror of
https://github.com/psycopg/psycopg2.git
synced 2025-07-01 02:03:05 +03:00
fix: handle types in the search path in register_composite()
Fix #1487.
This commit is contained in:
parent
31a80410db
commit
d88e4c2a3c
6
NEWS
6
NEWS
|
@ -1,3 +1,9 @@
|
||||||
|
What's new in psycopg 2.9.4 (unreleased)
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
- Fix `register_composite()` with customized search_path (:ticket:`#1487`).
|
||||||
|
|
||||||
|
|
||||||
Current release
|
Current release
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
|
|
@ -1098,9 +1098,40 @@ ORDER BY attnum;
|
||||||
|
|
||||||
recs = curs.fetchall()
|
recs = curs.fetchall()
|
||||||
|
|
||||||
|
if not recs:
|
||||||
|
# The above algorithm doesn't work for customized seach_path
|
||||||
|
# (#1487) The implementation below works better, but, to guarantee
|
||||||
|
# backwards compatibility, use it only if the original one failed.
|
||||||
|
try:
|
||||||
|
savepoint = False
|
||||||
|
# Because we executed statements earlier, we are either INTRANS
|
||||||
|
# or we are IDLE only if the transaction is autocommit, in
|
||||||
|
# which case we don't need the savepoint anyway.
|
||||||
|
if conn.status == _ext.STATUS_IN_TRANSACTION:
|
||||||
|
curs.execute("SAVEPOINT register_type")
|
||||||
|
savepoint = True
|
||||||
|
|
||||||
|
curs.execute("""\
|
||||||
|
SELECT t.oid, %s, attname, atttypid, nspname
|
||||||
|
FROM pg_type t
|
||||||
|
JOIN pg_namespace ns ON typnamespace = ns.oid
|
||||||
|
JOIN pg_attribute a ON attrelid = typrelid
|
||||||
|
WHERE t.oid = %%s::regtype
|
||||||
|
AND attnum > 0 AND NOT attisdropped
|
||||||
|
ORDER BY attnum;
|
||||||
|
""" % typarray, (name, ))
|
||||||
|
except psycopg2.ProgrammingError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
recs = curs.fetchall()
|
||||||
|
if recs:
|
||||||
|
schema = recs[0][4]
|
||||||
|
finally:
|
||||||
|
if savepoint:
|
||||||
|
curs.execute("ROLLBACK TO SAVEPOINT register_type")
|
||||||
|
|
||||||
# revert the status of the connection as before the command
|
# revert the status of the connection as before the command
|
||||||
if (conn_status != _ext.STATUS_IN_TRANSACTION
|
if conn_status != _ext.STATUS_IN_TRANSACTION and not conn.autocommit:
|
||||||
and not conn.autocommit):
|
|
||||||
conn.rollback()
|
conn.rollback()
|
||||||
|
|
||||||
if not recs:
|
if not recs:
|
||||||
|
|
|
@ -584,6 +584,49 @@ class AdaptTypeTestCase(ConnectingTestCase):
|
||||||
curs.execute("select (4,8)::typens.typens_ii")
|
curs.execute("select (4,8)::typens.typens_ii")
|
||||||
self.assertEqual(curs.fetchone()[0], (4, 8))
|
self.assertEqual(curs.fetchone()[0], (4, 8))
|
||||||
|
|
||||||
|
@skip_if_no_composite
|
||||||
|
def test_composite_namespace_path(self):
|
||||||
|
curs = self.conn.cursor()
|
||||||
|
curs.execute("""
|
||||||
|
select nspname from pg_namespace
|
||||||
|
where nspname = 'typens';
|
||||||
|
""")
|
||||||
|
if not curs.fetchone():
|
||||||
|
curs.execute("create schema typens;")
|
||||||
|
self.conn.commit()
|
||||||
|
|
||||||
|
self._create_type("typens.typensp_ii",
|
||||||
|
[("a", "integer"), ("b", "integer")])
|
||||||
|
curs.execute("set search_path=typens,public")
|
||||||
|
t = psycopg2.extras.register_composite(
|
||||||
|
"typensp_ii", self.conn)
|
||||||
|
self.assertEqual(t.schema, 'typens')
|
||||||
|
curs.execute("select (4,8)::typensp_ii")
|
||||||
|
self.assertEqual(curs.fetchone()[0], (4, 8))
|
||||||
|
|
||||||
|
@skip_if_no_composite
|
||||||
|
def test_composite_not_found(self):
|
||||||
|
|
||||||
|
self.assertRaises(
|
||||||
|
psycopg2.ProgrammingError, psycopg2.extras.register_composite,
|
||||||
|
"nosuchtype", self.conn)
|
||||||
|
self.assertEqual(self.conn.status, ext.STATUS_READY)
|
||||||
|
|
||||||
|
cur = self.conn.cursor()
|
||||||
|
cur.execute("select 1")
|
||||||
|
self.assertRaises(
|
||||||
|
psycopg2.ProgrammingError, psycopg2.extras.register_composite,
|
||||||
|
"nosuchtype", self.conn)
|
||||||
|
|
||||||
|
self.assertEqual(self.conn.status, ext.STATUS_IN_TRANSACTION)
|
||||||
|
|
||||||
|
self.conn.rollback()
|
||||||
|
self.conn.autocommit = True
|
||||||
|
self.assertRaises(
|
||||||
|
psycopg2.ProgrammingError, psycopg2.extras.register_composite,
|
||||||
|
"nosuchtype", self.conn)
|
||||||
|
self.assertEqual(self.conn.status, ext.STATUS_READY)
|
||||||
|
|
||||||
@skip_if_no_composite
|
@skip_if_no_composite
|
||||||
@skip_before_postgres(8, 4)
|
@skip_before_postgres(8, 4)
|
||||||
def test_composite_array(self):
|
def test_composite_array(self):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user