Thread

  1. translate function (BUG?)

    Edwin Ramirez <ramirez@doc.mssm.edu> — 1999-10-20T18:26:56Z

    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