Specify dblink column definition list from a local existing type
dblink, postgresql, sql
Solution
You might need to make sure that your types are always in sync but this should work:
SELECT (t1::test).*
FROM dblink('dbname=remote', 'select * from test') AS t1;
The key is that often you need parentheses to ensure that the parser knows you are dealing with tuples.
For example this works for me:
CREATE TABLE test (id int, test bool);
select (t1::test).* from (select 1, true) t1;
But this throws a syntax error:
select t1::test.* from (select 1, true) t1;
Problem
I am using dblink to move certain data between databases. Everything is save and sound but I am wondering if there is a more convenient way to define the column definition list of a dblink query result. I can do something like this: ``` SELECT * FROM dblink('dbname=remote', 'select * from test') AS t1(id integer, data text); ``` The tables I'm interacting with have the same schema definition in both databases (remote & local). I was thinking of something like: ``` SELECT * FROM dblink('dbname=remote', 'select * from test') AS t1 LIKE public.test; ``` Or: ``` SELECT * FROM dblink('dbname=remote', 'select * from test') AS t1::public.test; ``` The column definition list tends to become quite long. Is there something I may have overlooked? EDIT: As this has been a problem for me before I created a small function as a work-around. ``` CREATE OR REPLACE FUNCTION dblink_star_func(_conn text, _schema_name text, _table_name text) RETURNS text LANGUAGE PLPGSQL VOLATILE STRICT AS $function$ DECLARE _dblink_schema text; _cols text; _q text; _func_name text := format('star_%s', $3); _func text; BEGIN SELECT nspname INTO _dblink_schema FROM pg_namespace n, pg_extension e WHERE e.extname = 'dblink' AND e.extnamespace = n.oid; SELECT array_to_string(array_agg(column_name || ' ' || udt_name), ', ') INTO _cols FROM information_schema.columns WHERE table_schema = $2 AND table_name = $3; _q := format('SELECT * FROM %I.dblink(%L, %L) AS remote (%s)', _dblink_schema, _conn, format('SELECT * FROM %I.%I', $2, $3), _cols ); _func := $_func$ CREATE OR REPLACE FUNCTION %s() RETURNS SETOF %I.%I LANGUAGE SQL VOLATILE STRICT AS $$ %s; $$ $_func$; EXECUTE format(_func, _func_name, $2, $3, _q); RETURN _func_name; END; $function$; ``` This function creates and yields a function that wraps the dblink call. It's certainly not meant for heavy lifting but convenience.It would be nice if it turns out it's not necessary at all. ``` > select dblink_star_func('dbname=ben', 'public', 'test'); ┌──────────────────┐ │ dblink_star_func │ ├──────────────────┤ │ star_test │ └──────────────────┘ (1 row) > select * from star_test() where data = 'success'; ┌────┬─────────┐ │ id │ data │ ├────┼─────────┤ │ 1 │ success │ └────┴─────────┘ (1 row) ```