references: add computed fields page (#650)
This commit is contained in:
@@ -12,9 +12,10 @@ PostgREST exposes three database objects of a schema as resources: tables, views
|
||||
api/tables_views.rst
|
||||
api/stored_procedures.rst
|
||||
api/schemas.rst
|
||||
api/computed_fields.rst
|
||||
api/resource_embedding.rst
|
||||
api/openapi.rst
|
||||
api/resource_representation.rst
|
||||
api/openapi.rst
|
||||
api/*
|
||||
|
||||
.. raw:: html
|
||||
@@ -34,7 +35,7 @@ PostgREST exposes three database objects of a schema as resources: tables, views
|
||||
'#casting-columns': 'api/tables_views.html#casting-columns',
|
||||
'#json-columns': 'api/tables_views.html#json-columns',
|
||||
'#composite-array-columns': 'api/tables_views.html#composite-array-columns',
|
||||
'#computed-virtual-columns': 'api/tables_views.html#computed-virtual-columns',
|
||||
'#computed-virtual-columns': 'api/computed_fields.html#computed-fields',
|
||||
'#ordering': 'api/tables_views.html#ordering',
|
||||
'#limits-and-pagination': 'api/tables_views.html#limits-and-pagination',
|
||||
'#exact-count': 'api/tables_views.html#exact-count',
|
||||
@@ -115,4 +116,4 @@ PostgREST exposes three database objects of a schema as resources: tables, views
|
||||
if (willRedirectTo) {
|
||||
window.location.href = willRedirectTo;
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
.. _computed_cols:
|
||||
|
||||
Computed Fields
|
||||
###############
|
||||
|
||||
Computed fields are virtual columns that are not stored in a table. PostgreSQL makes it possible to implement them using functions on table types.
|
||||
|
||||
.. code-block:: postgres
|
||||
|
||||
CREATE TABLE people (
|
||||
first_name text
|
||||
, last_name text
|
||||
, job text
|
||||
);
|
||||
|
||||
-- a computed field that combines data from two columns
|
||||
CREATE FUNCTION full_name(people)
|
||||
RETURNS text AS $$
|
||||
SELECT $1.first_name || ' ' || $1.last_name;
|
||||
$$ LANGUAGE SQL;
|
||||
|
||||
:ref:`h_filter` can be applied to computed fields. For example, we can do a :ref:`fts` on :code:`full_name`:
|
||||
|
||||
.. code-block:: postgres
|
||||
|
||||
-- (optional) you can add an index on the computed field to speed up the query
|
||||
CREATE INDEX people_full_name_idx ON people
|
||||
USING GIN (to_tsvector('english', full_name(people)));
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. code-tab:: http
|
||||
|
||||
GET /people?full_name=fts.Beckett HTTP/1.1
|
||||
|
||||
.. code-tab:: bash Curl
|
||||
|
||||
curl "http://localhost:3000/people?full_name=fts.Beckett"
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
[
|
||||
{"first_name": "Samuel", "last_name": "Beckett", "job": "novelist"}
|
||||
]
|
||||
|
||||
|
||||
Computed fields won't appear on the response by default but you can use :ref:`v_filter` to include them:
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. code-tab:: http
|
||||
|
||||
GET /people?select=full_name,job HTTP/1.1
|
||||
|
||||
.. code-tab:: bash Curl
|
||||
|
||||
curl "http://localhost:3000/people?select=full_name,job"
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
[
|
||||
{"full_name": "Samuel Beckett", "job": "novelist"}
|
||||
]
|
||||
|
||||
|
||||
:ref:`ordering` on computed fields is also possible:
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. code-tab:: http
|
||||
|
||||
GET /people?order=full_name.desc HTTP/1.1
|
||||
|
||||
.. code-tab:: bash Curl
|
||||
|
||||
curl "http://localhost:3000/people?order=full_name.desc"
|
||||
|
||||
.. important::
|
||||
|
||||
Computed columns must be created in the :ref:`exposed schema <db-schemas>` or in a schema in the :ref:`extra search path <db-extra-search-path>` to be used in this way. When placing the computed column in the :ref:`exposed schema <db-schemas>` you can use an **unnamed** parameter, as in the example above, to prevent it from being exposed as an :ref:`RPC <s_procs>` under ``/rpc``.
|
||||
|
||||
.. note::
|
||||
|
||||
- PostgreSQL 12 introduced `generated columns <https://www.postgresql.org/docs/12/ddl-generated-columns.html>`_, which can also compute a value based on other columns. However they're stored, not virtual.
|
||||
- "computed fields" are documented on https://www.postgresql.org/docs/current/rowtypes.html#ROWTYPES-USAGE (search for "computed fields")
|
||||
- On previous PostgREST versions this feature was documented with the name of "computed columns".
|
||||
@@ -31,8 +31,8 @@ There are no deeply/nested/routes. Each route provides OPTIONS, GET, HEAD, POST,
|
||||
|
||||
.. _h_filter:
|
||||
|
||||
Horizontal Filtering (Rows)
|
||||
---------------------------
|
||||
Horizontal Filtering
|
||||
--------------------
|
||||
|
||||
You can filter result rows by adding conditions on columns. For instance, to return people aged under 13 years old:
|
||||
|
||||
@@ -249,10 +249,10 @@ Using `websearch_to_tsquery` requires PostgreSQL of version at least 11.0 and wi
|
||||
|
||||
.. _v_filter:
|
||||
|
||||
Vertical Filtering (Columns)
|
||||
----------------------------
|
||||
Vertical Filtering
|
||||
------------------
|
||||
|
||||
When certain columns are wide (such as those holding binary data), it is more efficient for the server to withhold them in a response. The client can specify which columns are required using the sql:`select` parameter.
|
||||
When certain columns are wide (such as those holding binary data), it is more efficient for the server to withhold them in a response. The client can specify which columns are required using the :code:`select` parameter.
|
||||
|
||||
.. tabs::
|
||||
|
||||
@@ -455,57 +455,6 @@ The arrow operators(``->``, ``->>``) can also be used for accessing composite fi
|
||||
|
||||
CREATE INDEX ON mytable ((to_jsonb(data) -> 'identification' ->> 'registration_number'));
|
||||
|
||||
.. _computed_cols:
|
||||
|
||||
Computed / Virtual Columns
|
||||
--------------------------
|
||||
|
||||
Filters may be applied to computed columns(**a.k.a. virtual columns**) as well as actual table/view columns, even though the computed columns will not appear in the output. For example, to search first and last names at once we can create a computed column that will not appear in the output but can be used in a filter:
|
||||
|
||||
.. code-block:: postgres
|
||||
|
||||
CREATE TABLE people (
|
||||
fname text,
|
||||
lname text
|
||||
);
|
||||
|
||||
CREATE FUNCTION full_name(people) RETURNS text AS $$
|
||||
SELECT $1.fname || ' ' || $1.lname;
|
||||
$$ LANGUAGE SQL;
|
||||
|
||||
-- (optional) add an index to speed up anticipated query
|
||||
CREATE INDEX people_full_name_idx ON people
|
||||
USING GIN (to_tsvector('english', full_name(people)));
|
||||
|
||||
A full-text search on the computed column:
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. code-tab:: http
|
||||
|
||||
GET /people?full_name=fts.Beckett HTTP/1.1
|
||||
|
||||
.. code-tab:: bash Curl
|
||||
|
||||
curl "http://localhost:3000/people?full_name=fts.Beckett"
|
||||
|
||||
As mentioned, computed columns do not appear in the output by default. However you can include them by listing them in the vertical filtering :code:`select` parameter:
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. code-tab:: http
|
||||
|
||||
GET /people?select=*,full_name HTTP/1.1
|
||||
|
||||
.. code-tab:: bash Curl
|
||||
|
||||
curl "http://localhost:3000/people?select=*,full_name"
|
||||
|
||||
.. important::
|
||||
|
||||
Computed columns must be created in the :ref:`exposed schema <db-schemas>` or in a schema in the :ref:`extra search path <db-extra-search-path>` to be used in this way. When placing the computed column in the :ref:`exposed schema <db-schemas>` you can use an **unnamed** argument, as in the example above, to prevent it from being exposed as an :ref:`RPC <s_procs>` under ``/rpc``.
|
||||
|
||||
|
||||
.. _ordering:
|
||||
|
||||
Ordering
|
||||
@@ -557,7 +506,17 @@ If you care where nulls are sorted, add ``nullsfirst`` or ``nullslast``:
|
||||
|
||||
curl "http://localhost:3000/people?order=age.desc.nullslast"
|
||||
|
||||
You can also use :ref:`computed_cols` to order the results, even though the computed columns will not appear in the output. You can sort by nested fields of :ref:`json_columns` with the JSON operators.
|
||||
You can also sort on fields of :ref:`composite_array_columns` or :ref:`json_columns`.
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. code-tab:: http
|
||||
|
||||
GET /countries?order=location->>lat HTTP/1.1
|
||||
|
||||
.. code-tab:: bash Curl
|
||||
|
||||
curl "http://localhost:3000/countries?order=location->>lat"
|
||||
|
||||
.. _limits:
|
||||
|
||||
@@ -1142,3 +1101,19 @@ Using ``offset`` to target a different subset of rows is also possible.
|
||||
|
||||
There is no native ``UPDATE...LIMIT`` or ``DELETE...LIMIT`` support in PostgreSQL; the generated query simulates that behavior and is based on `this Crunchy Data blog post <https://www.crunchydata.com/blog/simulating-update-or-delete-with-limit-in-postgres-ctes-to-the-rescue>`_.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<script type="text/javascript">
|
||||
let hash = window.location.hash;
|
||||
|
||||
const redirects = {
|
||||
// Tables and Views
|
||||
'#computed-virtual-columns': 'computed_fields.html#computed-fields',
|
||||
};
|
||||
|
||||
let willRedirectTo = redirects[hash];
|
||||
|
||||
if (willRedirectTo) {
|
||||
window.location.href = willRedirectTo;
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user