bug + patch - Mailing list pgsql-hackers

From Massimo Dal Zotto
Subject bug + patch
Date
Msg-id 199808301524.RAA13046@nikita.wizard.net
Whole thread Raw
List 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@cs.unitn.it             |
|  Via Marconi, 141                 phone:  ++39-461-534251            |
|  38057 Pergine Valsugana (TN)     www:  http://www.cs.unitn.it/~dz/  |
|  Italy                            pgp:  finger dz@tango.cs.unitn.it  |
+----------------------------------------------------------------------+

pgsql-hackers by date:

Previous
From: Massimo Dal Zotto
Date:
Subject: updated contrib modules
Next
From: Massimo Dal Zotto
Date:
Subject: Re: [HACKERS] flock patch breaks things here