Skip to main content
markup, format, fiddle, link
Source Link
Erwin Brandstetter
  • 182.2k
  • 28
  • 457
  • 620

There is a way.

Given a table t and a function f() that returns an anonymous record that would match that table type:

CREATE TABLE t (id int, d date);

You cannot just cast the anonymous record, since a column definition list is required for

SELECT * FROM f()

Quoting the manual on the SELECT commandthe manual on the SELECT command:

If the function has been defined as returning the record data type, then an alias or the key word AS must be present, followed by a column definition list in the form ...

Bold emphasis mine.

So, while all of these queries work:

SELECT '(1,2013-11-11)'::t;
SELECT ('(1,2013-11-11)'::t).*;
SELECT f();                      -- returning anonymous record
SELECT * FROM f() AS f(id int, d date);

Neither of these do:

SELECT * FROM f();
SELECT * FROM f()::t;

The latter raising an exception:

ERROR: cannot cast type record to t

You could wrap the SELECT with column definition list into a VIEW or function like @a_horse and @deszo suggested. That would work just fine:

CREATE OR REPLACE VIEW v1 AS
SELECT * FROM f() AS f(id int, d date);

But that wouldn't answer your question:

convert the record (or setof record return type) into the T rowtype without listing the attributes?

Solution for single row

###Solution for single row WhileWhile a cast fails, an assignment in plpgsql works.

CREATE OR REPLACE function f1(OUT rec t) AS
$func$
BEGIN
rec := f();   -- assignment succeeds where cast failed (!)
END
$func$ LANGUAGE plpgsql;
CREATE OR REPLACE function f1(OUT rec t)
  LANGUAGE plpgsql AS
$func$
BEGIN
   rec := f();   -- assignment succeeds where cast failed (!)
END
$func$;

Call:

SELECT * FROM f1();

While you can also write a set returning function with that pattern I did not find a way to SELECT from a set returning function without supplying a column definition list ...

->SQLfiddledb<>fiddle here
Old sqlfiddle

There is a way.

Given a table t and a function f() that returns an anonymous record that would match that table type:

CREATE TABLE t (id int, d date);

You cannot just cast the anonymous record, since a column definition list is required for

SELECT * FROM f()

Quoting the manual on the SELECT command:

If the function has been defined as returning the record data type, then an alias or the key word AS must be present, followed by a column definition list in the form ...

Bold emphasis mine.

So, while all of these queries work:

SELECT '(1,2013-11-11)'::t;
SELECT ('(1,2013-11-11)'::t).*;
SELECT f();                      -- returning anonymous record
SELECT * FROM f() AS f(id int, d date);

Neither of these do:

SELECT * FROM f();
SELECT * FROM f()::t;

The latter raising an exception:

ERROR: cannot cast type record to t

You could wrap the SELECT with column definition list into a VIEW or function like @a_horse and @deszo suggested. That would work just fine:

CREATE OR REPLACE VIEW v1 AS
SELECT * FROM f() AS f(id int, d date);

But that wouldn't answer your question:

convert the record (or setof record return type) into the T rowtype without listing the attributes?

###Solution for single row While a cast fails, an assignment in plpgsql works.

CREATE OR REPLACE function f1(OUT rec t) AS
$func$
BEGIN
rec := f();   -- assignment succeeds where cast failed (!)
END
$func$ LANGUAGE plpgsql;

Call:

SELECT * FROM f1();

While you can also write a set returning function with that pattern I did not find a way to SELECT from a set returning function without supplying a column definition list ...

->SQLfiddle

There is a way.

Given a table t and a function f() that returns an anonymous record that would match that table type:

CREATE TABLE t (id int, d date);

You cannot just cast the anonymous record, since a column definition list is required for

SELECT * FROM f()

Quoting the manual on the SELECT command:

If the function has been defined as returning the record data type, then an alias or the key word AS must be present, followed by a column definition list in the form ...

Bold emphasis mine.

So, while all of these queries work:

SELECT '(1,2013-11-11)'::t;
SELECT ('(1,2013-11-11)'::t).*;
SELECT f();                      -- returning anonymous record
SELECT * FROM f() AS f(id int, d date);

Neither of these do:

SELECT * FROM f();
SELECT * FROM f()::t;

The latter raising an exception:

ERROR: cannot cast type record to t

You could wrap the SELECT with column definition list into a VIEW or function like @a_horse and @deszo suggested. That would work just fine:

CREATE OR REPLACE VIEW v1 AS
SELECT * FROM f() AS f(id int, d date);

But that wouldn't answer your question:

convert the record (or setof record return type) into the T rowtype without listing the attributes?

Solution for single row

While a cast fails, an assignment in plpgsql works.

CREATE OR REPLACE function f1(OUT rec t)
  LANGUAGE plpgsql AS
$func$
BEGIN
   rec := f();   -- assignment succeeds where cast failed (!)
END
$func$;

Call:

SELECT * FROM f1();

While you can also write a set returning function with that pattern I did not find a way to SELECT from a set returning function without supplying a column definition list ...

db<>fiddle here
Old sqlfiddle

replaced http://dba.stackexchange.com/ with https://dba.stackexchange.com/
Source Link

There is a way.

Given a table t and a function f() that returns an anonymous record that would match that table type:

CREATE TABLE t (id int, d date);

You cannot just cast the anonymous record, since a column definition list is required for

SELECT * FROM f()

Quoting the manual on the SELECT command:

If the function has been defined as returning the record data type, then an alias or the key word AS must be present, followed by a column definition list in the form ...

Bold emphasis mine.

So, while all of these queries work:

SELECT '(1,2013-11-11)'::t;
SELECT ('(1,2013-11-11)'::t).*;
SELECT f();                      -- returning anonymous record
SELECT * FROM f() AS f(id int, d date);

Neither of these do:

SELECT * FROM f();
SELECT * FROM f()::t;

The latter raising an exception:

ERROR: cannot cast type record to t

You could wrap the SELECT with column definition list into a VIEW or function like @a_horse@a_horse and @deszo@deszo suggested. That would work just fine:

CREATE OR REPLACE VIEW v1 AS
SELECT * FROM f() AS f(id int, d date);

But that wouldn't answer your question:

convert the record (or setof record return type) into the T rowtype without listing the attributes?

###Solution for single row While a cast fails, an assignment in plpgsql works.

CREATE OR REPLACE function f1(OUT rec t) AS
$func$
BEGIN
rec := f();   -- assignment succeeds where cast failed (!)
END
$func$ LANGUAGE plpgsql;

Call:

SELECT * FROM f1();

While you can also write a set returning function with that pattern I did not find a way to SELECT from a set returning function without supplying a column definition list ...

->SQLfiddle

There is a way.

Given a table t and a function f() that returns an anonymous record that would match that table type:

CREATE TABLE t (id int, d date);

You cannot just cast the anonymous record, since a column definition list is required for

SELECT * FROM f()

Quoting the manual on the SELECT command:

If the function has been defined as returning the record data type, then an alias or the key word AS must be present, followed by a column definition list in the form ...

Bold emphasis mine.

So, while all of these queries work:

SELECT '(1,2013-11-11)'::t;
SELECT ('(1,2013-11-11)'::t).*;
SELECT f();                      -- returning anonymous record
SELECT * FROM f() AS f(id int, d date);

Neither of these do:

SELECT * FROM f();
SELECT * FROM f()::t;

The latter raising an exception:

ERROR: cannot cast type record to t

You could wrap the SELECT with column definition list into a VIEW or function like @a_horse and @deszo suggested. That would work just fine:

CREATE OR REPLACE VIEW v1 AS
SELECT * FROM f() AS f(id int, d date);

But that wouldn't answer your question:

convert the record (or setof record return type) into the T rowtype without listing the attributes?

###Solution for single row While a cast fails, an assignment in plpgsql works.

CREATE OR REPLACE function f1(OUT rec t) AS
$func$
BEGIN
rec := f();   -- assignment succeeds where cast failed (!)
END
$func$ LANGUAGE plpgsql;

Call:

SELECT * FROM f1();

While you can also write a set returning function with that pattern I did not find a way to SELECT from a set returning function without supplying a column definition list ...

->SQLfiddle

There is a way.

Given a table t and a function f() that returns an anonymous record that would match that table type:

CREATE TABLE t (id int, d date);

You cannot just cast the anonymous record, since a column definition list is required for

SELECT * FROM f()

Quoting the manual on the SELECT command:

If the function has been defined as returning the record data type, then an alias or the key word AS must be present, followed by a column definition list in the form ...

Bold emphasis mine.

So, while all of these queries work:

SELECT '(1,2013-11-11)'::t;
SELECT ('(1,2013-11-11)'::t).*;
SELECT f();                      -- returning anonymous record
SELECT * FROM f() AS f(id int, d date);

Neither of these do:

SELECT * FROM f();
SELECT * FROM f()::t;

The latter raising an exception:

ERROR: cannot cast type record to t

You could wrap the SELECT with column definition list into a VIEW or function like @a_horse and @deszo suggested. That would work just fine:

CREATE OR REPLACE VIEW v1 AS
SELECT * FROM f() AS f(id int, d date);

But that wouldn't answer your question:

convert the record (or setof record return type) into the T rowtype without listing the attributes?

###Solution for single row While a cast fails, an assignment in plpgsql works.

CREATE OR REPLACE function f1(OUT rec t) AS
$func$
BEGIN
rec := f();   -- assignment succeeds where cast failed (!)
END
$func$ LANGUAGE plpgsql;

Call:

SELECT * FROM f1();

While you can also write a set returning function with that pattern I did not find a way to SELECT from a set returning function without supplying a column definition list ...

->SQLfiddle

sqlfiddle is up again
Source Link
Erwin Brandstetter
  • 182.2k
  • 28
  • 457
  • 620

There is a way.

Given a table t and a function f() that returns an anonymous record that would match that table type:

CREATE TABLE t (id int, d date);

You cannot just cast the anonymous record, since a column definition list is required for

SELECT * FROM f()

Quoting the manual on the SELECT command:

If the function has been defined as returning the record data type, then an alias or the key word AS must be present, followed by a column definition list in the form ...

Bold emphasis mine.

So, while all of these queries work:

SELECT '(1,2013-11-11)'::t;
SELECT ('(1,2013-11-11)'::t).*;
SELECT f();                      -- returning anonymous record
SELECT * FROM f() AS f(id int, d date);

Neither of these do:

SELECT * FROM f();
SELECT * FROM f()::t;

The latter raising an exception:

ERROR: cannot cast type record to t

You could wrap the SELECT with column definition list into a VIEW or function like @a_horse and @deszo suggested. That would work just fine:

CREATE OR REPLACE VIEW v1 AS
SELECT * FROM f() AS f(id int, d date);

But that wouldn't answer your question:

convert the record (or setof record return type) into the T rowtype without listing the attributes?

###Solution for single row While a cast fails, an assignment in plpgsql works.

CREATE OR REPLACE function f1(OUT rec t) AS
$func$
BEGIN
rec := f();   -- assignment succeeds where cast failed (!)
END
$func$ LANGUAGE plpgsql;

Call:

SELECT * FROM f1();

While you can also write a set returning function with that pattern I did not find a way to SELECT from a set returning function without supplying a column definition list ...

->SQLfiddle->SQLfiddle .. is down atm ..

There is a way.

Given a table t and a function f() that returns an anonymous record that would match that table type:

CREATE TABLE t (id int, d date);

You cannot just cast the anonymous record, since a column definition list is required for

SELECT * FROM f()

Quoting the manual on the SELECT command:

If the function has been defined as returning the record data type, then an alias or the key word AS must be present, followed by a column definition list in the form ...

Bold emphasis mine.

So, while all of these queries work:

SELECT '(1,2013-11-11)'::t;
SELECT ('(1,2013-11-11)'::t).*;
SELECT f();                      -- returning anonymous record
SELECT * FROM f() AS f(id int, d date);

Neither of these do:

SELECT * FROM f();
SELECT * FROM f()::t;

The latter raising an exception:

ERROR: cannot cast type record to t

You could wrap the SELECT with column definition list into a VIEW or function like @a_horse and @deszo suggested. That would work just fine:

CREATE OR REPLACE VIEW v1 AS
SELECT * FROM f() AS f(id int, d date);

But that wouldn't answer your question:

convert the record (or setof record return type) into the T rowtype without listing the attributes?

###Solution for single row While a cast fails, an assignment in plpgsql works.

CREATE OR REPLACE function f1(OUT rec t) AS
$func$
BEGIN
rec := f();   -- assignment succeeds where cast failed (!)
END
$func$ LANGUAGE plpgsql;

Call:

SELECT * FROM f1();

While you can also write a set returning function with that pattern I did not find a way to SELECT from a set returning function without supplying a column definition list ...

->SQLfiddle .. is down atm ..

There is a way.

Given a table t and a function f() that returns an anonymous record that would match that table type:

CREATE TABLE t (id int, d date);

You cannot just cast the anonymous record, since a column definition list is required for

SELECT * FROM f()

Quoting the manual on the SELECT command:

If the function has been defined as returning the record data type, then an alias or the key word AS must be present, followed by a column definition list in the form ...

Bold emphasis mine.

So, while all of these queries work:

SELECT '(1,2013-11-11)'::t;
SELECT ('(1,2013-11-11)'::t).*;
SELECT f();                      -- returning anonymous record
SELECT * FROM f() AS f(id int, d date);

Neither of these do:

SELECT * FROM f();
SELECT * FROM f()::t;

The latter raising an exception:

ERROR: cannot cast type record to t

You could wrap the SELECT with column definition list into a VIEW or function like @a_horse and @deszo suggested. That would work just fine:

CREATE OR REPLACE VIEW v1 AS
SELECT * FROM f() AS f(id int, d date);

But that wouldn't answer your question:

convert the record (or setof record return type) into the T rowtype without listing the attributes?

###Solution for single row While a cast fails, an assignment in plpgsql works.

CREATE OR REPLACE function f1(OUT rec t) AS
$func$
BEGIN
rec := f();   -- assignment succeeds where cast failed (!)
END
$func$ LANGUAGE plpgsql;

Call:

SELECT * FROM f1();

While you can also write a set returning function with that pattern I did not find a way to SELECT from a set returning function without supplying a column definition list ...

->SQLfiddle

typo, clarify
Source Link
Erwin Brandstetter
  • 182.2k
  • 28
  • 457
  • 620
Loading
Source Link
Erwin Brandstetter
  • 182.2k
  • 28
  • 457
  • 620
Loading