Allt testat i Postgres 9.4 .
Postgres har några svaga punkter i syntaxen för hantering av ROW-typer. Du kan inte casta från en tabell (alias) direkt:
SELECT w::waypoint FROM waypoints w;
Lösningen är bara ett steg bort:dekomponera raden i en underfråga, sedan fungerar casten. På så sätt bryts kolumnvärden upp och lindas in i den nya typen direkt, utan att casta till text
och tillbaka. Du behöver inte lista alla kolumner individuellt och du behöver inte skapa en anpassad roll heller:
SELECT (w.*)::waypoint FROM (SELECT * FROM waypoints) w;
Eller kortare:
SELECT w.*::waypoint FROM (TABLE waypoints) w;
Eller ännu kortare:
SELECT w::waypoint FROM (TABLE waypoints) w;
Det är kortare och snabbare, i ett snabbtest med 30 000 rader och enkla typer 10 gånger snabbare än att casta till text
och tillbaka. Om du har (stor) jsonb
kolumner eller någon komplex typ (dyr konvertering till/från text
), kommer skillnaden att vara mycket större, ännu.
Ännu viktigare är att du inte behöver en annan anpassad komposittyp (ROW). Varje tabell har redan sin rad definierad som typ automatiskt. Använd bara den befintliga typen waypoints
istället för waypoint
(om ens möjligt). Då behöver du bara:
SELECT w FROM waypoints w;
Eller, till exempel:
SELECT everything(t) FROM temp t; -- using type waypoints
SELECT everything(t::waypoint) FROM (TABLE temp) t; -- using type waypoint
Bortsett från:
- En tabell har inte "argument" utan kolumner.
-
Du är inte skicka en
table parameter to this function
utan snarare ett radvärde . Det är så du skickar en tabell med namn:Du kan inte "passera en hel tabell" som parameter direkt i Postgres, det finns inga tabellvariabler. Du skulle använda en markör eller en temporär tabell för det.
Funktion
Din funktion har en ogiltig typdeklaration och är onödigt komplex. Jag tvivlar allvarligt på att du vill skapa en vy:
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
är inte giltig syntax, med text[]
istället för att deklarera en array med text
.
Använd hellre inte tabell-/typnamnet waypoints
som funktionsparameternamn, som öppnar upp för förvirrande fel.
Eller använd bara en enkel SQL-funktion om ditt fall är så enkelt som visas:
CREATE FUNCTION everything(_wp waypoint) -- or use type waypoints
RETURNS TABLE(node int, xy text[]) AS
$func$
SELECT ...
$func$ LANGUAGE sql;
Citera inte språknamnet. Det är en identifierare.