10

I've got a function that returns two parameters as an anonymous composite type via output parameters.

I can access the individual columns with a query like this:

# select * from guess_user('Joe','Bloggs');
 confidence | matchid 
------------+---------
   0.142857 |    1121

Now I want to combine the output from this function with some data:

# select firstname,lastname from users limit 5;
 firstname | lastname 
-----------+----------
 Adam      | Smith
 Amy       | Peters
 Annette   | Bloggs
 Annie     | Mills
 Amanda    | Hibbins

I am looking for a query that will output the following:

 firstname | lastname | confidence | matchid 
-----------+----------+------------+---------
 Adam      | Smith    |            | 
 Amy       | Peters   |            | 
 Annette   | Bloggs   |            | 
 Annie     | Mills    |            | 
 Amanda    | Hibbins  |            | 

With the confidence and matchid columns filled out using the results of calling guess_user with the names from that row.

My current closest effort is:

# select firstname, lastname, guess_user(firstname, lastname) from users limit 5;

Which returns:

 firstname | lastname  |  guess_user   
-----------+-----------+---------------
 Angela    | Abbott    | (0.285714,3)
 Amy       | Allan     | (0.285714,4)
 Annette   | Allison   | (0.285714,5)
 Annie     | Ashworth  | (0.285714,6)
 Amanda    | Baird     | (0.285714,7)

Is there a way to split the guess_user output into separate columns?

2
  • In case it's helpful for anyone wanting to experiment, here's a function that will return the same record type as the one I'm using: create or replace function guess_user ( firstname varchar, lastname varchar, OUT confidence real, OUT matchid integer ) as $$ BEGIN matchid := 1; confidence := 0.5; RETURN; END; $$ LANGUAGE plpgsql; Commented Dec 11, 2009 at 4:25
  • Would it be possible to implement this as a view instead? developer.postgresql.org/pgdocs/postgres/sql-createview.html Commented Dec 11, 2009 at 5:05

5 Answers 5

14

combining depesz and fazal's answers this seems to work:

select firstname, lastname, (guess_user(firstname, lastname)).*
from users
limit 5
Sign up to request clarification or add additional context in comments.

1 Comment

To add a little more information, per postgresql.org/docs/9.3/static/rowtypes.html "To access a field of a composite column, one writes a dot and the field name, much like selecting a field from a table name. In fact, it's so much like selecting from a table name that you often have to use parentheses to keep from confusing the parser."
2

Simply make it like this:

select firstname, lastname, x.confidence, x.matchid
from 
(
select firstname, lastname, guess_user(firstname, lastname) as x
from users
limit 5
) q;

1 Comment

You have to use parenthesis around to access composite type fields: select firstname, lastname, (x).confidence, (x).matchid Otherwise, get this error: "missing FROM-clause entry for table "x""
1

You need to change your function to return a set - the last example is identical to the functionality you are asking for.

2 Comments

RETURNS SETOF record to indicate that the function returns multiple rows instead of just one. They aren't tied to an existing table, you could return a TYPE instead if you preferred. wiki.postgresql.org/wiki/…
Thanks, I gave that a go but I still couldn't seem to put the function in the right place to get it to work. This page: depesz.com/index.php/2008/11/03/… Seems to suggest it's a limitation of postgres, which is solved on 8.4 (I'm running 8.3.8).
0

Unless someone comes along and corrects me, I believe that the answer is that it's currently not possible in 8.3 but can be done in Postgres 8.4.

http://www.depesz.com/index.php/2008/11/03/waiting-for-84-pl-srf-functions-in-selects/

Comments

0

You may need to parenthesize the "x" in depesz's solution, to distinguish the composite record value from a table, so you don't get the message:

missing FROM-clause entry for table "x"

At least I do on 9.0.2.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.