Всичко тествано в Postgres 9.4 .
Postgres има някои слаби места в синтаксиса за обработка на типове ROW. Не можете да прехвърляте от таблица (псевдоним) директно:
SELECT w::waypoint FROM waypoints w;
Решението е само на една стъпка:разложете реда в подзаявка, след което кастингът работи. По този начин стойностите на колоните се разлагат и обгръщат в новия тип директно, без прехвърляне към text
и обратно. Няма нужда да изброявате всички колони поотделно и не е необходимо да създавате персонализирана кастинг:
SELECT (w.*)::waypoint FROM (SELECT * FROM waypoints) w;
Или по-кратко:
SELECT w.*::waypoint FROM (TABLE waypoints) w;
Или още по-кратко:
SELECT w::waypoint FROM (TABLE waypoints) w;
Това е по-кратко и по-бързо, в бърз тест с 30 000 реда и прости типове 10 пъти по-бързо отколкото кастинг към text
и обратно. Ако имате (голям) jsonb
колони или всеки сложен тип (скъпо преобразуване към/от text
), все пак разликата ще бъде много по-голяма.
По-важното е, че не имате нужда друг персонализиран съставен тип (ROW). Всяка таблица вече има свой ред, дефиниран като тип автоматично. Просто използвайте съществуващия тип waypoints
вместо waypoint
(ако изобщо е възможно). Тогава всичко, от което се нуждаете, е:
SELECT w FROM waypoints w;
Или, за вашия пример:
SELECT everything(t) FROM temp t; -- using type waypoints
SELECT everything(t::waypoint) FROM (TABLE temp) t; -- using type waypoint
Добавки:
- Таблицата няма „аргументи“, а колони.
-
Вие не сте предаване на
table parameter to this function
, а по-скоро стойност на ред . Ето как предавате таблица по име:Не можете да "предадете цяла таблица" като параметър директно в Postgres, няма променливи на таблица. За това бихте използвали курсор или временна таблица.
Функция
Вашата функция има невалидна декларация на тип и е ненужно сложна. Сериозно се съмнявам, че искате да създадете изглед:
CREATE FUNCTION everything(_wp waypoint) -- or use type waypoints
RETURNS TABLE(node int, xy text[]) AS
$func$
BEGIN
RETURN QUERY
SELECT ...
END
$func$ LANGUAGE plpgsql;
text array
не е валиден синтаксис, използвайки text[]
вместо да декларирате масив от text
.
По-скоро не използвайте името на таблицата/типа waypoints
като име на параметър на функцията, което ви отваря за объркващи грешки.
Или просто използвайте проста SQL функция, ако вашият случай е толкова прост, колкото е показано:
CREATE FUNCTION everything(_wp waypoint) -- or use type waypoints
RETURNS TABLE(node int, xy text[]) AS
$func$
SELECT ...
$func$ LANGUAGE sql;
Не цитирайте името на езика. Това е идентификатор.