Skip to content

Commit 1ff6eb7

Browse files
author
James William Pye
committed
Fix stored procedure statement rendering.
bug 1010620 reported by Dallas Morisette.
1 parent de86175 commit 1ff6eb7

3 files changed

Lines changed: 36 additions & 18 deletions

File tree

postgresql/driver/pq3.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,12 @@
8080
pg_proc.oid::regprocedure as procedure_id,
8181
-- mm, the pain. the sweet, sweet pain. oh it's portable.
8282
-- it's so portable that it runs on BDB on win32.
83-
COALESCE(string_to_array(trim(textin(array_out(string_to_array(
84-
replace(
85-
trim(textin(oidvectorout(proargtypes)), '{}'),
86-
',', ' '
87-
), ' ')::oid[]::regtype[])), '{}'), ',')::text[], '{}'::text[])
88-
AS _proargs,
83+
COALESCE(
84+
string_to_array(
85+
replace(trim(textin(oidvectorout(proargtypes)), '{}'), ',', ' '), ' '
86+
)::oid[],
87+
'{}'::oid[]
88+
) AS proargtypes,
8989
(pg_type.oid = 'record'::regtype or pg_type.typtype = 'c') AS composite
9090
FROM
9191
pg_proc LEFT JOIN pg_type ON (
@@ -1580,13 +1580,17 @@ def __init__(self, ident, database, description = ()):
15801580
if an is not None:
15811581
self._input_attmap[an] = x
15821582

1583-
proargs = proctup['_proargs']
1583+
tio = database.typio
1584+
proargs = proctup['proargtypes']
1585+
for x in proargs:
1586+
tio.resolve(x)
1587+
15841588
self.statement = database.prepare(
15851589
"SELECT * FROM %s(%s) AS func%s" %(
15861590
proctup['_proid'],
15871591
# ($1::type, $2::type, ... $n::type)
15881592
', '.join([
1589-
'$%d::%s' %(x + 1, proargs[x])
1593+
'$%d::%s' %(x + 1, tio.sql_type_from_oid(proargs[x]))
15901594
for x in range(len(proargs))
15911595
]),
15921596
# Description for anonymous record returns

postgresql/protocol/typio.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ def sql_type_from_oid(self, oid):
730730
if oid in self.typmeta:
731731
nsp, name, *_ = self.typmeta[oid]
732732
return pg_str.quote_ident(nsp) + '.' + pg_str.quote_ident(name)
733-
return pg_types.oid_to_name.get(oid)
733+
return 'pg_catalog.' + pg_types.oid_to_name.get(oid)
734734

735735
def type_from_oid(self, oid):
736736
typ = pg_types.oid_to_type.get(oid)

postgresql/test/test_driver.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -398,37 +398,37 @@ def testStatementAndCursorMetadata(self):
398398

399399
ps = self.db.prepare("SELECT $1::text AS my_text_column")
400400
self.failUnlessEqual(tuple(ps.column_names), ('my_text_column',))
401-
self.failUnlessEqual(tuple(ps.sql_column_types), ('text',))
402-
self.failUnlessEqual(tuple(ps.sql_parameter_types), ('text',))
401+
self.failUnlessEqual(tuple(ps.sql_column_types), ('pg_catalog.text',))
402+
self.failUnlessEqual(tuple(ps.sql_parameter_types), ('pg_catalog.text',))
403403
self.failUnlessEqual(tuple(ps.pg_parameter_types), (pg_types.TEXTOID,))
404404
self.failUnlessEqual(tuple(ps.column_types), (str,))
405405
self.failUnlessEqual(tuple(ps.parameter_types), (str,))
406406
c = ps.declare('textdata')
407407
self.failUnlessEqual(tuple(c.column_names), ('my_text_column',))
408-
self.failUnlessEqual(tuple(c.sql_column_types), ('text',))
408+
self.failUnlessEqual(tuple(c.sql_column_types), ('pg_catalog.text',))
409409
self.failUnlessEqual(tuple(c.pg_column_types), (pg_types.TEXTOID,))
410410
self.failUnlessEqual(tuple(c.column_types), (str,))
411411

412412
ps = self.db.prepare("SELECT $1::text AS my_column1, $2::varchar AS my_column2")
413413
self.failUnlessEqual(tuple(ps.column_names), ('my_column1','my_column2'))
414-
self.failUnlessEqual(tuple(ps.sql_column_types), ('text', 'CHARACTER VARYING'))
415-
self.failUnlessEqual(tuple(ps.sql_parameter_types), ('text', 'CHARACTER VARYING'))
414+
self.failUnlessEqual(tuple(ps.sql_column_types), ('pg_catalog.text', 'CHARACTER VARYING'))
415+
self.failUnlessEqual(tuple(ps.sql_parameter_types), ('pg_catalog.text', 'CHARACTER VARYING'))
416416
self.failUnlessEqual(tuple(ps.pg_parameter_types), (pg_types.TEXTOID, pg_types.VARCHAROID))
417417
self.failUnlessEqual(tuple(ps.pg_column_types), (pg_types.TEXTOID, pg_types.VARCHAROID))
418418
self.failUnlessEqual(tuple(ps.parameter_types), (str,str))
419419
self.failUnlessEqual(tuple(ps.column_types), (str,str))
420420
c = ps.declare('textdata', 'varchardata')
421421
self.failUnlessEqual(tuple(c.column_names), ('my_column1','my_column2'))
422-
self.failUnlessEqual(tuple(c.sql_column_types), ('text', 'CHARACTER VARYING'))
422+
self.failUnlessEqual(tuple(c.sql_column_types), ('pg_catalog.text', 'CHARACTER VARYING'))
423423
self.failUnlessEqual(tuple(c.pg_column_types), (pg_types.TEXTOID, pg_types.VARCHAROID))
424424
self.failUnlessEqual(tuple(c.column_types), (str,str))
425425

426426
self.db.execute("CREATE TYPE public.myudt AS (i int)")
427427
myudt_oid = self.db.prepare("select oid from pg_type WHERE typname='myudt'").first()
428428
ps = self.db.prepare("SELECT $1::text AS my_column1, $2::varchar AS my_column2, $3::public.myudt AS my_column3")
429429
self.failUnlessEqual(tuple(ps.column_names), ('my_column1','my_column2', 'my_column3'))
430-
self.failUnlessEqual(tuple(ps.sql_column_types), ('text', 'CHARACTER VARYING', 'public.myudt'))
431-
self.failUnlessEqual(tuple(ps.sql_parameter_types), ('text', 'CHARACTER VARYING', 'public.myudt'))
430+
self.failUnlessEqual(tuple(ps.sql_column_types), ('pg_catalog.text', 'CHARACTER VARYING', 'public.myudt'))
431+
self.failUnlessEqual(tuple(ps.sql_parameter_types), ('pg_catalog.text', 'CHARACTER VARYING', 'public.myudt'))
432432
self.failUnlessEqual(tuple(ps.pg_column_types), (
433433
pg_types.TEXTOID, pg_types.VARCHAROID, myudt_oid)
434434
)
@@ -439,7 +439,7 @@ def testStatementAndCursorMetadata(self):
439439
self.failUnlessEqual(tuple(ps.column_types), (str,str,tuple))
440440
c = ps.declare('textdata', 'varchardata', (123,))
441441
self.failUnlessEqual(tuple(c.column_names), ('my_column1','my_column2', 'my_column3'))
442-
self.failUnlessEqual(tuple(c.sql_column_types), ('text', 'CHARACTER VARYING', 'public.myudt'))
442+
self.failUnlessEqual(tuple(c.sql_column_types), ('pg_catalog.text', 'CHARACTER VARYING', 'public.myudt'))
443443
self.failUnlessEqual(tuple(c.pg_column_types), (
444444
pg_types.TEXTOID, pg_types.VARCHAROID, myudt_oid
445445
))
@@ -589,6 +589,20 @@ def testProcExecution(self):
589589
ifoo = self.db.proc('ifoo(int)')
590590
self.failUnless(ifoo(1) == 1)
591591
self.failUnless(ifoo(None) is None)
592+
self.db.execute(
593+
"CREATE OR REPLACE FUNCTION ifoo(varchar) RETURNS text LANGUAGE SQL AS 'select $1'"
594+
)
595+
ifoo = self.db.proc('ifoo(varchar)')
596+
self.failUnlessEqual(ifoo('1'), '1')
597+
self.failUnlessEqual(ifoo(None), None)
598+
self.db.execute(
599+
"CREATE OR REPLACE FUNCTION ifoo(varchar,int) RETURNS text LANGUAGE SQL AS 'select ($1::int + $2)::varchar'"
600+
)
601+
ifoo = self.db.proc('ifoo(varchar,int)')
602+
self.failUnlessEqual(ifoo('1',1), '2')
603+
self.failUnlessEqual(ifoo(None,1), None)
604+
self.failUnlessEqual(ifoo('1',None), None)
605+
self.failUnlessEqual(ifoo('2',2), '4')
592606

593607
def testProcExecutionInXact(self):
594608
with self.db.xact():

0 commit comments

Comments
 (0)