1

I have the Postgres function below to return some info from my DB. I need the p_ic parameter to be able to take an array of strings.

CREATE OR REPLACE FUNCTION eddie.getinv(
    IN p_ic character varying[],
    IN p_id character varying)
  RETURNS TABLE(cnt bigint, actualid text, actualcompany text, part text, daysinstock double precision, condition text, 
                ic text, price numeric, stock text, quantity bigint, location text, comments text) AS
$
BEGIN
    RETURN QUERY
        WITH cte AS (
                SELECT 
                CASE WHEN partnerslist IS NULL OR partnerslist = '' THEN
                    'XX99'
                ELSE 
                    partnerslist
                END AS a
            FROM support.members WHERE id = p_id
        ), ctegroup AS
        (    
            SELECT 
               u.id AS actualid,
              (SELECT m.company || ' (' || m.id ||')' FROM support.members m WHERE m.id = u.id) AS actualcompany,
              u.itemname AS part, 
              DATE_PART('day', CURRENT_TIMESTAMP - u.datein::timestamp) AS daysinstock, 
              TRIM(u.grade)::character varying AS condition, 
              u.vstockno::text AS stock, 
              u.holl::text AS ic, 
              CASE WHEN u.rprice > 0 THEN 
                    u.rprice 
              ELSE 
                    NULL 
              END AS price, 
              u.quantity, 
              u.location,
              u.comments::text
            FROM public.net u 
            WHERE u.holl in (p_ic)
              AND visibledate <= now() 
              AND u.id = ANY(REGEXP_SPLIT_TO_ARRAY(p_id ||','|| (SELECT a FROM cte), ','))
            ORDER BY u.itemname, u.id
        )  
        SELECT 
            COUNT(ctegroup.ic) OVER(PARTITION BY ctegroup.ic ORDER BY ctegroup.ic) AS cnt,
            actualid,
            MAX(actualcompany) AS actualcompany,
            MAX(part) AS part,
            MAX(daysinstock) AS daysinstock, 
            STRING_AGG(condition,',') AS condition, 
            MAX(ic) AS ic,
            MAX(price) AS price,
            STRING_AGG(stock,',') AS stock, 
            SUM(quantity) AS qty, 
            STRING_AGG(location,',') AS location,
            STRING_AGG(comments,';') AS comments
        FROM ctegroup
        GROUP BY part, actualid, ic
        ORDER BY actualid;
END; $

LANGUAGE 'plpgsql';

I am calling it from the pgAdminIII Query window like this:

SELECT * FROM eddie.getinv(array['536-01036','536-01033L','536-01037'], 'N40')

But it is returning this error:

ERROR:  operator does not exist: text = character varying[]`
LINE 28:             WHERE u.holl in (p_ic)`

How do I fix this, or am I calling it incorrectly? I will be calling it from a PHP API function similar to this:

$id = 'N40';
$ic = array('536-01036','536-01033L','536-01037');

$sql = "SELECT * FROM eddie.getinv(array['". implode("','",$ic)."'], '".$id."');";

try 
{       
    $results = pg_query($sql);
    if(pg_num_rows($results) == 0) {
        $rows = [];
    }
    else
    {
        $data = pg_fetch_all($results);
        foreach($data as $item)
        {                    
            $rows[$item["ic"]][] = $item;
        }
    }
    pg_free_result($results);
}
catch (Exception $e) 
{
    $err = array("message"=>$e->getMessage(), "code"=> $e->getCode(), "error"=>$e->__toString().",\n".print_r($_REQUEST, true));
    echo json_encode($err);
}
echo json_encode($rows);
2
  • Have you tried replacing the varying[] type to text[] ? Jun 12, 2018 at 21:31
  • same error but text = text[]
    – MB34
    Jun 12, 2018 at 21:50

1 Answer 1

1

It looks like your array is being passed to the function just fine. The problem is in your query.

IN () clauses expect a comma-separated list of values. When you put an array in there, it's interpreted as a one-element list, where the value is the whole array. In other words, u.holl in (p_ic) will check if u.holl is equal to p_ic, and the comparison fails due to the type mismatch.

If you want to test the value against the contents of the array, use u.holl = ANY(p_ic).

3
  • If I do it like that, it returns 112 rows. If I replace the p_ic with the contents of the array and use in, it returns 14, which is correct.
    – MB34
    Jun 12, 2018 at 21:55
  • What would be the opposite of regex_split_to_array() so I can take the array and make it a comma-separated list of values to use in the in?
    – MB34
    Jun 12, 2018 at 21:56
  • Actually it should be 36 rows returned, not 14. I modified to WHERE u.holl in (SELECT unnest(p_ic)) This is the solution that worked.
    – MB34
    Jun 12, 2018 at 22:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.