CREATE OR REPLACE FUNCTION F_WORDS_USD_1 (p_number IN NUMERIC)
   RETURNS VARCHAR AS 
$$
DECLARE
   l_str VARCHAR[] := ARRAY['', 'thousand', 'million', 'billion', 'trillion', 'quadrillion', 'quintillion', 'sextillion', 
                            'septillion', 'octillion', 'nonillion', 'decillion', 'undecillion'];
   l_num      VARCHAR(50) := TRUNC(p_number)::VARCHAR;
   l_return   VARCHAR := '';
   l_decimal  NUMERIC;
   l_return_decimal VARCHAR := '';
BEGIN
   SELECT (p_number::DECIMAL - l_num::DECIMAL) INTO l_decimal;
   FOR i IN 1 .. array_length(l_str, 1)
   LOOP
      EXIT WHEN l_num IS NULL;
      IF (SUBSTRING(l_num FROM GREATEST(LENGTH(l_num) - 2, 1) FOR 3) <> '000')
      THEN
         l_return := TO_CHAR(TO_DATE(SUBSTRING(l_num FROM GREATEST(LENGTH(l_num) - 2, 1) FOR 3), 'J'), 'Jsp') || ' ' ||
                     l_str[i] || CASE WHEN i != 1 THEN ' ' ELSE '' END || l_return;
      END IF;
      l_num := SUBSTRING(l_num FROM 1 FOR LENGTH(l_num) - 3);
   END LOOP;
   IF l_return IS NOT NULL THEN
      l_return := l_return || ' US Dollar ';
   END IF;
   IF l_decimal != 0
   THEN
      l_decimal := l_decimal * 100;
      IF (SUBSTRING(l_decimal::VARCHAR FROM GREATEST(LENGTH(l_decimal::VARCHAR) - 2, 1) FOR 3) <> '000')
      THEN
         l_return_decimal := TO_CHAR(TO_DATE(SUBSTRING(l_decimal::VARCHAR FROM GREATEST(LENGTH(l_decimal::VARCHAR) - 2, 1) FOR 3), 'J'), 'Jsp');
      END IF;
      l_return :=  l_return || ' and ' || l_return_decimal || ' Cents ';
   END IF;
   IF l_return IS NOT NULL THEN
      l_return := l_return || 'Only';
   END IF;
   RETURN l_return;
END
$$ LANGUAGE plpgsql;

fix the error in the given function and give new function with defect free
ERROR: negative substring length not allowed
  Where: PL/pgSQL function f_words_usd_1(numeric) line 19 at assignment