translate function (BUG?)

Edwin Ramirez <ramirez@doc.mssm.edu>

From: Edwin Ramirez <ramirez@doc.mssm.edu>
To: pgsql-hackers@postgreSQL.org
Date: 1999-10-20T18:26:56Z
Lists: pgsql-hackers
Hello all,

I was looking at the translate function and I think that it does not
behave quite right.  I modified the translate function in
oracle_compat.c (included below) to make work more like its Oracle
counterpart. It seems to work but it returns the following message:
	NOTICE:  PortalHeapMemoryFree: 0x8241fcc not in alloc set!

Below are the Oracle and Postgres session transcripts.  

select translate('edwin', 'wi', 'af') from dual;
ORACLE:
TRANS
-----
edafn
1 row selected.

POSTGRES
translate
---------
edain    
(1 row)

select translate('edwin', 'wi', 'a') from dual;
ORACLE
TRAN
----
edan
1 row selected.

POSTGRES
translate
---------
edain    
(1 row)

select length(translate('edwin', 'wi', 'a')) from dual;
ORACLE
LENGTH(TRA
----------
         4
1 row selected.

POSTGRES
length
------
     5
(1 row)


-----------------------NEW
FUNCTION--------------------------------------
text *
translate(text *string, text *from, text *to)
{
	text	   *ret;
	char	   *ptr_ret, *from_ptr, *to_ptr, *source, *target, *temp, rep;
	int	   m, fromlen, tolen, retlen, i;

	if ((string == (text *) NULL) ||
		((m = VARSIZE(string) - VARHDRSZ) <= 0))
		return string;

	target   = (char *) palloc(VARSIZE(string) - VARHDRSZ);
	source   = VARDATA(string);
	temp     = target;

	fromlen = VARSIZE(from) - VARHDRSZ;
	from_ptr = VARDATA(from);
	tolen = VARSIZE(to) - VARHDRSZ;
	to_ptr   = VARDATA(to);
	retlen = 0;
	while (m--)
	{
	  rep = *source;
	  for(i=0;i<fromlen;i++) {
	    if(from_ptr[i] == *source)  {
	      if(i < tolen) {
		rep = to_ptr[i];
	      } else {
		rep = 0;
	      }
	      break;
	    }
	  }
	  if(rep != 0) {
	    *target++ = rep;
	    retlen++;
	  }
	  source++;
	}

	ret = (text *) palloc(retlen + VARHDRSZ);
	VARSIZE(ret) = retlen + VARHDRSZ;
	ptr_ret = VARDATA(ret);
	for(i=0;i<retlen;i++) {
	  *ptr_ret++ = temp[i];
	}
	pfree(target);
	return ret;
}


Thanks,
Edwin S. Ramirez