references: add computed fields page (#650)

This commit is contained in:
Steve Chavez
2023-06-22 09:14:23 -05:00
committed by GitHub
parent 9780790cee
commit 14de9f1dfd
3 changed files with 122 additions and 60 deletions
+4 -3
View File
@@ -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>
+86
View File
@@ -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".
+32 -57
View File
@@ -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>