bug + patch

From: Massimo Dal Zotto <dz(at)cs(dot)unitn(dot)it>
To: hackers(at)postgreSQL(dot)org (PostgreSQL Hackers), pgsql-patches(at)postgreSQL(dot)org (Pgsql Patches)
Subject: bug + patch
Date: 1998-08-30 15:24:36
Message-ID: 199808301524.RAA13046@nikita.wizard.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi Hackers,

I am porting my old contrib modules to 6.4. While testing string_io I found
this strange bug:

dz=> select textin(textout('a\007b'));
textin
------
ab
(1 row)

dz=> \i /usr/local/pgsql/lib/sql/string_io.sql;
...
dz=> select textin(c_textout('a\007b'));
textin
------
a\\007b
(1 row)

Ok, seems that my code is working, so I try to use it as typoutput for text:

dz=> update pg_type set typoutput='c_textout' where typname='text';
UPDATE 1
dz=> select 'abc'::text;

and at this point psql hangs forever. Hitting Ctrl-C sends cancel requests
to the backend but these have no effect because it has already finished
processing the query, while psql is still waiting for data.
Evidently that some output has been lost.

After some playing with gdb I found that in printtup() there is a non null
attribute with typeinfo->attrs[i]->atttypid = 0 (invalid oid). Unfortunately
attibutes with invalid type are neither printed nor marked as null, and this
explains why psql doesn't get all the expected data.

So I made this patch to printtup():

*** src/backend/access/common/printtup.c.orig Wed Aug 26 09:00:30 1998
--- src/backend/access/common/printtup.c Sun Aug 30 17:16:55 1998
***************
*** 123,131 ****
for (i = 0; i < tuple->t_natts; ++i)
{
attr = heap_getattr(tuple, i + 1, typeinfo, &isnull);
! typoutput = typtoout((Oid) typeinfo->attrs[i]->atttypid);

! if (!isnull && OidIsValid(typoutput))
{
outputstr = fmgr(typoutput, attr,
gettypelem(typeinfo->attrs[i]->atttypid),
--- 123,133 ----
for (i = 0; i < tuple->t_natts; ++i)
{
attr = heap_getattr(tuple, i + 1, typeinfo, &isnull);
! if (isnull)
! continue;

! typoutput = typtoout((Oid) typeinfo->attrs[i]->atttypid);
! if (OidIsValid(typoutput))
{
outputstr = fmgr(typoutput, attr,
gettypelem(typeinfo->attrs[i]->atttypid),
***************
*** 140,145 ****
--- 142,153 ----
#endif
pfree(outputstr);
}
+ else
+ {
+ outputstr = "<unprintable>";
+ pq_putint(strlen(outputstr) + VARHDRSZ, VARHDRSZ);
+ pq_putnchar(outputstr, strlen(outputstr));
+ }
}
}

Now the communication between the backend and psql is correct and I get:

dz=> select 'abc'::text;
?column?
-------------
<unprintable>
(1 row)

Still wrong but at least it doesn't hang and I can go on with investigation.
So I recreate a new db and try the following:

dz=> select typname,typoutput from pg_type where typname='text';
typname|typoutput
-------+-----------
text |47(textout)
(1 row)

dz=> update pg_type set typoutput = 'textout' where typname='text';
UPDATE 1
dz=> select typname,typoutput from pg_type where typname='text';
typname|typoutput
-------+---------
text | -

dz=> select 'abc'::text;
?column?
-------------
<unprintable>
(1 row)

dz=> update pg_type set typoutput = 'textout'::regproc where typname='text';
UPDATE 1
dz=> select 'abc'::text;
?column?
-------------
<unprintable>
(1 row)

So the problem is not in my c_textout() but in the update of typoutput.
After a few experiments I found that the only way to change this attribute
is to specify the oid of the functions instead of the name:

dz=> update pg_type set typoutput = 47::regproc where typname='text';
UPDATE 1
dz=> select 'abc'::text;
?column?
--------
abc
(1 row)

dz=> select oid from pg_proc where proname='c_textout';
oid
-----
18561
(1 row)

dz=> update pg_type set typoutput = 18561::regproc where typname='text';
UPDATE 1
dz=> select 'abc'::text;
?column?
--------
abc
(1 row)

However supplying the proc name was ok in previous version of postgres, so
we must have broken something. Could please those who worked in this area
have a look at their changes?

--
Massimo Dal Zotto

+----------------------------------------------------------------------+
| Massimo Dal Zotto email: dz(at)cs(dot)unitn(dot)it |
| Via Marconi, 141 phone: ++39-461-534251 |
| 38057 Pergine Valsugana (TN) www: http://www.cs.unitn.it/~dz/ |
| Italy pgp: finger dz(at)tango(dot)cs(dot)unitn(dot)it |
+----------------------------------------------------------------------+

Browse pgsql-hackers by date

  From Date Subject
Next Message David Hartwig 1998-08-30 15:40:31 Re: [INTERFACES] Re: [HACKERS] changes in 6.4
Previous Message Tom Lane 1998-08-30 15:23:38 Re: [HACKERS] flock patch breaks things here