CREATE OR REPLACE FUNCTION query_to_values(p_sql text)
 RETURNS text
 LANGUAGE plpgsql
AS $function$
DECLARE
	v_values_sql text;
	v_values text;
	v_column_format text;
	v_column_list text;
	v_column_cast text;
BEGIN
	EXECUTE $$CREATE TEMPORARY TABLE __arbitrary_resultset AS $$ || p_sql;
	
	SELECT string_agg(column_name, ', '), string_agg(column_name || '::' || data_type, ', '), string_agg('%'||ordinal_position||'$L', ', ')
	INTO v_column_list, v_column_cast, v_column_format
	FROM (
		SELECT
		pg_attribute.attname AS column_name,
		pg_catalog.format_type(pg_attribute.atttypid, pg_attribute.atttypmod) AS data_type,
		attnum AS ordinal_position
		FROM pg_catalog.pg_attribute
		INNER JOIN pg_catalog.pg_class ON pg_class.oid = pg_attribute.attrelid
		INNER JOIN pg_catalog.pg_namespace ON pg_namespace.oid = pg_class.relnamespace
		WHERE pg_attribute.attnum > 0
		AND NOT pg_attribute.attisdropped
		AND pg_namespace.nspname like 'pg_temp%'
		AND pg_class.relname = '__arbitrary_resultset'
	) x;	
	
	v_values_sql := format($query$SELECT string_agg(format($$(%1$s)$$, %2$s), E'\n,')
	FROM __arbitrary_resultset res;$query$
	, v_column_format, v_column_list);
	
	EXECUTE v_values_sql
	INTO v_values;	
	
	DROP TABLE __arbitrary_resultset;
	
	RETURN $$SELECT $$||v_column_cast||$$
FROM (VALUES 
$$||v_values||$$
) as res ($$||v_column_list||$$);$$;
END
$function$
;