Обсуждение: funny (cache (?)) bug in postgres (7.x tested)

Поиск
Список
Период
Сортировка

funny (cache (?)) bug in postgres (7.x tested)

От
RISKO Gergely
Дата:
Hello!

I found a funny bug in postgres with c functions. (or feature??)
Let's say we have got an function like this:
CREATE FUNCTION hupper(text)
RETURNS text
AS '/fun.so'
LANGUAGE 'c';

and fun.c:
#include <postgresql/postgres.h>
#include <postgresql/utils/elog.h>
#include <postgresql/libpq/libpq-fs.h>

text *hupper (text *a) {   int hossz,i;
   hossz=a->vl_len;   for (i=0;i<hossz;i++)   {       char ch;       ch=a->vl_dat[i];       if ((ch>=97)&(ch<=122))
ch=ch-32;      else if (ch=='á') ch='Á';       else if (ch=='é') ch='É';       else if (ch=='í') ch='Í';       else if
(ch=='ó')ch='Ó';       else if (ch=='ő') ch='Ő';       else if (ch=='ö') ch='Ö';       else if (ch=='ú') ch='Ú';
elseif (ch=='ű') ch='Ű';       else if (ch=='ü') ch='Ü';       a->vl_dat[i]=ch;   }
 
   return a;
}

We use this to make hungarian upper (=Hupper).
And two select:
gergo=> select mire from mamapenz;mire
-------betetebedebedebedebedebed
(6 rows)

gergo=> select hupper(mire) from mamapenz;hupper
--------BETETEBEDEBEDEBEDEBEDEBED
(6 rows)

this is good, and now:
gergo=> select mire from mamapenz;        ^^^^^^^^^^^^^^^^^^^^^mire
-------BETETEBEDEBEDEBEDEBEDEBED
(6 rows)

After once hupper run on the table it will be upper case even I don't use hupper.
It can be fixed with a postgres restart or with 10-20 minutes of waiting.

If this is documented, sorry (but please point out where).

Thanks,
RISKO Gergely



Re: funny (cache (?)) bug in postgres (7.x tested)

От
Jan Wieck
Дата:
RISKO Gergely wrote:
[Charset iso-8859-1,iso- unsupported, skipping...]

> Hello!
>
> I found a funny bug in postgres with c functions. (or feature??)
> Let's say we have got an function like this:
> CREATE FUNCTION hupper(text)
> RETURNS text
> AS '/fun.so'
> LANGUAGE 'c';
   This  is  actually  neither a feature, nor a bug in Postgres.   Your function is violating some coding rules.
   The text argument handed into is actually residing inside the   shared buffer cache. So you're not supposed to
changeit!
 
   Your function isn't safe for compressed or toasted values. If   you accidentially have big data  in  that  column,
it might   crash the backend completely.
 
   A  function  returning  text has to allocate the return value   with palloc().
   Look into utils/adt/*.c for examples how  to  deal  correctly   with text attributes.


Jan

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me.                                  #
#================================================== JanWieck@Yahoo.com #



_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com



Re: funny (cache (?)) bug in postgres (7.x tested)

От
Alex Pilosov
Дата:
On Thu, 28 Jun 2001, RISKO Gergely wrote:

> text *hupper (text *a) {
>     int hossz,i;
> 
>     hossz=a->vl_len;
>     for (i=0;i<hossz;i++)
>     {
>         char ch;
>         ch=a->vl_dat[i];
>         if ((ch>=97)&(ch<=122)) ch=ch-32;
>         else if (ch=='�') ch='�';
>         else if (ch=='�') ch='�';
>         else if (ch=='�') ch='�';
>         else if (ch=='�') ch='�';
>         else if (ch=='�') ch='�';
>         else if (ch=='�') ch='�';
>         else if (ch=='�') ch='�';
>         else if (ch=='�') ch='�';
>         else if (ch=='�') ch='�';
>         a->vl_dat[i]=ch;
>     }
> 
>     return a;
> }
(Rest snipped).

You are not supposed to write directly to the argument you are given. You
must construct a new text value (by allocating space via palloc) and
copy your string there. By overwriting existing values, you potentially
corrupt postgres' cache, resulting in your behaviour.



Re: funny (cache (?)) bug in postgres (7.x tested)

От
Tom Lane
Дата:
RISKO Gergely <risko@atom.hu> writes:
> I found a funny bug in postgres with c functions. (or feature??)

Scribbling on your input datum is verboten.  palloc a new value
to return.
        regards, tom lane


Re: funny (cache (?)) bug in postgres (7.x tested)

От
Doug McNaught
Дата:
RISKO Gergely <risko@atom.hu> writes:

> text *hupper (text *a) {
>     int hossz,i;
> 
>     hossz=a->vl_len;
>     for (i=0;i<hossz;i++)
>     {
>         char ch;
>         ch=a->vl_dat[i];
>         if ((ch>=97)&(ch<=122)) ch=ch-32;
>         else if (ch=='á') ch='Á';
>         else if (ch=='é') ch='É';
>         else if (ch=='í') ch='Í';
>         else if (ch=='ó') ch='Ó';
>         else if (ch=='õ') ch='Õ';
>         else if (ch=='ö') ch='Ö';
>         else if (ch=='ú') ch='Ú';
>         else if (ch=='û') ch='Û';
>         else if (ch=='ü') ch='Ü';
>         a->vl_dat[i]=ch;
>     }
> 
>     return a;
> }

I think you need to allocate a new TEXT datum and return it.  You're
modifying the cached data in place, which is a no-no AFAIK.

-Doug
-- 
The rain man gave me two cures; he said jump right in,
The first was Texas medicine--the second was just railroad gin,
And like a fool I mixed them, and it strangled up my mind,
Now people just get uglier, and I got no sense of time...          --Dylan